Skip to content

Commit 6547ac5

Browse files
Add some explanations about correctness.
1 parent b0a068e commit 6547ac5

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

algo/src/main/java/org/neo4j/gds/steiner/SteinerBasedDeltaStepping.java

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,26 @@ private long tryToUpdateSteinerTree(
217217
//We Use two simple criteria to discover if there is a terminal for which with full certainty,
218218
//we have found a shortest to it:
219219

220-
// Whenever we change from one bin to another, we find the terminal of smallest distance
221-
//if it's distance is below the currentBin, the path to it is optimal.
222-
223-
//Otherwise, if we keep the current bin, ensure all future entries in the current bin
224-
//are worse of than the shortest path to a terminal (hence its shortest distance cannot improve)
220+
// The first criterion checks whenever when we move to a new bucket in the next iteration.
221+
//We first consider the terminal which currently has the shortest distance from the source node.
222+
// If it's distance is below the threshold of the currentBin (i.e., the one processed in the
223+
//next step), then it means its path from source cannot be improved further
224+
// (since all values in the next bucket are further from the source node).
225+
226+
//The next criterion is relevant when we continue with the same bucket in the next iteration.
227+
//Again, we consider the terminal t which currently has the shortest distance from the source node.
228+
//If this terminal is inside the current Bucket,
229+
//We consider from all nodes that will be relaxed later on, the one with smallest distance from source
230+
//(let's call this node r)
231+
//Since any nodes that will be updated in the next iteration, will end up having a distance >=d(r)
232+
//any future nodes examined for the same bucket during the current phase, will have a distance d >= d(r).
233+
//Hence, if d(t) <=d(r) we can be certain neither of those next examined vertices will be able to improve
234+
// t's path (or improve the path to any other terminal since they too would end up with a value >=d(r)).
235+
236+
//Note it is not required that t (the closet terminal) is in the current bucket B.
237+
//After a path has been merged, we return back to Bucket 0. If t is in the bucket B where B>0.
238+
//Then at some point, we must pass from a bucket B' <B to a bucket B<=B'' hence the first criterion
239+
//will be able to locate t via the change of bucket criterion.
225240

226241
long terminalId = nextTerminal(terminalQueue);
227242
if (terminalId == NO_TERMINAL) {
@@ -287,7 +302,15 @@ public DijkstraResult compute() {
287302
terminalQueue.pop();
288303
shouldBreak = updateSteinerTree(terminalId, frontierIndex, paths, pathResultBuilder);
289304
currentBin = 0;
290-
} else { //otherwise proceed as normal, sync the contents of the bucket for each thread to the global queue.
305+
//Note if this scenario occurs:
306+
// The content in the local buckets which normally would have been synced, remains stored inside buckets
307+
//and can be processed next time the currentBin is set as the smallest bin.
308+
//There might be some invalid situations (for example node a is located in multiple local buckets of different threads)
309+
//But such situations are also possible for the original delta-stepping algorithm,
310+
//although admittedly, this might be more frequent due to the "revert path to zero" steiner heuristic!
311+
// I doubt this is a very big problem though
312+
} else {
313+
//otherwise proceed as normal, sync the contents of the bucket for each thread to the global queue.
291314
// Phase 2
292315
syncPhase(tasks, currentBin, frontierIndex);
293316
}

0 commit comments

Comments
 (0)