private void EnqueueDeviationPaths(
            IQueue <DeviationPath> queue,
            IDictionary <TVertex, double> distances,
            TEdge[] path,
            int iedge,
            TVertex previousVertex,
            double previousWeight,
            Dictionary <TVertex, int> pathVertices
            )
        {
            Contract.Requires(queue != null);
            Contract.Requires(distances != null);
            Contract.Requires(path != null);

            var edge = path[iedge];

            foreach (var deviationEdge in this.VisitedGraph.OutEdges(previousVertex))
            {
                // skip self edges,
                // skip equal edges,
                if (deviationEdge.Equals(edge) ||
                    EdgeExtensions.IsSelfEdge <TVertex, TEdge>(deviationEdge))
                {
                    continue;
                }

                // any edge obviously creating a loop
                var atarget = deviationEdge.Target;

                double adistance;
                if (distances.TryGetValue(atarget, out adistance))
                {
                    var deviationWeight =
                        this.DistanceRelaxer.Combine(
                            previousWeight,
                            this.DistanceRelaxer.Combine(
                                this.edgeWeights(deviationEdge),
                                adistance
                                )
                            );

                    var deviation = new DeviationPath(
                        path,
                        iedge,
                        deviationEdge,
                        deviationWeight
                        );
                    queue.Enqueue(deviation);
                }
            }
        }
예제 #2
0
        public bool RemoveEdge(TEdge edge)
        {
            bool removed = this._adjacentEdges[edge.Source].Remove(edge);

            if (removed)
            {
                if (!EdgeExtensions.IsSelfEdge <TVertex, TEdge>(edge))
                {
                    this._adjacentEdges[edge.Target].Remove(edge);
                }
                this.EdgeCount--;
                Contract.Assert(this.EdgeCount >= 0);
                this.OnEdgeRemoved(edge);
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #3
0
        public bool AddVerticesAndEdge(TEdge edge)
        {
            var sourceEdges = this.AddAndReturnEdges(edge.Source);
            var targetEdges = this.AddAndReturnEdges(edge.Target);

            if (!this.AllowParallelEdges)
            {
                if (this.ContainsEdgeBetweenVertices(sourceEdges, edge))
                {
                    return(false);
                }
            }

            sourceEdges.Add(edge);
            if (!EdgeExtensions.IsSelfEdge <TVertex, TEdge>(edge))
            {
                targetEdges.Add(edge);
            }
            this.EdgeCount++;
            this.OnEdgeAdded(edge);

            return(true);
        }
예제 #4
0
        public bool AddEdge(TEdge edge)
        {
            var sourceEdges = _adjacentEdges[edge.Source];

            if (!AllowParallelEdges)
            {
                if (ContainsEdgeBetweenVertices(sourceEdges, edge))
                {
                    return(false);
                }
            }

            sourceEdges.Add(edge);
            if (!EdgeExtensions.IsSelfEdge <TVertex, TEdge>(edge))
            {
                var targetEdges = _adjacentEdges[edge.Target];
                targetEdges.Add(edge);
            }
            EdgeCount++;
            OnEdgeAdded(edge);

            return(true);
        }
        protected override void InternalCompute()
        {
            TVertex root;

            if (!this.TryGetRootVertex(out root))
            {
                throw new InvalidOperationException("root vertex not set");
            }
            TVertex goal;

            if (!this.TryGetGoalVertex(out goal))
            {
                throw new InvalidOperationException("goal vertex not set");
            }

            // little shortcut
            if (root.Equals(goal))
            {
                this.OnGoalReached();
                return; // found it
            }

            var cancelManager = this.Services.CancelManager;
            var open          = new BinaryHeap <double, TVertex>(this.distanceRelaxer.Compare);
            var operators     = new Dictionary <TEdge, GraphColor>();
            var g             = this.VisitedGraph;

            // (1) Place the initial node on Open, with all its operators marked unused.
            open.Add(0, root);
            foreach (var edge in g.OutEdges(root))
            {
                operators.Add(edge, GraphColor.White);
            }

            while (open.Count > 0)
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                // (3) Else, choose an Open node n of lowest cost for expansion
                var entry = open.RemoveMinimum();
                var cost  = entry.Key;
                var n     = entry.Value;

                // (4) if node n is a goal node, terminate with success
                if (n.Equals(goal))
                {
                    this.OnGoalReached();
                    return;
                }

                // (5) else, expand node n,
                // genarting all successors n' reachable via unused legal operators
                // compute their cost and delete node n
                foreach (var edge in g.OutEdges(n))
                {
                    if (EdgeExtensions.IsSelfEdge <TVertex, TEdge>(edge))
                    {
                        continue; // skip self-edges
                    }
                    GraphColor edgeColor;
                    bool       hasColor = operators.TryGetValue(edge, out edgeColor);
                    if (!hasColor || edgeColor == GraphColor.White)
                    {
                        var weight = this.edgeWeights(edge);
                        var ncost  = this.distanceRelaxer.Combine(cost, weight);

                        // (7) foreach neighboring node of n' mark the operator from n to n' as used
                        // (8) for each node n', if there is no copy of n' in open addit
                        // else save on open on the copy of n' with lowest cose. Mark as used all operators
                        // mak as used in any of the copies
                        operators[edge] = GraphColor.Gray;
                        if (open.MinimumUpdate(ncost, edge.Target))
                        {
                            this.OnTreeEdge(edge);
                        }
                    }
                    else if (hasColor)
                    {
                        Contract.Assume(edgeColor == GraphColor.Gray);
                        // edge already seen, remove it
                        operators.Remove(edge);
                    }
                }

#if DEBUG
                this.operatorMaxCount = Math.Max(this.operatorMaxCount, operators.Count);
#endif

                // (6) in a directed graph, generate each predecessor node n via an unused operator
                // and create dummy nodes for each with costs of infinity
                foreach (var edge in g.InEdges(n))
                {
                    GraphColor edgeColor;
                    if (operators.TryGetValue(edge, out edgeColor) &&
                        edgeColor == GraphColor.Gray)
                    {
                        // delete node n
                        operators.Remove(edge);
                    }
                }
            }
        }