9
9
use Fhaculty \Graph \Vertex ;
10
10
use Fhaculty \Graph \Edge \Base as Edge ;
11
11
12
+ /**
13
+ * Abstract base class for shortest path algorithms
14
+ *
15
+ * This abstract base class provides the base interface for working with
16
+ * single-source shortest paths (SSSP).
17
+ *
18
+ * The shortest path problem is the problem of finding a path between two
19
+ * vertices such that the sum of the weights of its constituent edges is
20
+ * minimized. The weight of the shortest path is referred to as distance.
21
+ *
22
+ * A--[10]-------------B---E<--F
23
+ * \ /
24
+ * \--[4]--C--[2]--D
25
+ *
26
+ * In the above pictured graph, the distance (weight of the shortest path)
27
+ * between A and C is 4, and the shortest path between A and B is "A->C->D->B"
28
+ * with a distance (total weight) of 6.
29
+ *
30
+ * In graph theory, it is usually assumed that a path to an unreachable vertex
31
+ * has infinite distance. In the above pictured graph, there's no way path
32
+ * from A to F, i.e. vertex F is unreachable from vertex A because of the
33
+ * directed edge "E <- F" pointing in the opposite direction. This library
34
+ * considers this an Exception instead. So if you're asking for the distance
35
+ * between A and F, you'll receive an OutOfBoundsException instead.
36
+ *
37
+ * In graph theory, it is usually assumed that each vertex has a (pseudo-)path
38
+ * to itself with a distance of 0. In order to produce reliable, consistent
39
+ * results, this library considers this (pseudo-)path to be non-existant, i.e.
40
+ * there's NO "magic" path between A and A. So if you're asking for the distance
41
+ * between A and A, you'll receive an OutOfBoundsException instead. This allows
42
+ * us to check hether there's a real path between A and A (cycle via other
43
+ * vertices) as well as working with loop edges.
44
+ *
45
+ * @link http://en.wikipedia.org/wiki/Shortest_path_problem
46
+ * @link http://en.wikipedia.org/wiki/Tree_%28data_structure%29
47
+ * @see ShortestPath\Dijkstra
48
+ * @see ShortestPath\MooreBellmanFord which also supports negative Edge weights
49
+ * @see ShortestPath\BreadthFirst with does not consider Edge weights, but only the number of hops
50
+ */
12
51
abstract class Base extends BaseVertex
13
52
{
14
53
/**
@@ -31,8 +70,8 @@ public function getWalkTo(Vertex $endVertex)
31
70
* @param Vertex $endVertex
32
71
* @throws OutOfBoundsException if there's no path to the given end vertex
33
72
* @return Edge[]
34
- * @uses AlgorithmSp ::getEdges()
35
- * @uses AlgorithmSp ::getEdgesToInternal()
73
+ * @uses self ::getEdges()
74
+ * @uses self ::getEdgesToInternal()
36
75
*/
37
76
public function getEdgesTo (Vertex $ endVertex )
38
77
{
@@ -46,7 +85,7 @@ public function getEdgesTo(Vertex $endVertex)
46
85
* @param array $edges array of all input edges to operate on
47
86
* @throws OutOfBoundsException if there's no path to the given vertex
48
87
* @return Edge[]
49
- * @uses AlgorithmSp ::getEdges() if no edges were given
88
+ * @uses self ::getEdges() if no edges were given
50
89
*/
51
90
protected function getEdgesToInternal (Vertex $ endVertex , array $ edges )
52
91
{
@@ -94,7 +133,7 @@ private function sumEdges(array $edges)
94
133
* get array of all vertices the given start vertex has a path to
95
134
*
96
135
* @return Vertex[]
97
- * @uses AlgorithmSp ::getDistanceMap()
136
+ * @uses self ::getDistanceMap()
98
137
*/
99
138
public function getVertices ()
100
139
{
@@ -113,7 +152,7 @@ public function getVertices()
113
152
* get array of all vertices' IDs the given start vertex has a path to
114
153
*
115
154
* @return int[]
116
- * @uses AlgorithmSp ::getDistanceMap()
155
+ * @uses self ::getDistanceMap()
117
156
*/
118
157
public function getVerticesId ()
119
158
{
@@ -142,9 +181,9 @@ public function hasVertex(Vertex $vertex)
142
181
* get map of vertex IDs to distance
143
182
*
144
183
* @return float[]
145
- * @uses AlgorithmSp ::getEdges()
146
- * @uses AlgorithmSp ::getEdgesToInternal()
147
- * @uses AlgorithmSp ::sumEdges()
184
+ * @uses self ::getEdges()
185
+ * @uses self ::getEdgesToInternal()
186
+ * @uses self ::sumEdges()
148
187
*/
149
188
public function getDistanceMap ()
150
189
{
@@ -166,8 +205,8 @@ public function getDistanceMap()
166
205
* @param Vertex $endVertex
167
206
* @return float
168
207
* @throws OutOfBoundsException if there's no path to the given end vertex
169
- * @uses AlgorithmSp ::getEdgesTo()
170
- * @uses AlgorithmSp ::sumEdges()
208
+ * @uses self ::getEdgesTo()
209
+ * @uses self ::sumEdges()
171
210
*/
172
211
public function getDistance (Vertex $ endVertex )
173
212
{
@@ -177,8 +216,43 @@ public function getDistance(Vertex $endVertex)
177
216
/**
178
217
* create new resulting graph with only edges on shortest path
179
218
*
219
+ * The resulting Graph will always represent a tree with the start vertex
220
+ * being the root vertex.
221
+ *
222
+ * For example considering the following input Graph with equal weights on
223
+ * each edge:
224
+ *
225
+ * A----->F
226
+ * / \ ^
227
+ * / \ /
228
+ * / \ /
229
+ * | E
230
+ * | \
231
+ * | \
232
+ * B--->C<---D
233
+ *
234
+ * The resulting shortest path tree Graph will look like this:
235
+ *
236
+ * A----->F
237
+ * / \
238
+ * / \
239
+ * / \
240
+ * | E
241
+ * | \
242
+ * | \
243
+ * B--->C D
244
+ *
245
+ * Or by just arranging the Vertices slightly different:
246
+ *
247
+ * A
248
+ * /|\
249
+ * / | \
250
+ * B E \->F
251
+ * / |
252
+ * C<-/ D
253
+ *
180
254
* @return Graph
181
- * @uses AlgorithmSp ::getEdges()
255
+ * @uses self ::getEdges()
182
256
* @uses Graph::createGraphCloneEdges()
183
257
*/
184
258
public function createGraph ()
0 commit comments