示例#1
0
        /// <summary>
        /// Algorytm znajdujący drugą pod względem długości najkrótszą ścieżkę między a i b.
        /// Możliwe, że jej długość jest równa najkrótszej (jeśli są dwie najkrótsze ścieżki,
        /// algorytm zwróci jedną z nich).
        /// Wymagamy, aby na ścieżce nie było powtórzeń wierzchołków ani krawędzi.
        /// Można założyć, że a!=b oraz że w grafie nie występują pętle.
        /// </summary>
        /// <remarks>
        /// Wymagana złożoność to O(nD), gdzie D jest złożonością implementacji algorytmu Dijkstry w bibliotece Graph.
        /// </remarks>
        /// <param name="g"></param>
        /// <param name="path">null jeśli druga ścieżka nie istnieje, wpp ściezka jako ciąg krawędzi</param>
        /// <returns>null jeśli druga ścieżka nie istnieje, wpp długość tej ścieżki</returns>
        public static double?FindSecondSimpleShortestPath(this Graph g, int a, int b, out Edge[] path)
        {
            path = null;
            PathsInfo[] d, best = null;
            double      min     = Double.MaxValue;

            g.DijkstraShortestPaths(a, out d);
            if (d[b].Dist.IsNaN())
            {
                return(null);
            }
            Edge[] firstpath = PathsInfo.ConstructPath(a, b, d);

            foreach (Edge e in firstpath)
            {
                g.DelEdge(e);
                g.DijkstraShortestPaths(a, out d);
                if (d[b].Dist < min)
                {
                    min  = d[b].Dist;
                    best = d;
                }
                g.AddEdge(e);
            }

            if (min == Double.MaxValue)
            {
                return(null);
            }

            path = PathsInfo.ConstructPath(a, b, best);

            return(min);
        }
示例#2
0
        /// <summary>
        /// Algorytm znajdujący drugą pod względem długości najkrótszą ścieżkę między a i b.
        /// Możliwe, że jej długość jest równa najkrótszej (jeśli są dwie najkrótsze ścieżki,
        /// algorytm zwróci jedną z nich).
        /// Wymagamy, aby na ścieżce nie było powtórzeń wierzchołków ani krawędzi.
        /// Można założyć, że a!=b oraz że w grafie nie występują pętle.
        /// </summary>
        /// <remarks>
        /// Wymagana złożoność to O(nD), gdzie D jest złożonością implementacji algorytmu Dijkstry w bibliotece Graph.
        /// </remarks>
        /// <param name="g"></param>
        /// <param name="path">null jeśli druga ścieżka nie istnieje, wpp ściezka jako ciąg krawędzi</param>
        /// <returns>null jeśli druga ścieżka nie istnieje, wpp długość tej ścieżki</returns>
        public static double?FindSecondSimpleShortestPath(this Graph g, int a, int b, out Edge[] path)
        {
            path = null;
            PathsInfo[] bestPathInfo, tempPathInfo, secondBestPathInfo = null;
            double      secondBest = double.PositiveInfinity;
            EdgesStack  stack      = new EdgesStack();

            if (!g.DijkstraShortestPaths(a, out bestPathInfo))
            {
                return(null);
            }
            int v         = b;
            int pathCount = 0;

            while (bestPathInfo[v].Last != null)
            {
                stack.Put((Edge)bestPathInfo[v].Last);
                v = stack.Peek().From;
                pathCount++;
            }
            Edge deleted;

            while (!stack.Empty)
            {
                deleted = stack.Get();
                g.DelEdge(deleted);
                g.DijkstraShortestPaths(a, out tempPathInfo);
                if (tempPathInfo[b].Dist < secondBest)
                {
                    secondBestPathInfo = tempPathInfo;
                    secondBest         = tempPathInfo[b].Dist;
                }
                g.AddEdge(deleted);
            }
            List <Edge> pathList = new List <Edge>();

            v = b;
            if (!double.IsPositiveInfinity(secondBest))
            {
                while (secondBestPathInfo[v].Last != null)
                {
                    pathList.Add((Edge)secondBestPathInfo[v].Last);
                    v = pathList.Last().From;
                }
                pathList.Reverse();
                path = pathList.ToArray();
            }
            if (path == null)
            {
                return(null);
            }
            else
            {
                return(pathList.Sum(edge => edge.Weight));
            }
        }
示例#3
0
        /// <summary>
        /// Algorytm znajdujący drugą pod względem długości najkrótszą ścieżkę między a i b.
        /// Możliwe, że jej długość jest równa najkrótszej (jeśli są dwie najkrótsze ścieżki,
        /// algorytm zwróci jedną z nich).
        /// Wymagamy, aby na ścieżce nie było powtórzeń wierzchołków ani krawędzi.
        /// Można założyć, że a!=b oraz że w grafie nie występują pętle.
        /// </summary>
        /// <remarks>
        /// Wymagana złożoność to O(nD), gdzie D jest złożonością implementacji algorytmu Dijkstry w bibliotece Graph.
        /// </remarks>
        /// <param name="g"></param>
        /// <param name="path">null jeśli druga ścieżka nie istnieje, wpp ściezka jako ciąg krawędzi</param>
        /// <returns>null jeśli druga ścieżka nie istnieje, wpp długość tej ścieżki</returns>
        public static double?FindSecondSimpleShortestPath(this Graph g, int a, int b, out Edge[] path)
        {
            PathsInfo[] pi;
            PathsInfo[] pi2;
            Graph       G = g.Clone();

            G.DijkstraShortestPaths(a, out pi);

            if (double.IsNaN(pi[b].Dist))
            {
                path = null;
                return(null);
            }

            Edge[] firstPath = PathsInfo.ConstructPath(a, b, pi);

            double secondShortest = double.PositiveInfinity;

            path = null;

            for (int i = firstPath.Length - 1; i >= 0; i--)
            {
                G.DelEdge(firstPath[i]);

                G.DijkstraShortestPaths(a, out pi2);
                if (double.IsNaN(pi2[b].Dist))
                {
                    continue;
                }

                if (pi2[b].Dist < secondShortest)
                {
                    secondShortest = pi2[b].Dist;
                    path           = PathsInfo.ConstructPath(a, b, pi2);
                }

                G.AddEdge(firstPath[i]);
            }

            if (secondShortest == double.PositiveInfinity)
            {
                return(null);
            }

            return(secondShortest);
        }
        /// <summary>
        /// Algorytm znajdujący drugą pod względem długości najkrótszą ścieżkę między a i b.
        /// Możliwe, że jej długość jest równa najkrótszej (jeśli są dwie najkrótsze ścieżki,
        /// algorytm zwróci jedną z nich).
        /// Wymagamy, aby na ścieżce nie było powtórzeń wierzchołków ani krawędzi.
        /// Można założyć, że a!=b oraz że w grafie nie występują pętle.
        /// </summary>
        /// <remarks>
        /// Wymagana złożoność to O(nD), gdzie D jest złożonością implementacji algorytmu Dijkstry w bibliotece Graph.
        /// </remarks>
        /// <param name="g"></param>
        /// <param name="path">null jeśli druga ścieżka nie istnieje, wpp ściezka jako ciąg krawędzi</param>
        /// <returns>null jeśli druga ścieżka nie istnieje, wpp długość tej ścieżki</returns>
        public static double?FindSecondSimpleShortestPath(this Graph g, int a, int b, out Edge[] path)
        {
            PathsInfo[] d;
            g.DijkstraShortestPaths(a, out d);
            Edge[] shortestPath = PathsInfo.ConstructPath(a, b, d);
            if (shortestPath == null)
            {
                path = null;
                return(null);
            }
            double minDist = double.MaxValue;
            bool   changed = false;

            Edge[] temp = null;
            foreach (Edge e in shortestPath)
            {
                PathsInfo[] dT;
                Graph       tG = g.Clone();
                tG.DelEdge(e);
                tG.DijkstraShortestPaths(a, out dT);
                Edge[] secondShortest = PathsInfo.ConstructPath(a, b, dT);
                if (dT[b].Dist <= minDist)
                {
                    changed = true;
                    minDist = dT[b].Dist;
                    temp    = PathsInfo.ConstructPath(a, b, dT);
                }
            }
            if (!changed)
            {
                path = null;
                return(null);
            }
            path = temp;
            return(minDist);
        }