MCPcopy Create free account
hub / github.com/codemix/graph / dijkstra

Method dijkstra

packages/graph/src/Steps.ts:5181–5261  ·  view source on GitHub ↗

* Dijkstra's algorithm for weighted shortest path. * Time complexity: O((V + E) log V) with a binary heap.

(
    source: GraphSource<any>,
    startVertex: Vertex<any, any>,
    targetId: ElementId | undefined,
    targetCondition: Condition | undefined,
    direction: Direction,
    edgeLabels: readonly string[],
    maxDepth: number,
    weightProperty: string,
  )

Source from the content-addressed store, hash-verified

5179 * Time complexity: O((V + E) log V) with a binary heap.
5180 */
5181 private dijkstra(
5182 source: GraphSource<any>,
5183 startVertex: Vertex<any, any>,
5184 targetId: ElementId | undefined,
5185 targetCondition: Condition | undefined,
5186 direction: Direction,
5187 edgeLabels: readonly string[],
5188 maxDepth: number,
5189 weightProperty: string,
5190 ): ShortestPathResult | null {
5191 // Early termination: check if start is target
5192 if (this.isTarget(startVertex, targetId, targetCondition)) {
5193 return { vertices: [startVertex], edges: [], length: 0, weight: 0 };
5194 }
5195
5196 // Dijkstra data structures
5197 const distances = new Map<ElementId, number>([[startVertex.id, 0]]);
5198 const previous = new Map<ElementId, { vertex: Vertex<any, any>; edge: Edge<any, any> } | null>([
5199 [startVertex.id, null],
5200 ]);
5201
5202 // Priority queue using binary min-heap for O(log V) operations
5203 const pq = new MinHeap<{ vertex: Vertex<any, any>; distance: number }>(
5204 (a, b) => a.distance - b.distance,
5205 );
5206 pq.push({ vertex: startVertex, distance: 0 });
5207
5208 let iterations = 0;
5209 // Safety limit: prevent DoS with hard cap independent of maxDepth
5210 const maxIterations = Math.min(maxDepth * 1000, 100000);
5211
5212 while (pq.size > 0 && iterations < maxIterations) {
5213 iterations++;
5214
5215 // Get vertex with minimum distance (O(log V) operation)
5216 const current = pq.pop();
5217 if (!current) break;
5218
5219 const { vertex: currentVertex, distance: currentDistance } = current;
5220
5221 // Skip if we've already processed this with a shorter distance
5222 const storedDistance = distances.get(currentVertex.id);
5223 if (storedDistance !== undefined && storedDistance < currentDistance) {
5224 continue;
5225 }
5226
5227 // Check if we've reached the target
5228 if (this.isTarget(currentVertex, targetId, targetCondition)) {
5229 // Reconstruct path
5230 return this.reconstructPath(currentVertex, previous, currentDistance);
5231 }
5232
5233 // Get neighbors
5234 const neighbors = this.getNeighbors(source, currentVertex, direction, edgeLabels);
5235
5236 for (const { vertex: neighbor, edge } of neighbors) {
5237 // Get edge weight (default to 1 if not found)
5238 // Note: Missing or non-numeric weights default to 1 for unweighted behavior

Callers 1

traverseMethod · 0.95

Calls 6

isTargetMethod · 0.95
pushMethod · 0.95
popMethod · 0.95
reconstructPathMethod · 0.95
getNeighborsMethod · 0.95
getMethod · 0.65

Tested by

no test coverage detected