private readonly IndexMinPQ<Double> _pq; // priority queue of vertices

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Computes a shortest-paths tree from the source vertex <tt>s</tt> to every
        /// other vertex in the edge-weighted graph <tt>G</tt>.
        /// </summary>
        /// <param name="g">g the edge-weighted graph</param>
        /// <param name="s">s the source vertex</param>
        /// <exception cref="ArgumentException">if an edge weight is negative</exception>
        /// <exception cref="ArgumentException">unless 0 &lt;= <tt>s</tt> &lt;= <tt>V</tt> - 1</exception>
        public DijkstraUndirectedSP(EdgeWeightedGraph g, int s)
        {
            foreach (var e in g.Edges())
            {
                if (e.Weight < 0)
                    throw new ArgumentException($"edge {e} has negative weight");
            }

            _distTo = new double[g.V];
            _edgeTo = new EdgeW[g.V];
            for (var v = 0; v < g.V; v++)
                _distTo[v] = double.PositiveInfinity;
            _distTo[s] = 0.0;

            // relax vertices in order of distance from s
            _pq = new IndexMinPQ<Double>(g.V);
            _pq.Insert(s, _distTo[s]);
            while (!_pq.IsEmpty())
            {
                var v = _pq.DelMin();
                foreach (var e in g.Adj(v))
                    Relax(e, v);
            }

            // check optimality conditions
            //assert check(G, s);
        }
Пример #2
0
        private readonly IndexMinPQ <Double> _pq;   // priority queue of vertices

        /// <summary>
        /// Computes a shortest-paths tree from the source vertex <tt>s</tt> to every
        /// other vertex in the edge-weighted graph <tt>G</tt>.
        /// </summary>
        /// <param name="g">g the edge-weighted graph</param>
        /// <param name="s">s the source vertex</param>
        /// <exception cref="ArgumentException">if an edge weight is negative</exception>
        /// <exception cref="ArgumentException">unless 0 &lt;= <tt>s</tt> &lt;= <tt>V</tt> - 1</exception>
        public DijkstraUndirectedSP(EdgeWeightedGraph g, int s)
        {
            foreach (var e in g.Edges())
            {
                if (e.Weight < 0)
                {
                    throw new ArgumentException($"edge {e} has negative weight");
                }
            }

            _distTo = new double[g.V];
            _edgeTo = new EdgeW[g.V];
            for (var v = 0; v < g.V; v++)
            {
                _distTo[v] = double.PositiveInfinity;
            }
            _distTo[s] = 0.0;

            // relax vertices in order of distance from s
            _pq = new IndexMinPQ <Double>(g.V);
            _pq.Insert(s, _distTo[s]);
            while (!_pq.IsEmpty())
            {
                var v = _pq.DelMin();
                foreach (var e in g.Adj(v))
                {
                    Relax(e, v);
                }
            }

            // check optimality conditions
            //assert check(G, s);
        }
Пример #3
0
 /// <summary>
 /// scan vertex v
 /// </summary>
 /// <param name="g"></param>
 /// <param name="v"></param>
 private void Scan(EdgeWeightedGraph g, int v)
 {
     _marked[v] = true;
     foreach (var e in g.Adj(v))
     {
         var w = e.Other(v);
         if (_marked[w])
         {
             continue;                     // v-w is obsolete edge
         }
         if (e.Weight < _distTo[w])
         {
             _distTo[w] = e.Weight;
             _edgeTo[w] = e;
             if (_pq.Contains(w))
             {
                 _pq.DecreaseKey(w, _distTo[w]);
             }
             else
             {
                 _pq.Insert(w, _distTo[w]);
             }
         }
     }
 }
Пример #4
0
 /// <summary>
 /// add all edges e incident to v onto pq if the other endpoint has not yet been scanned
 /// </summary>
 /// <param name="g"></param>
 /// <param name="v"></param>
 private void Scan(EdgeWeightedGraph g, int v)
 {
     //assert !marked[v];
     _marked[v] = true;
     foreach (var e in g.Adj(v))
     {
         if (!_marked[e.Other(v)])
         {
             _pq.Insert(e);
         }
     }
 }
Пример #5
0
 /// <summary>
 /// add all edges e incident to v onto pq if the other endpoint has not yet been scanned
 /// </summary>
 /// <param name="g"></param>
 /// <param name="v"></param>
 private void Scan(EdgeWeightedGraph g, int v)
 {
     //assert !marked[v];
     _marked[v] = true;
     foreach (var e in g.Adj(v))
         if (!_marked[e.Other(v)]) _pq.Insert(e);
 }
Пример #6
0
        /// <summary>
        /// check optimality conditions:
        /// (i) for all edges e = v-w:            distTo[w] &lt;= distTo[v] + e.weight()
        /// (ii) for all edge e = v-w on the SPT: distTo[w] == distTo[v] + e.weight()
        /// </summary>
        /// <param name="g"></param>
        /// <param name="s"></param>
        /// <returns></returns>
        public bool Check(EdgeWeightedGraph g, int s)
        {
            // check that edge weights are nonnegative
            if (g.Edges().Any(e => e.Weight < 0))
            {
                Console.Error.WriteLine("negative edge weight detected");
                return(false);
            }

            // check that distTo[v] and edgeTo[v] are consistent
            if (Math.Abs(_distTo[s]) > 1E12 || _edgeTo[s] != null)
            {
                Console.Error.WriteLine("distTo[s] and edgeTo[s] inconsistent");
                return(false);
            }
            for (var v = 0; v < g.V; v++)
            {
                if (v == s)
                {
                    continue;
                }
                if (_edgeTo[v] == null && !double.IsPositiveInfinity(_distTo[v]))
                {
                    Console.Error.WriteLine("distTo[] and edgeTo[] inconsistent");
                    return(false);
                }
            }

            // check that all edges e = v-w satisfy distTo[w] <= distTo[v] + e.weight()
            for (var v = 0; v < g.V; v++)
            {
                foreach (var e in g.Adj(v))
                {
                    var w = e.Other(v);
                    if (_distTo[v] + e.Weight < _distTo[w])
                    {
                        Console.Error.WriteLine($"edge {e} not relaxed");
                        return(false);
                    }
                }
            }

            // check that all edges e = v-w on SPT satisfy distTo[w] == distTo[v] + e.weight()
            for (var w = 0; w < g.V; w++)
            {
                if (_edgeTo[w] == null)
                {
                    continue;
                }
                var e = _edgeTo[w];
                if (w != e.Either() && w != e.Other(e.Either()))
                {
                    return(false);
                }
                int v = e.Other(w);
                if (Math.Abs(_distTo[v] + e.Weight - _distTo[w]) > 1E12)
                {
                    Console.Error.WriteLine($"edge {e} on shortest path not tight");
                    return(false);
                }
            }
            return(true);
        }
        /// <summary>
        /// check optimality conditions:
        /// (i) for all edges e = v-w:            distTo[w] &lt;= distTo[v] + e.weight()
        /// (ii) for all edge e = v-w on the SPT: distTo[w] == distTo[v] + e.weight()
        /// </summary>
        /// <param name="g"></param>
        /// <param name="s"></param>
        /// <returns></returns>
        public bool Check(EdgeWeightedGraph g, int s)
        {
            // check that edge weights are nonnegative
            if (g.Edges().Any(e => e.Weight < 0))
            {
                Console.Error.WriteLine("negative edge weight detected");
                return false;
            }

            // check that distTo[v] and edgeTo[v] are consistent
            if (Math.Abs(_distTo[s]) > 1E12 || _edgeTo[s] != null)
            {
                Console.Error.WriteLine("distTo[s] and edgeTo[s] inconsistent");
                return false;
            }
            for (var v = 0; v < g.V; v++)
            {
                if (v == s) continue;
                if (_edgeTo[v] == null && !double.IsPositiveInfinity(_distTo[v]))
                {
                    Console.Error.WriteLine("distTo[] and edgeTo[] inconsistent");
                    return false;
                }
            }

            // check that all edges e = v-w satisfy distTo[w] <= distTo[v] + e.weight()
            for (var v = 0; v < g.V; v++)
            {
                foreach (var e in g.Adj(v))
                {
                    var w = e.Other(v);
                    if (_distTo[v] + e.Weight < _distTo[w])
                    {
                        Console.Error.WriteLine($"edge {e} not relaxed");
                        return false;
                    }
                }
            }

            // check that all edges e = v-w on SPT satisfy distTo[w] == distTo[v] + e.weight()
            for (var w = 0; w < g.V; w++)
            {
                if (_edgeTo[w] == null) continue;
                var e = _edgeTo[w];
                if (w != e.Either() && w != e.Other(e.Either())) return false;
                int v = e.Other(w);
                if (Math.Abs(_distTo[v] + e.Weight - _distTo[w]) > 1E12)
                {
                    Console.Error.WriteLine($"edge {e} on shortest path not tight");
                    return false;
                }
            }
            return true;
        }
Пример #8
0
 /// <summary>
 /// scan vertex v
 /// </summary>
 /// <param name="g"></param>
 /// <param name="v"></param>
 private void Scan(EdgeWeightedGraph g, int v)
 {
     _marked[v] = true;
     foreach (var e in g.Adj(v))
     {
         var w = e.Other(v);
         if (_marked[w]) continue;         // v-w is obsolete edge
         if (e.Weight < _distTo[w])
         {
             _distTo[w] = e.Weight;
             _edgeTo[w] = e;
             if (_pq.Contains(w)) _pq.DecreaseKey(w, _distTo[w]);
             else _pq.Insert(w, _distTo[w]);
         }
     }
 }