/// <summary>
            /// If possible, relax the given edge using the supplied base cost and edge-weight function.
            /// </summary>
            /// <param name="edge">The edge to relax.</param>
            /// <param name="cost">The base cost to reach the edge destination vertex.</param>
            /// <param name="ew">The edge weigher.</param>
            /// <param name="forbidNegatives">If true, negative values will forbid the link.</param>
            /// <returns>True if the edge was relaxed, otherwise false.</returns>
            public bool RelaxEdge(E edge, IWeight cost, IEdgeWeigher <V, E> ew, bool forbidNegatives = true)
            {
                V       v       = edge.Dst;
                IWeight hopCost = ew.GetWeight(edge);

                if ((!hopCost.IsViable) || (hopCost.IsNegative && forbidNegatives))
                {
                    return(false);
                }

                IWeight newCost = cost.Merge(hopCost);

                int compareResult = -1;

                if (HasCost(v))
                {
                    IWeight oldCost = GetCost(v);
                    compareResult = newCost.CompareTo(oldCost);
                }

                if (compareResult <= 0)
                {
                    UpdateVertex(v, edge, newCost, compareResult < 0);
                }

                return(compareResult < 0);
            }
Esempio n. 2
0
 public IWeight GetWeight(E edge)
 {
     if (subsetF[riskGrouping[edge]])
     {
         return(weigher.GetWeight(edge));
     }
     return(weigher.NonViableWeight);
 }
            /// <summary>
            /// Sums the given edges using the given weigher.
            /// </summary>
            /// <param name="weigher">The weigher to use.</param>
            /// <param name="edges">The edges to sum.</param>
            /// <returns>The sum of path cost between the given edges.</returns>
            private IWeight CalculatePathCost(IEdgeWeigher <V, E> weigher, IEnumerable <E> edges)
            {
                IWeight totalCost = weigher.InitialWeight;

                foreach (E edge in edges)
                {
                    totalCost = totalCost.Merge(weigher.GetWeight(edge));
                }
                return(totalCost);
            }
Esempio n. 4
0
        /// <summary>
        /// Scans the specified graph, using recursion, and produces SCC results.
        /// </summary>
        /// <param name="graph">The graph to search.</param>
        /// <param name="vertex">The current vertex to scan and connect.</param>
        /// <param name="weigher">The optional weigher to use.</param>
        /// <param name="result">The graph search result.</param>
        /// <returns>Augmentation vertex data for the current vertex.</returns>
        private VertexData Connect(IGraph <V, E> graph, V vertex, IEdgeWeigher <V, E> weigher, SccResult result)
        {
            VertexData data = result.AddData(vertex);

            // Scan through all egress edges of the current vertex.
            foreach (E edge in graph.GetEdgesFrom(vertex))
            {
                V nextVertex = edge.Dst;

                // If edge is not viable, skip it.
                if (weigher != null && !weigher.GetWeight(edge).IsViable)
                {
                    continue;
                }

                // Attempt to get the augmentation vertex data for the next vertex.
                VertexData nextData = result.GetData(nextVertex);
                if (nextData is null)
                {
                    // Next vertex has not been visited yet, so do this now.
                    nextData     = Connect(graph, nextVertex, weigher, result);
                    data.LowLink = Math.Min(data.LowLink, nextData.LowLink);
                }
                else if (result.Visited(nextData))
                {
                    // Next vertex has been visited, which means
                    // it is in the same cluster as the current vertex.
                    data.LowLink = Math.Min(data.LowLink, nextData.Index);
                }
            }

            if (data.LowLink == data.Index)
            {
                result.AddCluster(data);
            }
            return(data);
        }