Skip to content

Commit 6a68bf7

Browse files
committed
Refactored run method & improved convenience methods
1 parent 9499751 commit 6a68bf7

File tree

2 files changed

+74
-94
lines changed

2 files changed

+74
-94
lines changed

src/AI-Algorithms-Graph-Tests/AIFloydWarshallTest.class.st

+6-4
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ AIFloydWarshallTest >> testAllPairsDistances [
3030
to: #second
3131
weight: #third.
3232

33-
result := floydWarshall runAndGetAllPairsDistances.
34-
33+
floydWarshall run.
34+
result := floydWarshall getAllPairsDistances.
35+
3536
self assert: (result at: { 1. 2 }) equals: 3.
3637
self assert: (result at: { 1. 5 }) equals: 8.
3738
self assert: (result at: { 3. 5 }) equals: 5
@@ -51,8 +52,9 @@ AIFloydWarshallTest >> testAllPairsPaths [
5152
to: #second
5253
weight: #third.
5354

54-
result := floydWarshall runAndGetAllPairsPaths.
55-
55+
floydWarshall run.
56+
result := floydWarshall getAllPairsPaths.
57+
5658
self assert: (result at: { 1. 2 }) equals: #( 1 2 ).
5759
self assert: (result at: { 1. 5 }) equals: #( 1 5 ).
5860
self assert: (result at: { 3. 5 }) equals: #( 3 4 5 )

src/AI-Algorithms-Graph/AIFloydWarshall.class.st

+68-90
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,22 @@ Class {
2727
#tag : 'Shortest path'
2828
}
2929

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+
3046
{ #category : 'configuration' }
3147
AIFloydWarshall >> distanceFrom: sourceModel to: destinationModel [
3248

@@ -48,6 +64,56 @@ AIFloydWarshall >> edgeClass [
4864
^ AIWeightedEdge
4965
]
5066

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+
51117
{ #category : 'accessing' }
52118
AIFloydWarshall >> hasNegativeCycle [
53119

@@ -131,96 +197,8 @@ AIFloydWarshall >> reset [
131197
AIFloydWarshall >> run [
132198

133199
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.
224202
]
225203

226204
{ #category : 'configuration' }

0 commit comments

Comments
 (0)