/// <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;
                }
示例#2
0
                /// <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);
                    }
                }
示例#5
0
 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);
                        }
                    }
                }
示例#7
0
                /// <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);
                }
示例#9
0
                /// <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);
                }
示例#10
0
                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);
                        }
                    }
                }