private void FillJData(
            [NotNull, ItemNotNull] IEnumerable <TVertex> vertices,
            [NotNull] TVertex vi,
            [NotNull] TVertex vk,
            VertexData pathIk)
        {
            foreach (TVertex vj in vertices)
            {
                var kj = new SEquatableEdge <TVertex>(vk, vj);
                if (_data.TryGetValue(kj, out VertexData pathKj))
                {
                    double combined = _distanceRelaxer.Combine(
                        pathIk.Distance,
                        pathKj.Distance);

                    var ij = new SEquatableEdge <TVertex>(vi, vj);
                    if (_data.TryGetValue(ij, out VertexData pathIj))
                    {
                        if (_distanceRelaxer.Compare(combined, pathIj.Distance) < 0)
                        {
                            _data[ij] = new VertexData(combined, vk);
                        }
                    }
                    else
                    {
                        _data[ij] = new VertexData(combined, vk);
                    }
                }
            }
        }
Example #2
0
        /// <summary>
        /// Runs the relaxation algorithm on the given <paramref name="edge"/>.
        /// </summary>
        /// <param name="edge">Edge to relax.</param>
        /// <param name="source">Source vertex.</param>
        /// <param name="target">Target vertex.</param>
        /// <returns>True if relaxation decreased the target vertex distance, false otherwise.</returns>
        protected bool Relax(TEdge edge, TVertex source, TVertex target)
        {
            Debug.Assert(edge != null);
            Debug.Assert(source != null);
            Debug.Assert(target != null);
            Debug.Assert(
                (EqualityComparer <TVertex> .Default.Equals(edge.Source, source) &&
                 EqualityComparer <TVertex> .Default.Equals(edge.Target, target))
                ||
                (EqualityComparer <TVertex> .Default.Equals(edge.Source, target) &&
                 EqualityComparer <TVertex> .Default.Equals(edge.Target, source)));

            double du = Distances[source];
            double dv = Distances[target];
            double we = Weights(edge);

            IDistanceRelaxer relaxer = DistanceRelaxer;
            double           duwe    = relaxer.Combine(du, we);

            if (relaxer.Compare(duwe, dv) < 0)
            {
                Distances[target] = duwe;
                return(true);
            }

            return(false);
        }
Example #3
0
        /// <summary>
        /// Applies the Bellman Ford algorithm.
        /// </summary>
        /// <remarks>
        /// Does not initialize the predecessor and distance map.
        /// </remarks>
        protected override void InternalCompute()
        {
            // Getting the number of vertices
            int nbVertices = VisitedGraph.VertexCount;

            for (int k = 0; k < nbVertices; ++k)
            {
                bool atLeastOneTreeEdge = false;
                foreach (TEdge edge in VisitedGraph.Edges)
                {
                    OnExamineEdge(edge);

                    if (Relax(edge))
                    {
                        atLeastOneTreeEdge = true;
                        OnTreeEdge(edge);
                    }
                    else
                    {
                        OnEdgeNotRelaxed(edge);
                    }
                }

                if (!atLeastOneTreeEdge)
                {
                    break;
                }
            }

            IDistanceRelaxer relaxer = DistanceRelaxer;

            foreach (TEdge edge in VisitedGraph.Edges)
            {
                var edgeWeight = Weights(edge);
                if (edgeWeight < 0)
                {
                    throw new InvalidOperationException("Non negative edge weight.");
                }

                if (relaxer.Compare(
                        relaxer.Combine(Distances[edge.Source], edgeWeight),
                        Distances[edge.Target]) < 0)
                {
                    OnEdgeMinimized(edge);
                    FoundNegativeCycle = true;
                    return;
                }

                OnEdgeNotMinimized(edge);
            }

            FoundNegativeCycle = false;
        }
        /// <summary>
        /// Applies the Bellman Ford algorithm.
        /// </summary>
        /// <remarks>
        /// Does not initialize the predecessor and distance map.
        /// </remarks>
        protected override void InternalCompute()
        {
            // Getting the number of vertices
            int nbVertices = VisitedGraph.VertexCount;

            for (int k = 0; k < nbVertices; ++k)
            {
                bool atLeastOneTreeEdge = false;
                foreach (TEdge edge in VisitedGraph.Edges)
                {
                    OnExamineEdge(edge);

                    if (Relax(edge))
                    {
                        atLeastOneTreeEdge = true;
                        OnTreeEdge(edge);
                    }
                    else
                    {
                        OnEdgeNotRelaxed(edge);
                    }
                }

                if (!atLeastOneTreeEdge)
                {
                    break;
                }
            }

            IDistanceRelaxer relaxer = DistanceRelaxer;

            foreach (TEdge edge in VisitedGraph.Edges)
            {
                double edgeWeight = Weights(edge);
                if (relaxer.Compare(
                        relaxer.Combine(GetVertexDistance(edge.Source), edgeWeight),
                        GetVertexDistance(edge.Target)) < 0)
                {
                    OnEdgeMinimized(edge);
                    FoundNegativeCycle = true;
                    return;
                }

                OnEdgeNotMinimized(edge);
            }

            FoundNegativeCycle = false;
        }