Esempio n. 1
0
        /// <summary>
        /// Get shortest distance to target
        /// </summary>
        /// <param name="graph"></param>
        /// <param name="source"></param>
        /// <param name="destination"></param>
        /// <returns></returns>
        public ShortestPathResult <T, W> GetShortestPath(WeightedDiGraph <T, W> graph, T source, T destination)
        {
            //regular argument checks
            if (graph == null || graph.FindVertex(source) == null ||
                graph.FindVertex(destination) == null)
            {
                throw new ArgumentException();
            }

            var progress  = new Dictionary <T, W>();
            var parentMap = new Dictionary <T, T>();

            foreach (var vertex in graph.Vertices)
            {
                parentMap.Add(vertex.Key, default(T));
                progress.Add(vertex.Key, operators.MaxValue);
            }

            progress[source] = operators.DefaultValue;

            var iterations = graph.Vertices.Count - 1;
            var updated    = true;

            while (iterations > 0 && updated)
            {
                updated = false;

                foreach (var vertex in graph.Vertices)
                {
                    //skip not discovered nodes
                    if (progress[vertex.Key].Equals(operators.MaxValue))
                    {
                        continue;
                    }

                    foreach (var edge in vertex.Value.OutEdges)
                    {
                        var currentDistance = progress[edge.Key.Value];
                        var newDistance     = operators.Sum(progress[vertex.Key],
                                                            vertex.Value.OutEdges[edge.Key]);

                        if (newDistance.CompareTo(currentDistance) < 0)
                        {
                            updated = true;
                            progress[edge.Key.Value]  = newDistance;
                            parentMap[edge.Key.Value] = vertex.Key;
                        }
                    }
                }

                iterations--;

                if (iterations < 0)
                {
                    throw new Exception("Negative cycle exists in this graph.");
                }
            }

            return(tracePath(graph, parentMap, source, destination));
        }
        private W findMinWeight(IGraphVertex <T> sourceVertex,
                                IGraphVertex <T> tgtVertex,
                                int remainingVertexCount,
                                HashSet <IGraphVertex <T> > visited,
                                Dictionary <string, W> cache)
        {
            var cacheKey = $"{sourceVertex.Key}-{remainingVertexCount}";

            if (cache.ContainsKey(cacheKey))
            {
                return(cache[cacheKey]);
            }

            visited.Add(sourceVertex);

            var results = new List <W>();

            foreach (var edge in sourceVertex.Edges)
            {
                //base case
                if (edge.TargetVertex.Equals(tgtVertex) &&
                    remainingVertexCount == 1)
                {
                    results.Add(edge.Weight <W>());
                    break;
                }

                if (!visited.Contains(edge.TargetVertex))
                {
                    var result = findMinWeight(edge.TargetVertex, tgtVertex, remainingVertexCount - 1, visited, cache);

                    if (!result.Equals(@operator.MaxValue))
                    {
                        results.Add(@operator.Sum(result, edge.Weight <W>()));
                    }
                }
            }

            visited.Remove(sourceVertex);

            if (results.Count == 0)
            {
                return(@operator.MaxValue);
            }

            var min = results.Min();

            cache.Add(cacheKey, min);
            return(min);
        }
Esempio n. 3
0
        public List <AllPairShortestPathResult <T, W> > GetAllPairShortestPaths(WeightedGraph <T, W> graph)
        {
            //we need this vertex array index for generics
            //since array indices are int and T is unknown type
            var vertexIndex        = new Dictionary <int, T>();
            var reverseVertexIndex = new Dictionary <T, int>();
            var i = 0;

            foreach (var vertex in graph.Vertices)
            {
                vertexIndex.Add(i, vertex.Key);
                reverseVertexIndex.Add(vertex.Key, i);
                i++;
            }

            //init all distance to default Weight
            var result = new W[graph.Vertices.Count, graph.Vertices.Count];
            //to trace the path
            var parent = new T[graph.Vertices.Count, graph.Vertices.Count];

            for (i = 0; i < graph.VerticesCount; i++)
            {
                for (int j = 0; j < graph.VerticesCount; j++)
                {
                    result[i, j] = operators.MaxValue;
                }
            }

            for (i = 0; i < graph.VerticesCount; i++)
            {
                result[i, i] = operators.DefaultValue;
            }
            //now set the known edge weights to neighbours
            for (i = 0; i < graph.VerticesCount; i++)
            {
                foreach (var edge in graph.Vertices[vertexIndex[i]].Edges)
                {
                    result[i, reverseVertexIndex[edge.Key.Value]] = edge.Value;
                    parent[i, reverseVertexIndex[edge.Key.Value]] = graph.Vertices[vertexIndex[i]].Value;

                    result[reverseVertexIndex[edge.Key.Value], i] = edge.Value;
                    parent[reverseVertexIndex[edge.Key.Value], i] = edge.Key.Value;
                }
            }

            //here is the meat of this algorithm
            //if we can reach node i to j via node k and if it is shorter pick that Distance
            for (int k = 0; k < graph.VerticesCount; k++)
            {
                for (i = 0; i < graph.VerticesCount; i++)
                {
                    for (int j = 0; j < graph.VerticesCount; j++)
                    {
                        //no path
                        if (result[i, k].Equals(operators.MaxValue) ||
                            result[k, j].Equals(operators.MaxValue))
                        {
                            continue;
                        }

                        var sum = operators.Sum(result[i, k], result[k, j]);

                        if (sum.CompareTo(result[i, j]) >= 0)
                        {
                            continue;
                        }

                        result[i, j] = sum;
                        parent[i, j] = parent[k, j];
                    }
                }
            }

            //trace path
            var finalResult = new List <AllPairShortestPathResult <T, W> >();

            for (i = 0; i < graph.VerticesCount; i++)
            {
                for (int j = 0; j < graph.VerticesCount; j++)
                {
                    var source   = vertexIndex[i];
                    var dest     = vertexIndex[j];
                    var distance = result[i, j];
                    var path     = tracePath(result, parent, i, j, vertexIndex, reverseVertexIndex);

                    finalResult.Add(new AllPairShortestPathResult <T, W>(source, dest, distance, path));
                }
            }

            return(finalResult);
        }
        /// <summary>
        /// Get shortest distance to target.
        /// </summary>
        public ShortestPathResult <T, W> FindShortestPath(IGraph <T> graph, T source, T destination)
        {
            //regular argument checks
            if (graph?.GetVertex(source) == null || graph.GetVertex(destination) == null)
            {
                throw new ArgumentException();
            }

            if (this.@operator == null)
            {
                throw new ArgumentException("Provide an operator implementation for generic type W during initialization.");
            }

            if (!graph.IsWeightedGraph)
            {
                if ([email protected]() != typeof(int))
                {
                    throw new ArgumentException("Edges of unweighted graphs are assigned an imaginary weight of one (1)." +
                                                "Provide an appropriate IShortestPathOperators<int> operator implementation during initialization.");
                }
            }

            //track progress for distance to each Vertex from source
            var progress = new Dictionary <T, W>();

            //trace our current path by mapping current vertex to its Parent
            var parentMap = new Dictionary <T, T>();

            //min heap to pick next closest vertex
            var minHeap = new FibonacciHeap <MinHeapWrap <T, W> >();
            //keep references of heap Node for decrement key operation
            var heapMapping = new Dictionary <T, MinHeapWrap <T, W> >();

            //add vertices to min heap and progress map
            foreach (var vertex in graph.VerticesAsEnumberable)
            {
                //init parent
                parentMap.Add(vertex.Key, default(T));

                //init to max value
                progress.Add(vertex.Key, @operator.MaxValue);

                if (vertex.Key.Equals(source))
                {
                    continue;
                }
            }

            //start from source vertex as current
            var current = new MinHeapWrap <T, W>()
            {
                Distance = @operator.DefaultValue,
                Vertex   = source
            };

            minHeap.Insert(current);
            heapMapping.Add(current.Vertex, current);

            //until heap is empty
            while (minHeap.Count > 0)
            {
                //next min vertex to visit
                current = minHeap.Extract();
                heapMapping.Remove(current.Vertex);

                //no path exists, so return max value
                if (current.Distance.Equals(@operator.MaxValue))
                {
                    return(new ShortestPathResult <T, W>(null, @operator.MaxValue));
                }

                //visit neighbours of current
                foreach (var neighbour in graph.GetVertex(current.Vertex).Edges.Where(x => !x.TargetVertexKey.Equals(source)))
                {
                    //new distance to neighbour
                    var newDistance = @operator.Sum(current.Distance,
                                                    graph.GetVertex(current.Vertex).GetEdge(neighbour.TargetVertex).Weight <W>());

                    //current distance to neighbour
                    var existingDistance = progress[neighbour.TargetVertexKey];

                    //update distance if new is better
                    if (newDistance.CompareTo(existingDistance) < 0)
                    {
                        progress[neighbour.TargetVertexKey] = newDistance;

                        if (!heapMapping.ContainsKey(neighbour.TargetVertexKey))
                        {
                            var wrap = new MinHeapWrap <T, W>()
                            {
                                Distance = newDistance, Vertex = neighbour.TargetVertexKey
                            };
                            minHeap.Insert(wrap);
                            heapMapping.Add(neighbour.TargetVertexKey, wrap);
                        }
                        else
                        {
                            //decrement distance to neighbour in heap
                            var decremented = new MinHeapWrap <T, W>()
                            {
                                Distance = newDistance, Vertex = neighbour.TargetVertexKey
                            };
                            minHeap.UpdateKey(heapMapping[neighbour.TargetVertexKey], decremented);
                            heapMapping[neighbour.TargetVertexKey] = decremented;
                        }

                        //trace parent
                        parentMap[neighbour.TargetVertexKey] = current.Vertex;
                    }
                }
            }

            return(tracePath(graph, parentMap, source, destination));
        }
Esempio n. 5
0
        /// <summary>
        /// Search path to target using the heuristic.
        /// </summary>
        public ShortestPathResult <T, W> FindShortestPath(WeightedDiGraph <T, W> graph, T source, T destination)
        {
            //regular argument checks
            if (graph?.FindVertex(source) == null || graph.FindVertex(destination) == null)
            {
                throw new ArgumentException();
            }

            //track progress for distance to each Vertex from source
            var progress = new Dictionary <T, W>();

            //trace our current path by mapping current vertex to its Parent
            var parentMap = new Dictionary <T, T>();

            //min heap to pick next closest vertex
            var minHeap = new FibonacciHeap <AStarWrap <T, W> >();
            //keep references of heap Node for decrement key operation
            var heapMapping = new Dictionary <T, AStarWrap <T, W> >();

            //add vertices to min heap and progress map
            foreach (var vertex in graph.Vertices)
            {
                //init parent
                parentMap.Add(vertex.Key, default(T));

                //init to max value
                progress.Add(vertex.Key, operators.MaxValue);

                if (vertex.Key.Equals(source))
                {
                    continue;
                }
            }

            //start from source vertex as current
            var current = new AStarWrap <T, W>(heuristic, destination)
            {
                Distance = operators.DefaultValue,
                Vertex   = source
            };

            //insert neighbour in heap
            minHeap.Insert(current);
            heapMapping[source] = current;

            //until heap is empty
            while (minHeap.Count > 0)
            {
                //next min vertex to visit
                current = minHeap.Extract();
                heapMapping.Remove(current.Vertex);

                //no path exists, so return max value
                if (current.Distance.Equals(operators.MaxValue))
                {
                    return(new ShortestPathResult <T, W>(null, operators.MaxValue));
                }

                //visit neighbours of current
                foreach (var neighbour in graph.Vertices[current.Vertex].OutEdges.Where(x => !x.Key.Value.Equals(source)))
                {
                    //new distance to neighbour
                    var newDistance = operators.Sum(current.Distance,
                                                    graph.Vertices[current.Vertex].OutEdges[neighbour.Key]);

                    //current distance to neighbour
                    var existingDistance = progress[neighbour.Key.Value];

                    //update distance if new is better
                    if (newDistance.CompareTo(existingDistance) < 0)
                    {
                        progress[neighbour.Key.Value] = newDistance;

                        if (heapMapping.ContainsKey(neighbour.Key.Value))
                        {
                            //decrement distance to neighbour in heap
                            var decremented = new AStarWrap <T, W>(heuristic, destination)
                            {
                                Distance = newDistance, Vertex = neighbour.Key.Value
                            };
                            minHeap.UpdateKey(heapMapping[neighbour.Key.Value], decremented);
                            heapMapping[neighbour.Key.Value] = decremented;
                        }
                        else
                        {
                            //insert neighbour in heap
                            var discovered = new AStarWrap <T, W>(heuristic, destination)
                            {
                                Distance = newDistance, Vertex = neighbour.Key.Value
                            };
                            minHeap.Insert(discovered);
                            heapMapping[neighbour.Key.Value] = discovered;
                        }

                        //trace parent
                        parentMap[neighbour.Key.Value] = current.Vertex;
                    }
                }
            }

            return(tracePath(graph, parentMap, source, destination));
        }
Esempio n. 6
0
        /// <summary>
        /// Get shortest distance to target
        /// </summary>
        /// <param name="graph"></param>
        /// <param name="source"></param>
        /// <param name="destination"></param>
        /// <returns></returns>
        public ShortestPathResult <T, W> GetShortestPath(WeightedDiGraph <T, W> graph, T source, T destination)
        {
            //regular argument checks
            if (graph == null || graph.FindVertex(source) == null ||
                graph.FindVertex(destination) == null)
            {
                throw new ArgumentException();
            }

            //track progress for distance to each Vertex from source
            var progress = new Dictionary <T, W>();

            //trace our current path by mapping current vertex to its Parent
            var parentMap = new Dictionary <T, T>();

            //min heap to pick next closest vertex
            var minHeap = new FibornacciMinHeap <MinHeapWrap <T, W> >();
            //keep references of heap Node for decrement key operation
            var heapMapping = new Dictionary <T, FibornacciHeapNode <MinHeapWrap <T, W> > >();

            //add vertices to min heap and progress map
            foreach (var vertex in graph.Vertices)
            {
                //init parent
                parentMap.Add(vertex.Key, default(T));

                //init to max value
                progress.Add(vertex.Key, operators.MaxValue);

                if (vertex.Key.Equals(source))
                {
                    continue;
                }

                //construct heap for all vertices with Max Distance as default
                var wrap = new MinHeapWrap <T, W>()
                {
                    Distance = operators.MaxValue,
                    Target   = vertex.Key
                };

                var heapNode = minHeap.Insert(wrap);
                heapMapping.Add(vertex.Key, heapNode);
            }

            //start from source vertex as current
            var sourceVertex = graph.Vertices[source];
            var current      = new MinHeapWrap <T, W>()
            {
                Distance = operators.DefaultValue,
                Target   = source
            };

            //until heap is empty
            while (minHeap.Count > 0)
            {
                //no path exists, so return max value
                if (current.Distance.Equals(operators.MaxValue))
                {
                    return(new ShortestPathResult <T, W>(null, operators.MaxValue));
                }

                //visit neighbours of current
                foreach (var neighbour in graph.Vertices[current.Target].OutEdges)
                {
                    //new distance to neighbour
                    var newDistance = operators.Sum(current.Distance,
                                                    graph.Vertices[current.Target].OutEdges[neighbour.Key]);

                    //current distance to neighbour
                    var existingDistance = progress[neighbour.Key.Value];

                    //update distance if new is better
                    if (newDistance.CompareTo(existingDistance) < 0)
                    {
                        progress[neighbour.Key.Value] = newDistance;
                        heapMapping[neighbour.Key.Value].Value.Distance = newDistance;

                        //decrement distance to neighbour in heap
                        minHeap.DecrementKey(heapMapping[neighbour.Key.Value]);

                        //trace parent
                        parentMap[neighbour.Key.Value] = current.Target;
                    }
                }

                //next min vertex to visit
                current = minHeap.ExtractMin();
            }

            return(tracePath(graph, parentMap, source, destination));
        }
        public List <AllPairShortestPathResult <T, W> > FindAllPairShortestPaths(IGraph <T> graph)
        {
            if (this.@operator == null)
            {
                throw new ArgumentException("Provide an operator implementation for generic type W during initialization.");
            }

            if (!graph.IsWeightedGraph)
            {
                if ([email protected]() != typeof(int))
                {
                    throw new ArgumentException("Edges of unweighted graphs are assigned an imaginary weight of one (1)." +
                                                "Provide an appropriate IShortestPathOperators<int> operator implementation during initialization.");
                }
            }

            //we need this vertex array index for generics
            //since array indices are int and T is unknown type
            var vertexIndex        = new Dictionary <int, T>();
            var reverseVertexIndex = new Dictionary <T, int>();
            var i = 0;

            foreach (var vertex in graph.VerticesAsEnumberable)
            {
                vertexIndex.Add(i, vertex.Key);
                reverseVertexIndex.Add(vertex.Key, i);
                i++;
            }

            //init all distance to default Weight
            var result = new W[graph.VerticesCount, graph.VerticesCount];
            //to trace the path
            var parent = new T[graph.VerticesCount, graph.VerticesCount];

            for (i = 0; i < graph.VerticesCount; i++)
            {
                for (int j = 0; j < graph.VerticesCount; j++)
                {
                    result[i, j] = @operator.MaxValue;
                }
            }

            for (i = 0; i < graph.VerticesCount; i++)
            {
                result[i, i] = @operator.DefaultValue;
            }
            //now set the known edge weights to neighbours
            for (i = 0; i < graph.VerticesCount; i++)
            {
                foreach (var edge in graph.GetVertex(vertexIndex[i]).Edges)
                {
                    result[i, reverseVertexIndex[edge.TargetVertexKey]] = edge.Weight <W>();
                    parent[i, reverseVertexIndex[edge.TargetVertexKey]] = graph.GetVertex(vertexIndex[i]).Key;

                    result[reverseVertexIndex[edge.TargetVertexKey], i] = edge.Weight <W>();
                    parent[reverseVertexIndex[edge.TargetVertexKey], i] = edge.TargetVertexKey;
                }
            }

            //here is the meat of this algorithm
            //if we can reach node i to j via node k and if it is shorter pick that Distance
            for (int k = 0; k < graph.VerticesCount; k++)
            {
                for (i = 0; i < graph.VerticesCount; i++)
                {
                    for (int j = 0; j < graph.VerticesCount; j++)
                    {
                        //no path
                        if (result[i, k].Equals(@operator.MaxValue) ||
                            result[k, j].Equals(@operator.MaxValue))
                        {
                            continue;
                        }

                        var sum = @operator.Sum(result[i, k], result[k, j]);

                        if (sum.CompareTo(result[i, j]) >= 0)
                        {
                            continue;
                        }

                        result[i, j] = sum;
                        parent[i, j] = parent[k, j];
                    }
                }
            }

            //trace path
            var finalResult = new List <AllPairShortestPathResult <T, W> >();

            for (i = 0; i < graph.VerticesCount; i++)
            {
                for (int j = 0; j < graph.VerticesCount; j++)
                {
                    var source   = vertexIndex[i];
                    var dest     = vertexIndex[j];
                    var distance = result[i, j];
                    var path     = tracePath(result, parent, i, j, vertexIndex, reverseVertexIndex);

                    finalResult.Add(new AllPairShortestPathResult <T, W>(source, dest, distance, path));
                }
            }

            return(finalResult);
        }
        /// <summary>
        /// Find shortest distance to target.
        /// </summary>
        public ShortestPathResult <T, W> FindShortestPath(IDiGraph <T> graph,
                                                          T source, T destination)
        {
            //regular argument checks
            if (graph == null || graph.GetVertex(source) == null ||
                graph.GetVertex(destination) == null)
            {
                throw new ArgumentException("Empty Graph or invalid source/destination.");
            }

            if (this.@operator == null)
            {
                throw new ArgumentException("Provide an operator implementation for generic type W during initialization.");
            }

            if (!graph.IsWeightedGraph)
            {
                if ([email protected]() != typeof(int))
                {
                    throw new ArgumentException("Edges of unweighted graphs are assigned an imaginary weight of one (1)." +
                                                "Provide an appropriate IShortestPathOperators<int> operator implementation during initialization.");
                }
            }

            var progress  = new Dictionary <T, W>();
            var parentMap = new Dictionary <T, T>();

            foreach (var vertex in graph.VerticesAsEnumberable)
            {
                parentMap.Add(vertex.Key, default(T));
                progress.Add(vertex.Key, @operator.MaxValue);
            }

            progress[source] = @operator.DefaultValue;

            var iterations = graph.VerticesCount - 1;
            var updated    = true;

            while (iterations > 0 && updated)
            {
                updated = false;

                foreach (var vertex in graph.VerticesAsEnumberable)
                {
                    //skip not discovered nodes
                    if (progress[vertex.Key].Equals(@operator.MaxValue))
                    {
                        continue;
                    }

                    foreach (var edge in vertex.OutEdges)
                    {
                        var currentDistance = progress[edge.TargetVertexKey];
                        var newDistance     = @operator.Sum(progress[vertex.Key],
                                                            vertex.GetOutEdge(edge.TargetVertex).Weight <W>());

                        if (newDistance.CompareTo(currentDistance) < 0)
                        {
                            updated = true;
                            progress[edge.TargetVertexKey]  = newDistance;
                            parentMap[edge.TargetVertexKey] = vertex.Key;
                        }
                    }
                }

                iterations--;

                if (iterations < 0)
                {
                    throw new Exception("Negative cycle exists in this graph.");
                }
            }

            return(tracePath(graph, parentMap, source, destination));
        }
Esempio n. 9
0
        public ShortestPathResult <T, W> GetShortestPath(WeightedDiGraph <T, W> graph, T source, T destination)
        {
            if (graph == null || graph.FindVertex(source) == null ||
                graph.FindVertex(destination) == null)
            {
                throw new ArgumentException();
            }

            var progress = new Dictionary <T, W>();

            var parentMap = new Dictionary <T, T>();

            var minHeap     = new FibornacciMinHeap <MinHeapWrap <T, W> >();
            var heapMapping = new Dictionary <T, FibornacciHeapNode <MinHeapWrap <T, W> > >();

            foreach (var vertex in graph.Vertices)
            {
                parentMap.Add(vertex.Key, default(T));

                progress.Add(vertex.Key, operators.MaxValue);

                if (vertex.Key.Equals(source))
                {
                    continue;
                }

                var wrap = new MinHeapWrap <T, W>()
                {
                    Distance = operators.MaxValue,
                    Target   = vertex.Key
                };

                var heapNode = minHeap.Insert(wrap);
                heapMapping.Add(vertex.Key, heapNode);
            }

            var sourceVertex = graph.Vertices[source];
            var current      = new MinHeapWrap <T, W>()
            {
                Distance = operators.DefaultValue,
                Target   = source
            };

            while (minHeap.Count > 0)
            {
                if (current.Distance.Equals(operators.MaxValue))
                {
                    return(new ShortestPathResult <T, W>(null, operators.MaxValue));
                }

                foreach (var neighbour in graph.Vertices[current.Target].OutEdges)
                {
                    var newDistance = operators.Sum(current.Distance,
                                                    graph.Vertices[current.Target].OutEdges[neighbour.Key]);

                    var existingDistance = progress[neighbour.Key.Value];

                    if (newDistance.CompareTo(existingDistance) < 0)
                    {
                        progress[neighbour.Key.Value] = newDistance;
                        heapMapping[neighbour.Key.Value].Value.Distance = newDistance;

                        minHeap.DecrementKey(heapMapping[neighbour.Key.Value]);

                        parentMap[neighbour.Key.Value] = current.Target;
                    }
                }

                current = minHeap.ExtractMin();
            }

            return(tracePath(graph, parentMap, source, destination));
        }
Esempio n. 10
0
        public List <AllPairShortestPathResult <T, W> > GetAllPairShortestPaths(WeightedGraph <T, W> graph)
        {
            var vertexIndex        = new Dictionary <int, T>();
            var reverseVertexIndex = new Dictionary <T, int>();
            int i = 0;

            foreach (var vertex in graph.Vertices)
            {
                vertexIndex.Add(i, vertex.Key);
                reverseVertexIndex.Add(vertex.Key, i);
                i++;
            }

            var result = new W[graph.Vertices.Count, graph.Vertices.Count];
            var parent = new T[graph.Vertices.Count, graph.Vertices.Count];

            for (i = 0; i < graph.VerticesCount; i++)
            {
                for (int j = 0; j < graph.VerticesCount; j++)
                {
                    result[i, j] = operators.MaxValue;
                }
            }

            for (i = 0; i < graph.VerticesCount; i++)
            {
                result[i, i] = operators.DefaultValue;
            }
            for (i = 0; i < graph.VerticesCount; i++)
            {
                foreach (var edge in graph.Vertices[vertexIndex[i]].Edges)
                {
                    result[i, reverseVertexIndex[edge.Key.Value]] = edge.Value;
                    parent[i, reverseVertexIndex[edge.Key.Value]] = graph.Vertices[vertexIndex[i]].Value;

                    result[reverseVertexIndex[edge.Key.Value], i] = edge.Value;
                    parent[reverseVertexIndex[edge.Key.Value], i] = edge.Key.Value;
                }
            }

            for (int k = 0; k < graph.VerticesCount; k++)
            {
                for (i = 0; i < graph.VerticesCount; i++)
                {
                    for (int j = 0; j < graph.VerticesCount; j++)
                    {
                        if (result[i, k].Equals(operators.MaxValue) ||
                            result[k, j].Equals(operators.MaxValue))
                        {
                            continue;
                        }

                        var sum = operators.Sum(result[i, k], result[k, j]);

                        if (sum.CompareTo(result[i, j]) < 0)
                        {
                            result[i, j] = sum;
                            parent[i, j] = parent[k, j];
                        }
                    }
                }
            }

            var finalResult = new List <AllPairShortestPathResult <T, W> >();

            for (i = 0; i < graph.VerticesCount; i++)
            {
                for (int j = 0; j < graph.VerticesCount; j++)
                {
                    var source   = vertexIndex[i];
                    var dest     = vertexIndex[j];
                    var distance = result[i, j];
                    var path     = tracePath(result, parent, i, j, vertexIndex, reverseVertexIndex);

                    finalResult.Add(new AllPairShortestPathResult <T, W>(source, dest, distance, path));
                }
            }

            return(finalResult);
        }