Skip to content

Commit 50fe3de

Browse files
committed
count sub graphs in AbstractGraph
1 parent 51f33fa commit 50fe3de

File tree

7 files changed

+461
-8
lines changed

7 files changed

+461
-8
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@
2525
},
2626
"require": {
2727
"php": ">=7.1",
28-
"doganoo/php-util": "0.0.*"
28+
"doganoo/php-util": "0.1.*"
2929
}
3030
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
/**
3+
* MIT License
4+
*
5+
* Copyright (c) 2018 Dogan Ucar, <dogan@dogan-ucar.de>
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in all
15+
* copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
* SOFTWARE.
24+
*/
25+
26+
namespace doganoo\PHPAlgorithms\Algorithm\Various;
27+
28+
29+
use doganoo\PHPAlgorithms\Datastructure\Lists\ArrayLists\ArrayList;
30+
use doganoo\PHPAlgorithms\Datastructure\Maps\HashMap;
31+
32+
/**
33+
* Class Converter
34+
* @package doganoo\PHPAlgorithms\Algorithm\Various
35+
*/
36+
class Converter {
37+
/**
38+
* @param HashMap|null $map
39+
* @return ArrayList|null
40+
* @throws \doganoo\PHPAlgorithms\common\Exception\InvalidKeyTypeException
41+
* @throws \doganoo\PHPAlgorithms\common\Exception\UnsupportedKeyTypeException
42+
*/
43+
public function hashMapToArrayList(?HashMap $map): ?ArrayList {
44+
if (null === $map) return null;
45+
46+
$keySet = $map->keySet();
47+
$list = new ArrayList();
48+
foreach ($keySet as $key) {
49+
$value = $map->get($key);
50+
$list->add($value);
51+
}
52+
53+
return $list;
54+
}
55+
56+
}

src/Common/Abstracts/AbstractGraph.php

Lines changed: 90 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,14 @@
2626
namespace doganoo\PHPAlgorithms\Common\Abstracts;
2727

2828

29+
use doganoo\PHPAlgorithms\Algorithm\Various\Converter;
2930
use doganoo\PHPAlgorithms\Common\Exception\InvalidGraphTypeException;
3031
use doganoo\PHPAlgorithms\Common\Interfaces\IComparable;
3132
use doganoo\PHPAlgorithms\Common\Util\Comparator;
3233
use doganoo\PHPAlgorithms\Datastructure\Graph\Graph\Node;
3334
use doganoo\PHPAlgorithms\Datastructure\Lists\ArrayLists\ArrayList;
35+
use doganoo\PHPAlgorithms\Datastructure\Maps\HashMap;
36+
use doganoo\PHPAlgorithms\Datastructure\Stackqueue\Queue;
3437

3538
/**
3639
* Class AbstractGraph
@@ -42,6 +45,7 @@ abstract class AbstractGraph implements IComparable, \JsonSerializable {
4245
public const UNDIRECTED_GRAPH = 2;
4346
protected $nodeList = null;
4447
private $type = 0;
48+
private $converter = null;
4549

4650
/**
4751
* AbstractGraph constructor.
@@ -51,6 +55,7 @@ abstract class AbstractGraph implements IComparable, \JsonSerializable {
5155
*/
5256
protected function __construct($type = self::DIRECTED_GRAPH) {
5357
$this->nodeList = new ArrayList();
58+
$this->converter = new Converter();
5459
if ($type === self::DIRECTED_GRAPH || $type === self::UNDIRECTED_GRAPH) {
5560
$this->type = $type;
5661
} else {
@@ -82,13 +87,6 @@ public function addNode(Node $node): bool {
8287
*/
8388
public abstract function addEdge(Node $startNode, Node $endNode): bool;
8489

85-
/**
86-
* @return ArrayList|null
87-
*/
88-
public function getNodes(): ?ArrayList {
89-
return $this->nodeList;
90-
}
91-
9290
/**
9391
* @param $object
9492
* @return int
@@ -127,4 +125,89 @@ public function jsonSerialize() {
127125
, "type" => $this->type,
128126
];
129127
}
128+
129+
/**
130+
* @param AbstractGraph $graph
131+
* @return AbstractGraph|null
132+
* @throws \doganoo\PHPAlgorithms\Common\Exception\IndexOutOfBoundsException
133+
* @throws \doganoo\PHPAlgorithms\common\Exception\InvalidKeyTypeException
134+
* @throws \doganoo\PHPAlgorithms\common\Exception\UnsupportedKeyTypeException
135+
*/
136+
public function deepCopy(AbstractGraph $graph): ?AbstractGraph {
137+
$root = $graph->getRoot();
138+
if (null === $root) return null;
139+
140+
$q = new Queue();
141+
$m = new HashMap();
142+
143+
$newRoot = new Node($root->getValue());
144+
145+
$q->enqueue($root);
146+
$m->put($root, $newRoot);
147+
148+
while (!$q->isEmpty()) {
149+
/** @var Node $node */
150+
$node = $q->dequeue();
151+
152+
/** @var Node $adjacent */
153+
foreach ($node->getAdjacents() as $adjacent) {
154+
if ($m->containsKey($adjacent)) {
155+
/** @var Node $x */
156+
$x = $m->get($node);
157+
/** @var Node $y */
158+
$y = $m->get($adjacent);
159+
$x->addAdjacent($y);
160+
} else {
161+
$copy = new Node($adjacent->getValue());
162+
$m->put($adjacent, $copy);
163+
/** @var Node $adj */
164+
$adj = $m->get($adjacent);
165+
$adj->addAdjacent($copy);
166+
$q->enqueue($adjacent);
167+
}
168+
}
169+
170+
$nodeList = $this->converter->hashMapToArrayList($m);
171+
$this->nodeList = $nodeList;
172+
return $this;
173+
}
174+
}
175+
176+
/**
177+
* returns the number of sub graphs
178+
*
179+
* @return int
180+
*/
181+
public function numberOfSubGraph(): int {
182+
if (null === $this->getNodes()) return 0;
183+
$c = 0;
184+
$v = new ArrayList();
185+
186+
foreach ($this->getNodes() as $node) {
187+
if ($v->containsValue($node)) continue;
188+
$c++;
189+
$this->flood($node, $v);
190+
}
191+
return $c;
192+
}
193+
194+
/**
195+
* @return ArrayList|null
196+
*/
197+
public function getNodes(): ?ArrayList {
198+
return $this->nodeList;
199+
}
200+
201+
/**
202+
* @param Node $node
203+
* @param ArrayList $v
204+
*/
205+
private function flood(Node $node, ArrayList &$v): void {
206+
foreach ($node->getAdjacents() as $adjacent) {
207+
if ($v->containsValue($adjacent)) continue;
208+
$v->add($adjacent);
209+
}
210+
}
211+
212+
130213
}

src/Datastructure/Maps/IntegerVector.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
* Class Vector
3434
*
3535
* @package doganoo\PHPAlgorithms\Datastructure\Maps
36+
* @deprecated
3637
*/
3738
class IntegerVector implements IVector {
3839
/** @var array|null $array */
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<?php
2+
/**
3+
* MIT License
4+
*
5+
* Copyright (c) 2018 Dogan Ucar
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in all
15+
* copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
* SOFTWARE.
24+
*/
25+
26+
namespace doganoo\PHPAlgorithms\Datastructure\Vector\BitVector;
27+
28+
29+
use doganoo\PHPAlgorithms\Common\Exception\InvalidBitLengthException;
30+
use doganoo\PHPAlgorithms\Common\Interfaces\IVector;
31+
32+
/**
33+
* Class Vector
34+
*
35+
* @package doganoo\PHPAlgorithms\Datastructure\Maps
36+
*/
37+
class IntegerVector implements IVector {
38+
/** @var array|null $array */
39+
private $array = null;
40+
/** @var int $bitLength */
41+
private $bitLength = 32;
42+
43+
/**
44+
* Vector constructor.
45+
*
46+
* @param int $bitLength
47+
* @throws InvalidBitLengthException
48+
*/
49+
public function __construct(int $bitLength = 32) {
50+
$this->array = [];
51+
if (0 === $bitLength) throw new InvalidBitLengthException();
52+
$this->bitLength = $bitLength;
53+
}
54+
55+
56+
/**
57+
* sets a value in the vector
58+
*
59+
* @param $value
60+
* @return bool
61+
*/
62+
public function set($value): bool {
63+
//TODO throw exception instead?
64+
if (\is_int($value)) {
65+
$info = $this->getIndexAndMask($value);
66+
$i = $info["i"];
67+
$k = $info["k"];
68+
69+
$flag = 1;
70+
$flag = $flag << $k;
71+
72+
if (isset($this->array[$i])) {
73+
$this->array[$i] |= $flag;
74+
} else {
75+
$this->array[$i] = $flag;
76+
}
77+
return true;
78+
}
79+
return false;
80+
}
81+
82+
private function getIndexAndMask(int $value): array {
83+
$i = $value / $this->bitLength;
84+
$k = $value % $this->bitLength;
85+
86+
$info = [];
87+
$info["i"] = $i;
88+
$info["k"] = $k;
89+
return $info;
90+
}
91+
92+
/**
93+
* retrieves the value in the vector
94+
*
95+
* @param $value
96+
* @return mixed
97+
*/
98+
public function get($value) {
99+
//TODO throw exception instead?!
100+
if (\is_int($value)) {
101+
$info = $this->getIndexAndMask($value);
102+
$i = $info["i"];
103+
$k = $info["k"];
104+
105+
$flag = 1;
106+
$flag = $flag << $k;
107+
108+
if (isset($this->array[$i])) return (($this->array[$i] & $flag) !== 0);
109+
return false;
110+
}
111+
return false;
112+
}
113+
114+
/**
115+
* clears the value in the vector
116+
*
117+
* @param $value
118+
* @return bool
119+
*/
120+
public function clear($value): bool {
121+
//TODO throw exception insted?!
122+
if (\is_int($value)) {
123+
$info = $this->getIndexAndMask($value);
124+
$i = $info["i"];
125+
$k = $info["k"];
126+
127+
$flag = 1;
128+
$flag = $flag << $k;
129+
$flag = !$flag;
130+
131+
if (isset($this->array[$i])) {
132+
$this->array[$i] &= $flag;
133+
} else {
134+
$this->array[$i] = $this->array[$i] & $flag;
135+
}
136+
return true;
137+
}
138+
return false;
139+
}
140+
141+
/**
142+
* @param $object
143+
* @return int
144+
*/
145+
public function compareTo($object): int {
146+
if ($object instanceof IntegerVector) {
147+
if (\count(\array_diff($this->array, $object->array)) === 0) return 0;
148+
if (\count($this->array) < \count($object->array)) return -1;
149+
if (\count($this->array) > \count($object->array)) return 1;
150+
}
151+
return -1;
152+
}
153+
154+
/**
155+
* Specify data which should be serialized to JSON
156+
*
157+
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
158+
* @return mixed data which can be serialized by <b>json_encode</b>,
159+
* which is a value of any type other than a resource.
160+
* @since 5.4.0
161+
*/
162+
public function jsonSerialize() {
163+
return [
164+
"array" => $this->array
165+
, "bit_length" => $this->bitLength,
166+
];
167+
}
168+
}

0 commit comments

Comments
 (0)