예제 #1
0
        /// <summary>
        /// Wyznacza ścieżkę powiekszającą o maksymalnej przepustowości spośród najkrótszych ścieżek
        /// </summary>
        /// <param name="g">Graf rezydualny</param>
        /// <param name="s">Wierzchołek źródłowy</param>
        /// <param name="t">Wierzchołek docelowy</param>
        /// <returns>
        /// Krotka (augmentingValue, augmentingFlow) składająca się z przepustowości wyznaczonej ścieżki
        /// i grafu opisującego tą ścieżkę
        /// </returns>
        /// <remarks>
        /// Jeśli ścieżka powiększająca nie istnieje, to zwracana jest krotka (0.0,null).<para/>
        /// Jeśli graf g jest typu <see cref="AdjacencyMatrixGraph"/> to wyznaczona ścieżka powiększająca p jest typu
        /// <see cref="AdjacencyListsGraph{HashTableAdjacencyList}"/>,
        /// w przeciwnym przypadku ścieżka p jest takiego samego typu jak graf g.
        /// </remarks>
        /// <seealso cref="MaxFlowGraphExtender"/>
        /// <seealso cref="ASD.Graphs"/>
        public static (double augmentingValue, Graph augmentingFlow) BFMaxPath(this Graph g, int s, int t)
        {
            var pi    = new PathsInfo[g.VerticesCount];
            var steps = new int[g.VerticesCount];

            steps[s]   = 1;
            pi[s].Dist = double.PositiveInfinity;

            bool VisitEdge(Edge e)
            {
                if (steps[e.From] == steps[t])
                {
                    return(false);
                }
                if (steps[e.To] == 0)
                {
                    steps[e.To] = steps[e.From] + 1;
                }
                else if (steps[e.To] != steps[e.From] + 1)
                {
                    return(true);
                }
                var d = Math.Min(pi[e.From].Dist, e.Weight);

                if (!(pi[e.To].Dist < d))
                {
                    return(true);
                }
                pi[e.To].Dist = d;
                pi[e.To].Last = e;
                return(true);
            }

            g.GeneralSearchFrom <EdgesQueue>(s, null, null, VisitEdge);
            return(pi[t].Dist, g.BuildGraph(s, t, pi));
        }