/// <summary> /// Finds the shortest, weighted path between two vertices, if one exists. Assumes there are no negative-weight edges in the graph. /// </summary> /// <param name="from">The start of the path.</param> /// <param name="to">The end of the path.</param> /// <param name="path">The path that was found. <code>null</code> if there is no path.</param> /// <returns><code>true</code> if there is a path; <code>false</code> otherwise.</returns> public bool Dijkstra(uint from, uint to, out Path path) { path = null; DMinHeap<int, uint> fringe = new DMinHeap<int, uint>(); Dictionary<uint, uint> parents = new Dictionary<uint, uint>(); Dictionary<uint, int> dist = new Dictionary<uint, int>(); this.DijkstraInit(from, dist, fringe); uint current; while (fringe.Count > 0) { current = fringe.Extract(); if (current == to) { path = Path.FromParents(from, to, parents, this); return true; } this.DijkstraRelax(current, dist, parents, fringe); } return false; }
/// <summary> /// Finds the shortest, weighted path between two vertices, if one exists. Assumes there are no negative-weight edges in the graph. /// </summary> /// <param name="from">The start of the path.</param> /// <param name="to">The end of the path.</param> /// <param name="path">The path that was found. <code>null</code> if there is no path.</param> /// <returns><code>true</code> if there is a path; <code>false</code> otherwise.</returns> public bool Dijkstra(uint from, uint to, out Path path) { path = null; DMinHeap <int, uint> fringe = new DMinHeap <int, uint>(); Dictionary <uint, uint> parents = new Dictionary <uint, uint>(); Dictionary <uint, int> dist = new Dictionary <uint, int>(); this.DijkstraInit(from, dist, fringe); uint current; while (fringe.Count > 0) { current = fringe.Extract(); if (current == to) { path = Path.FromParents(from, to, parents, this); return(true); } this.DijkstraRelax(current, dist, parents, fringe); } return(false); }
private void DijkstraInit(uint from, Dictionary<uint, int> dist, DMinHeap<int, uint> fringe) { foreach (uint v in this.Vertices.Keys) { if (v == from) dist[v] = 0; else dist[v] = int.MaxValue; fringe.Add(v, dist[v]); } }
/// <summary> /// Find the shortest, weighted paths from a given vertex to all other vertices. Assumes there are no negative-weight edges in the graph. /// </summary> /// <param name="from">The vertex to calculate the shortest paths from.</param> /// <param name="lengths">The lengths of the shortest paths to all vertices.</param> /// <param name="parents">The parent-pointers for the paths to all vertices.</param> public void Dijkstra(uint from, out Dictionary<uint, int> lengths, out Dictionary<uint, uint> parents) { DMinHeap<int, uint> fringe = new DMinHeap<int, uint>(); parents = new Dictionary<uint, uint>(); lengths = new Dictionary<uint, int>(); this.DijkstraInit(from, lengths, fringe); uint current; while (fringe.Count > 0) { current = fringe.Extract(); this.DijkstraRelax(current, lengths, parents, fringe); } }
private void DijkstraInit(uint from, Dictionary <uint, int> dist, DMinHeap <int, uint> fringe) { foreach (uint v in this.Vertices.Keys) { if (v == from) { dist[v] = 0; } else { dist[v] = int.MaxValue; } fringe.Add(v, dist[v]); } }
private void DijkstraRelax(uint current, Dictionary<uint, int> dist, Dictionary<uint, uint> parents, DMinHeap<int, uint> fringe) { foreach (Edge e in this.Vertices[current].Neighbours.Values) { if (!fringe.ContainsValue(e.To)) continue; int newDist = dist[current] + e.Weight; if (newDist < dist[e.To]) { dist[e.To] = newDist; parents[e.To] = current; fringe.ChangeKey(e.To, newDist); } } }
/// <summary> /// Find the shortest, weighted paths from a given vertex to all other vertices. Assumes there are no negative-weight edges in the graph. /// </summary> /// <param name="from">The vertex to calculate the shortest paths from.</param> /// <param name="lengths">The lengths of the shortest paths to all vertices.</param> /// <param name="parents">The parent-pointers for the paths to all vertices.</param> public void Dijkstra(uint from, out Dictionary <uint, int> lengths, out Dictionary <uint, uint> parents) { DMinHeap <int, uint> fringe = new DMinHeap <int, uint>(); parents = new Dictionary <uint, uint>(); lengths = new Dictionary <uint, int>(); this.DijkstraInit(from, lengths, fringe); uint current; while (fringe.Count > 0) { current = fringe.Extract(); this.DijkstraRelax(current, lengths, parents, fringe); } }
public static T[] PatienceSort(T[] input, int start, int length) { CheckArguments(input, start, length); List <Stack <T> > stacks = new List <Stack <T> >(); for (int i = start; i < start + length; i++) { Stack <T> stack = new Stack <T>(); stack.Push(input[i]); int index = stacks.BinarySearch(stack); if (index < 0) { index = ~index; } if (index != stacks.Count) { stacks[index].Push(input[i]); } else { stacks.Add(stack); } } DMinHeap <T, Stack <T> > heap = new DMinHeap <T, Stack <T> >(3); foreach (Stack <T> s in stacks) { heap.Add(s, s.Peek()); } for (int i = start; i < start + length; i++) { Stack <T> stack = heap.Extract(); input[i] = stack.Pop(); if (stack.Count != 0) { heap.Add(stack, stack.Peek()); } } return(input); }
/// <summary> /// Returns <code>true</code> if there is a path between two given nodes in the given, weighted graph; <code>false</code> otherwise. /// </summary> /// <param name="graph">The graph to find the path in.</param> /// <param name="start">The start of the path.</param> /// <param name="end">The end of the path.</param> /// <param name="path">A list containing the edges of the path that was found, in order. Empty if there is no path.</param> /// <returns><code>true</code> if there is a path; <code>false</code> otherwise.</returns> public static bool ShortestPath(IGraph <IWeightedGraphEdge> graph, IGraphNode <IWeightedGraphEdge> start, IGraphNode <IWeightedGraphEdge> end, out List <IWeightedGraphEdge> path) { path = new List <IWeightedGraphEdge>(); DMinHeap <DijkstraNode> open = new DMinHeap <DijkstraNode>(); open.Add(new DijkstraNode(start, null, null)); HashSet <uint> closed = new HashSet <uint>(); closed.Add(start.ID); DijkstraNode node; while (open.Count > 0) { node = open.Extract(); foreach (IWeightedGraphEdge e in node.Node.Neighbours) { if (closed.Contains(e.To)) { continue; } else if (e.To == end.ID) { path.Add(e); while (node.Parent != null) { path.Add(node.Edge); node = node.Parent; } path.Reverse(); return(true); } open.Add(new DijkstraNode(graph.Nodes[e.To], e, node)); } } return(false); }
private void DijkstraRelax(uint current, Dictionary <uint, int> dist, Dictionary <uint, uint> parents, DMinHeap <int, uint> fringe) { foreach (Edge e in this.Vertices[current].Neighbours.Values) { if (!fringe.ContainsValue(e.To)) { continue; } int newDist = dist[current] + e.Weight; if (newDist < dist[e.To]) { dist[e.To] = newDist; parents[e.To] = current; fringe.ChangeKey(e.To, newDist); } } }