示例#1
0
        public BellmanFordShortestPathAlgorithm(EdgeWeightedDigraph graph, Int32 vertice)
        {
            this._distTo  = new double[graph.VerticesCount];
            this._edgeTo  = new Edge[graph.VerticesCount];
            this._onQueue = new Boolean[graph.VerticesCount];

            for (int v = 0; v < graph.VerticesCount; v++)
            {
                this._distTo[v] = Double.PositiveInfinity;
            }

            this._distTo[vertice] = 0.0;

            this._queue = new AST.Queue <Int32>();
            this._queue.Enqueue(vertice);
            this._onQueue[vertice] = true;

            while (!this._queue.IsEmpty && !this.HasNegativeCycle)
            {
                Int32 v = this._queue.Dequeue();

                this._onQueue[v] = false;

                this.Relax(graph, v);
            }
        }
示例#2
0
        private void Relax(EdgeWeightedDigraph graph, Int32 vertice)
        {
            foreach (Edge edge in graph.GetAdjacentVertices(vertice))
            {
                Int32 target = edge.Target;

                if (this._distTo[target] > this._distTo[vertice] + edge.Weight)
                {
                    this._distTo[target] = this._distTo[vertice] + edge.Weight;
                    this._edgeTo[target] = edge;

                    if (!this._onQueue[target])
                    {
                        this._queue.Enqueue(target);
                        this._onQueue[target] = true;
                    }
                }

                if (this._cost++ % graph.VerticesCount == 0)
                {
                    this.FindNegativeCycle();

                    if (this.HasNegativeCycle)
                    {
                        return;  // Found a negative cycle.
                    }
                }
            }
        }
        public EdgeWeightedCycleChecker(EdgeWeightedDigraph graph)
        {
            this._visited = new Boolean[graph.VerticesCount];
            this._onStack = new Boolean[graph.VerticesCount];
            this._edgeTo  = new Edge[graph.VerticesCount];

            for (int i = 0; i < graph.VerticesCount; i++)
            {
                if (!this._visited[i])
                {
                    this.DFS(graph, i);
                }
            }
        }
示例#4
0
        private void FindNegativeCycle() // by finding a cycle in predecessor graph.
        {
            Int32 vertice             = this._edgeTo.Length;
            EdgeWeightedDigraph graph = new EdgeWeightedDigraph(vertice);

            for (int i = 0; i < vertice; i++)
            {
                if (this._edgeTo[i] != null)
                {
                    graph.AddEdge(this._edgeTo[i]);
                }
            }

            EdgeWeightedCycleChecker checker = EdgeWeightedCycleChecker.Create(graph);

            this._cycle = checker.GetCycle();
        }
        private void DFS(EdgeWeightedDigraph graph, Int32 vertice)
        {
            this._onStack[vertice] = true;
            this._visited[vertice] = true;

            foreach (Edge edge in graph.GetAdjacentVertices(vertice))
            {
                Int32 targetVertice = edge.Target;

                // Short circuit if directed cycle found.
                if (this._cycle != null)
                {
                    return;
                }

                // Found new vertex, so recur.
                if (!this._visited[targetVertice])
                {
                    this._edgeTo[targetVertice] = edge;

                    this.DFS(graph, targetVertice);
                }

                // trace back directed cycle
                else if (this._onStack[targetVertice])
                {
                    this._cycle = new AST.Stack <Edge>();

                    Edge tempEdge = edge;

                    while (tempEdge.Source != targetVertice)
                    {
                        this._cycle.Push(tempEdge);

                        tempEdge = this._edgeTo[tempEdge.Source];
                    }

                    this._cycle.Push(tempEdge);

                    return;
                }
            }

            this._onStack[vertice] = false;
        }
示例#6
0
        public DijkstraShortestPathAlgorithm(EdgeWeightedDigraph graph, Int32 vertice)
        {
            foreach (Edge edge in graph.GetEdges())
            {
                if (edge.Weight < 0)
                {
                    throw new InvalidOperationException("Edge" + edge + " has negative weight.");
                }
            }

            this._distTo = new Double[graph.VerticesCount];
            this._edgeTo = new Edge[graph.VerticesCount];

            for (int i = 0; i < graph.VerticesCount; i++)
            {
                this._distTo[i] = Double.PositiveInfinity;
            }

            this._distTo[vertice] = 0.0;

            // Relax vertices in order of distance from vertice.
            this._crossingEdgesByWeight = new IndexedMinPQ <Double>(graph.VerticesCount)
            {
                { vertice, this._distTo[vertice] }
            };

            while (!this._crossingEdgesByWeight.IsEmpty)
            {
                Int32 v = this._crossingEdgesByWeight.DeleteMin();

                foreach (Edge edge in graph.GetAdjacentVertices(v))
                {
                    this.Relax(edge);
                }
            }
        }
 public static EdgeWeightedCycleChecker Create(EdgeWeightedDigraph graph)
 {
     return(new EdgeWeightedCycleChecker(graph));
 }