Пример #1
0
        /// <summary>
        /// Computes a shortest paths tree from <tt>s</tt> to every other vertex in the edge-weighted digraph <tt>G</tt>.
        /// </summary>
        /// <param name="graph">the edge-weighted digraph</param>
        /// <param name="source">the source vertex</param>
        public DijkstraDirectedSearch(EdgeWeightedDirectedGraph graph, int source)
        {
            for (int i = graph.NumberOfEdges - 1; i >= 0; i--)
            {
                WeightedGraphEdge e = graph.GetEdge(i);
                if (e.Cost < 0)
                {
                    throw new RPGException(ErrorMessage.INTERNAL_BAD_ARGUMENT, "edge " + e + " has negative weight");
                }
            }
            distTo = new double[graph.NumberOfVertices];
            edgeTo = new WeightedGraphEdge[graph.NumberOfVertices];
            for (int v = 0; v < graph.NumberOfVertices; v++)
            {
                distTo[v] = Double.PositiveInfinity;
            }
            distTo[source] = 0.0;

            // relax vertices in order of distance from s
            pq = new IndexMinPQ <Double>(graph.NumberOfVertices);
            pq.Insert(source, distTo[source]);
            while (!pq.IsEmpty)
            {
                int v = pq.DelMin();
                WeightedGraphEdge[] adj = graph.GetVertexAdjacencies(v);
                for (int i = adj.Length - 1; i >= 0; i--)
                {
                    Relax(adj[i], v);
                }
            }

            // check optimality conditions
            Debug.Assert(Check(graph, source));
        }
Пример #2
0
        /// <summary>
        /// Relax the edge and update the priority queue if needed.
        /// </summary>
        /// <param name="edge">the edge</param>
        /// <param name="source">the source vertex where the edge leads from</param>
        private void Relax(WeightedGraphEdge edge, int source)
        {
            int v, w;

            if (source == edge.From)
            {
                v = edge.From;
                w = edge.To;
            }
            else
            {
                v = edge.To;
                w = edge.From;
            }
            if (distTo[w] > distTo[v] + edge.Cost)
            {
                distTo[w] = distTo[v] + edge.Cost;
                edgeTo[w] = edge;
                if (pq.Contains(w))
                {
                    pq.DecreaseKey(w, distTo[w]);
                }
                else
                {
                    pq.Insert(w, distTo[w]);
                }
            }
        }
Пример #3
0
        /**
         * Relax the edge and update the priority queue if needed.
         * @param edge the edge
         * @param source the source vertex where the edge leads from
         */
        private void Relax(WeightedGraphEdge edge, int source)
        {
            int v, w;

            if (source == edge.From)
            {
                v = edge.From;
                w = edge.To;
            }
            else
            {
                v = edge.To;
                w = edge.From;
            }
            // UnityEngine.Debug.Log("find distance from " + w+" to "+v);
            if (distTo[w] > distTo[v] + edge.Cost)
            {
                distTo[w] = distTo[v] + edge.Cost;
                edgeTo[w] = edge;
                if (pq.Contains(w))
                {
                    pq.DecreaseKey(w, distTo[w]);
                }
                else
                {
                    pq.Insert(w, distTo[w]);
                }
            }
        }
Пример #4
0
 /**
  * Returns a shortest path from the source vertex <tt>s</tt> to vertex
  * <tt>v</tt>.
  * @param v the destination vertex
  * @return a shortest path from the source vertex <tt>s</tt> to vertex
  *         <tt>v</tt> as an iterable of edges, and <tt>null</tt> if no such
  *         path
  */
 public WeightedGraphEdge[] pathTo(int v)
 {
     WeightedGraphEdge[] path = null;
     if (HasPathTo(v))
     {
         path = new WeightedGraphEdge[0];
         WeightedGraphEdge e = edgeTo[v];
         int lastVertex      = v;
         for (; e != null;)
         {
             path = ArrayUtilities.Instance.ExtendArray(e, path);
             if (e.From == lastVertex)
             {
                 lastVertex = e.To;
                 e          = edgeTo[e.To];
             }
             else
             {
                 lastVertex = e.From;
                 e          = edgeTo[e.From];
             }
         }
     }
     return(path);
 }
 /// <summary>
 /// Gets the directed edges incident from vertex <tt>v</tt>.
 /// </summary>
 /// <param name="v">vertex v</param>
 /// <returns><see cref="WeightedGraphEdge"/>[]</returns>
 public WeightedGraphEdge[] GetVertexAdjacencies(int v)
 {
     WeightedGraphEdge[] adj = new WeightedGraphEdge[0];
     for (int i = edges.Length - 1; i >= 0; i--)
     {
         if (edges[i].From == v)
         {
             adj = ArrayUtilities.Instance.ExtendArray(edges[i], adj);
         }
     }
     return(adj);
 }
Пример #6
0
        /// <summary>
        /// Determines if edge v-w exists on the graph.
        /// </summary>
        /// <param name="e"><see cref="WeightedGraphEdge"/> v-w</param>
        /// <returns>if edge v-w exists; false otherwise</returns>
        public bool HasEdge(WeightedGraphEdge e)
        {
            bool exists = false;

            for (int i = edges.Length - 1; i >= 0; i--)
            {
                if (edges[i].EqualsUndirected(e))
                {
                    exists = true;
                    break;
                }
            }
            return(exists);
        }
Пример #7
0
 /// <summary>
 /// Returns a shortest path from the source vertex <tt>s</tt> to vertex <tt>v</tt>.
 /// </summary>
 /// <param name="v">the destination vertex</param>
 /// <returns>a shortest path from the source vertex <tt>s</tt> to vertex <tt>v</tt> as an iterable of edges, and <tt>null</tt> if no such path</returns>
 public WeightedGraphEdge[] PathTo(int v)
 {
     WeightedGraphEdge[] path = null;
     if (HasPathTo(v))
     {
         path = new WeightedGraphEdge[0];
         for (WeightedGraphEdge e = edgeTo[v]; e != null;
              e = edgeTo[e.From])
         {
             path = ArrayUtilities.Instance.ExtendArray(e, path);
         }
     }
     return(path);
 }
Пример #8
0
 /// <summary>
 /// Adds edge v-w to this graph.
 /// </summary>
 /// <param name="e"><see cref="WeightedGraphEdge"/> v-w</param>
 public void AddEdge(WeightedGraphEdge e)
 {
     if (!HasEdge(e))
     {
         if (!HasVertex(e.From))
         {
             AddVertex(e.From);
         }
         if (!HasVertex(e.To))
         {
             AddVertex(e.To);
         }
         edges = ArrayUtilities.Instance.ExtendArray(new WeightedGraphEdge(e), edges);
     }
 }
Пример #9
0
        // check optimality conditions:
        // (i) for all edges e: distTo[e.to()] <= distTo[e.from()] + e.weight()
        // (ii) for all edge e on the SPT: distTo[e.to()] == distTo[e.from()] +
        // e.weight()
        private bool Check(EdgeWeightedDirectedGraph graph, int s)
        {
            // check that edge weights are nonnegative
            for (int i = graph.NumberOfEdges - 1; i >= 0; i--)
            {
                WeightedGraphEdge e = graph.GetEdge(i);
                if (e.Cost < 0)
                {
                    Console.WriteLine("negative edge weight detected");
                    return(false);
                }
            }
            // check that distTo[v] and edgeTo[v] are consistent
            if (distTo[s] != 0.0 || edgeTo[s] != null)
            {
                Console.WriteLine("distTo[s] and edgeTo[s] inconsistent");
                return(false);
            }
            for (int v = graph.NumberOfVertices - 1; v >= 0; v--)
            {
                if (v == s)
                {
                    continue;
                }
                if (edgeTo[v] == null && distTo[v] != Double.PositiveInfinity)
                {
                    Console.WriteLine("distTo[] and edgeTo[] inconsistent");
                    return(false);
                }
            }

            // check that all edges e = v->w satisfy distTo[w] <= distTo[v] +
            // e.weight()
            for (int v = graph.NumberOfVertices - 1; v >= 0; v--)
            {
                WeightedGraphEdge[] adj = graph.GetVertexAdjacencies(v);
                for (int i = adj.Length - 1; i >= 0; i--)
                {
                    WeightedGraphEdge e = adj[i];
                    int w;
                    if (v == e.To)
                    {
                        w = e.From;
                    }
                    else
                    {
                        w = e.To;
                    }
                    if (distTo[v] + e.Cost < distTo[w])
                    {
                        Console.WriteLine("edge " + e + " not relaxed");
                        return(false);
                    }
                }
            }

            // check that all edges e = v->w on SPT satisfy distTo[w] == distTo[v] +
            // e.weight()
            for (int w = 0; w < graph.NumberOfVertices; w++)
            {
                if (edgeTo[w] == null)
                {
                    continue;
                }
                WeightedGraphEdge e = edgeTo[w];
                int v = e.From;
                if (w != e.To)
                {
                    return(false);
                }
                if (distTo[v] + e.Cost != distTo[w])
                {
                    Console.WriteLine("edge " + e + " on shortest path not tight");
                    return(false);
                }
            }
            return(true);
        }
Пример #10
0
 /// <summary>
 /// Creates a new instance of <see cref="WeightedGraphEdge"/>.
 /// </summary>
 /// <param name="edge">the edge being cloned</param>
 public WeightedGraphEdge(WeightedGraphEdge edge) : base(edge)
 {
     Cost = edge.Cost;
 }