public static DijkstraPath GetDijkstraPath(DirectionalGraph graph, int startId, int destinationId) { var nodes = graph.Nodes; var start = NodeUtil.GetNodeWithId(nodes, startId); var destination = NodeUtil.GetNodeWithId(nodes, destinationId); if (start == null || destination == null) { return(null); } var accumulativeDistance = 0; var cur = start; cur.LowestDistance = 0; do { //3. For ea connected cur.Edges.ForEach(edge => { // set distanceFromCurrent = accumulative length + length to node var distanceFromCurrent = accumulativeDistance + edge.Value; //4. If node has no distance marked, or distanceFromCurrent<marked node distance... var connectedNode = NodeUtil.GetNodeWithId(nodes, edge.NodeId); if (!connectedNode.LowestDistance.HasValue || distanceFromCurrent < connectedNode.LowestDistance.Value) { // set marked node distance to distanceFromCurrent connectedNode.LowestDistance = distanceFromCurrent; } }); //4. Once all nodes marked, mark current node as visited cur.Visited = true; //5. Stop if at destination node if (cur == destination) { break; } //6. Else goto the unvisited node with lowest value cur = GetPrevNodeForPath(nodes); //7. Set accumulativeDistance = node value if (!cur.LowestDistance.HasValue) { throw new ArgumentNullException("Tried to get lowestDistance value for a Node, but there was none"); } accumulativeDistance = cur.LowestDistance.Value; //8. repeat from 3. } while (cur != null); // Get path return(new DijkstraPath(nodes, start, destination)); // then make it multi-threaded }
static Node GetPrevWithLowestValue(List <Node> nodes, Node fromNode) { // For ea prev Node nodeWithLowestValue = null; var edges = fromNode.Edges; for (int e = 0; e < edges.Count; e++) { var connectedNodeId = edges[e].NodeId; var connectedNode = NodeUtil.GetNodeWithId(nodes, connectedNodeId); var prevNodeValue = connectedNode.LowestDistance; if (nodeWithLowestValue == null || (prevNodeValue.HasValue && prevNodeValue.Value < nodeWithLowestValue.LowestDistance)) { nodeWithLowestValue = connectedNode; } } // Return one with lowest val return(nodeWithLowestValue); }