@@ -27,6 +27,22 @@ Class {
27
27
#tag : ' Shortest path'
28
28
}
29
29
30
+ { #category : ' private' }
31
+ AIFloydWarshall >> computeAllPairsShortestPaths [
32
+
33
+ nodes do: [ :k |
34
+ nodes do: [ :i |
35
+ nodes do: [ :j |
36
+ | currentDist throughK |
37
+ currentDist := distanceMatrix at: {i. j}.
38
+ ((distanceMatrix at: {i. k}) ~= Float infinity and : [
39
+ (distanceMatrix at: {k. j}) ~= Float infinity ]) ifTrue: [
40
+ throughK := (distanceMatrix at: {i. k}) + (distanceMatrix at: {k. j}).
41
+ throughK < currentDist ifTrue: [
42
+ distanceMatrix at: {i. j} put: throughK.
43
+ nextMatrix at: {i. j} put: (nextMatrix at: {i. k}) ] ] ] ] ]
44
+ ]
45
+
30
46
{ #category : ' configuration' }
31
47
AIFloydWarshall >> distanceFrom: sourceModel to: destinationModel [
32
48
@@ -48,6 +64,56 @@ AIFloydWarshall >> edgeClass [
48
64
^ AIWeightedEdge
49
65
]
50
66
67
+ { #category : ' running' }
68
+ AIFloydWarshall >> getAllPairsDistances [
69
+
70
+ | result |
71
+
72
+ result := Dictionary new .
73
+ nodes do: [ :source |
74
+ nodes do: [ :destination |
75
+ result
76
+ at: {
77
+ source model.
78
+ destination model }
79
+ put: (distanceMatrix at: {
80
+ source.
81
+ destination }) ] ].
82
+
83
+ ^ result
84
+ ]
85
+
86
+ { #category : ' running' }
87
+ AIFloydWarshall >> getAllPairsPaths [
88
+
89
+ | result |
90
+ result := Dictionary new .
91
+ nodes do: [ :source |
92
+ nodes do: [ :destination |
93
+ result
94
+ at: {
95
+ source model.
96
+ destination model }
97
+ put: (self pathFrom: source model to: destination model) ] ].
98
+ ^ result
99
+ ]
100
+
101
+ { #category : ' private' }
102
+ AIFloydWarshall >> handleNegativeCycles [
103
+
104
+ nodes do: [ :v | (distanceMatrix at: {v. v}) < 0 ifTrue: [ hasNegativeCycle := true ] ].
105
+
106
+ hasNegativeCycle ifTrue: [
107
+ nodes do: [ :k |
108
+ (distanceMatrix at: {k. k}) < 0 ifTrue: [
109
+ nodes do: [ :i |
110
+ nodes do: [ :j |
111
+ ((distanceMatrix at: {i. k}) ~= Float infinity and : [
112
+ (distanceMatrix at: {k. j}) ~= Float infinity ]) ifTrue: [
113
+ distanceMatrix at: {i. j} put: Float negativeInfinity.
114
+ nextMatrix at: {i. j} put: nil ] ] ] ] ] ]
115
+ ]
116
+
51
117
{ #category : ' accessing' }
52
118
AIFloydWarshall >> hasNegativeCycle [
53
119
@@ -131,96 +197,8 @@ AIFloydWarshall >> reset [
131
197
AIFloydWarshall >> run [
132
198
133
199
self reset.
134
-
135
- nodes do: [ :k |
136
- nodes do: [ :i |
137
- nodes do: [ :j |
138
- | currentDist throughK |
139
- currentDist := distanceMatrix at: {
140
- i.
141
- j }.
142
- ((distanceMatrix at: {
143
- i.
144
- k }) ~= Float infinity and : [
145
- (distanceMatrix at: {
146
- k.
147
- j }) ~= Float infinity ]) ifTrue: [
148
- throughK := (distanceMatrix at: {
149
- i.
150
- k }) + (distanceMatrix at: {
151
- k.
152
- j }).
153
- throughK < currentDist ifTrue: [
154
- distanceMatrix
155
- at: {
156
- i.
157
- j }
158
- put: throughK.
159
- nextMatrix
160
- at: {
161
- i.
162
- j }
163
- put: (nextMatrix at: {
164
- i.
165
- k }) ] ] ] ] ].
166
-
167
- nodes do: [ :v |
168
- (distanceMatrix at: {
169
- v.
170
- v }) < 0 ifTrue: [ hasNegativeCycle := true ] ].
171
-
172
- hasNegativeCycle ifTrue: [
173
- nodes do: [ :k |
174
- (distanceMatrix at: {
175
- k.
176
- k }) < 0 ifTrue: [
177
- nodes do: [ :i |
178
- nodes do: [ :j |
179
- ((distanceMatrix at: {
180
- i.
181
- k }) ~= Float infinity and : [
182
- (distanceMatrix at: {
183
- k.
184
- j }) ~= Float infinity ]) ifTrue: [
185
- distanceMatrix
186
- at: {
187
- i.
188
- j }
189
- put: Float negativeInfinity.
190
- nextMatrix
191
- at: {
192
- i.
193
- j }
194
- put: nil ] ] ] ] ] ]
195
- ]
196
-
197
- { #category : ' running' }
198
- AIFloydWarshall >> runAndGetAllPairsDistances [
199
-
200
- | result |
201
- self run.
202
-
203
- result := Dictionary new .
204
- nodes do: [ :source |
205
- nodes do: [ :destination |
206
- result at: {source model. destination model} put: (distanceMatrix at: {source. destination}).
207
- ].
208
- ].
209
-
210
- ^ result
211
- ]
212
-
213
- { #category : ' running' }
214
- AIFloydWarshall >> runAndGetAllPairsPaths [
215
-
216
- | result |
217
- self run.
218
- result := Dictionary new .
219
- nodes do: [ :source |
220
- nodes do: [ :destination |
221
- result at: {source model. destination model}
222
- put: (self pathFrom: source model to: destination model) ] ].
223
- ^ result
200
+ self computeAllPairsShortestPaths.
201
+ self handleNegativeCycles.
224
202
]
225
203
226
204
{ #category : ' configuration' }
0 commit comments