Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
87.88% |
29 / 33 |
|
92.31% |
12 / 13 |
CRAP | |
0.00% |
0 / 1 |
Node | |
87.88% |
29 / 33 |
|
92.31% |
12 / 13 |
26.11 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getId | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getData | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setData | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isEqual | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
setNodeRelative | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
setEdge | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
getEdge | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
hasNeighbor | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
20 | |||
getEdgeByNeighbor | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
4 | |||
getEdges | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
removeEdges | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getNeighbors | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
4 |
1 | <?php |
2 | /** |
3 | * Jingga |
4 | * |
5 | * PHP Version 8.1 |
6 | * |
7 | * @package phpOMS\Stdlib\Graph |
8 | * @copyright Dennis Eichhorn |
9 | * @license OMS License 2.0 |
10 | * @version 1.0.0 |
11 | * @link https://jingga.app |
12 | */ |
13 | declare(strict_types=1); |
14 | |
15 | namespace phpOMS\Stdlib\Graph; |
16 | |
17 | /** |
18 | * Node class. |
19 | * |
20 | * @package phpOMS\Stdlib\Graph |
21 | * @license OMS License 2.0 |
22 | * @link https://jingga.app |
23 | * @since 1.0.0 |
24 | */ |
25 | class Node |
26 | { |
27 | /** |
28 | * Node id. |
29 | * |
30 | * @var string |
31 | * @since 1.0.0 |
32 | */ |
33 | private string $id; |
34 | |
35 | /** |
36 | * Node data. |
37 | * |
38 | * @var mixed |
39 | * @since 1.0.0 |
40 | */ |
41 | private $data = null; |
42 | |
43 | /** |
44 | * Edges. |
45 | * |
46 | * @var Edge[] |
47 | * @since 1.0.0 |
48 | */ |
49 | protected array $edges = []; |
50 | |
51 | /** |
52 | * Constructor. |
53 | * |
54 | * @param string $id Node id |
55 | * @param mixed $data Node data |
56 | * |
57 | * @since 1.0.0 |
58 | */ |
59 | public function __construct(string $id, mixed $data = null) |
60 | { |
61 | $this->id = $id; |
62 | $this->data = $data; |
63 | } |
64 | |
65 | /** |
66 | * Get node id. |
67 | * |
68 | * @return string |
69 | * |
70 | * @since 1.0.0 |
71 | */ |
72 | public function getId() : string |
73 | { |
74 | return $this->id; |
75 | } |
76 | |
77 | /** |
78 | * Get data. |
79 | * |
80 | * @return mixed |
81 | * |
82 | * @since 1.0.0 |
83 | */ |
84 | public function getData() : mixed |
85 | { |
86 | return $this->data; |
87 | } |
88 | |
89 | /** |
90 | * Set data. |
91 | * |
92 | * @param mixed $data Node data |
93 | * |
94 | * @return void |
95 | * |
96 | * @since 1.0.0 |
97 | */ |
98 | public function setData(mixed $data) : void |
99 | { |
100 | $this->data = $data; |
101 | } |
102 | |
103 | /** |
104 | * Compare with other node. |
105 | * |
106 | * @param Node $node Node |
107 | * |
108 | * @return bool |
109 | * |
110 | * @since 1.0.0 |
111 | */ |
112 | public function isEqual(self $node) : bool |
113 | { |
114 | return $this->id === $node->getId() && $this->data === $node->getData(); |
115 | } |
116 | |
117 | /** |
118 | * Set a relative undirected node. |
119 | * |
120 | * @param Node $node Graph node |
121 | * @param int $key Index for absolute position |
122 | * @param bool $isDirected Is directed |
123 | * |
124 | * @return Edge |
125 | * |
126 | * @since 1.0.0 |
127 | */ |
128 | public function setNodeRelative(self $node, int $key = null, bool $isDirected = false) : Edge |
129 | { |
130 | $edge = new Edge($this, $node, 0.0, $isDirected); |
131 | $this->setEdge($edge, $key); |
132 | |
133 | if (!$edge->isDirected) { |
134 | $node->setEdge($edge); |
135 | } |
136 | |
137 | return $edge; |
138 | } |
139 | |
140 | /** |
141 | * Add edge to node. |
142 | * |
143 | * @param Edge $edge Graph edge |
144 | * @param int $key Index for absolute position |
145 | * |
146 | * @return Node |
147 | * |
148 | * @since 1.0.0 |
149 | */ |
150 | public function setEdge(Edge $edge, int $key = null) : self |
151 | { |
152 | if ($key === null) { |
153 | $this->edges[] = $edge; |
154 | } else { |
155 | $this->edges[$key] = $edge; |
156 | } |
157 | |
158 | return $this; |
159 | } |
160 | |
161 | /** |
162 | * Get graph edge. |
163 | * |
164 | * @param int $key Edge key |
165 | * |
166 | * @return null|Edge |
167 | * |
168 | * @since 1.0.0 |
169 | */ |
170 | public function getEdge(int $key) : ?Edge |
171 | { |
172 | return $this->edges[$key] ?? null; |
173 | } |
174 | |
175 | /** |
176 | * Check if the node has a certain neighbor |
177 | * |
178 | * @param Node $node Neighbor node |
179 | * |
180 | * @return bool |
181 | * |
182 | * @since 1.0.0 |
183 | */ |
184 | public function hasNeighbor(self $node) : bool |
185 | { |
186 | foreach ($this->edges as $edge) { |
187 | if ($edge->node1->isEqual($node) || $edge->node2->isEqual($node)) { |
188 | return true; |
189 | } |
190 | } |
191 | |
192 | return false; |
193 | } |
194 | |
195 | /** |
196 | * Get graph edge by neighbor. |
197 | * |
198 | * @param Node $node Neighbor node |
199 | * |
200 | * @return null|Edge |
201 | * |
202 | * @since 1.0.0 |
203 | */ |
204 | public function getEdgeByNeighbor(self $node) : ?Edge |
205 | { |
206 | foreach ($this->edges as $edge) { |
207 | if ($edge->node1->isEqual($node) || $edge->node2->isEqual($node)) { |
208 | return $edge; |
209 | } |
210 | } |
211 | |
212 | return null; |
213 | } |
214 | |
215 | /** |
216 | * Get graph edges |
217 | * |
218 | * @return Edge[] |
219 | * |
220 | * @since 1.0.0 |
221 | */ |
222 | public function getEdges() : array |
223 | { |
224 | return $this->edges; |
225 | } |
226 | |
227 | /** |
228 | * Removes all edges / neighbours from the node |
229 | * |
230 | * @return void |
231 | * |
232 | * @since 1.0.0 |
233 | */ |
234 | public function removeEdges() : void |
235 | { |
236 | $this->edges = []; |
237 | } |
238 | |
239 | /** |
240 | * Get all node neighbors. |
241 | * |
242 | * @return Node[] |
243 | * |
244 | * @since 1.0.0 |
245 | */ |
246 | public function getNeighbors() : array |
247 | { |
248 | $neighbors = []; |
249 | |
250 | foreach ($this->edges as $edge) { |
251 | $nodes = $edge->getNodes(); |
252 | |
253 | $neighbors[] = $nodes[0] !== null && !$this->isEqual($nodes[0]) |
254 | ? $nodes[0] |
255 | : $nodes[1]; |
256 | } |
257 | |
258 | return $neighbors; |
259 | } |
260 | } |