public static IEnumerable <IWeightedDirectedPath <TVertex, TEdge> > AllSimplePaths <TVertex, TEdge>(
            this IWeightedDirectedGraph <TVertex, TEdge> graph,
            TVertex origin,
            TVertex destination,
            int maxDepth = int.MaxValue
            )
        {
            if (graph == null)
            {
                throw new ArgumentNullException(nameof(graph));
            }
            if (origin == null)
            {
                throw new ArgumentNullException(nameof(origin));
            }
            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            if (!graph.Vertices.Contains(origin))
            {
                throw new ArgumentException();
            }
            if (!graph.Vertices.Contains(destination))
            {
                throw new ArgumentException();
            }

            return(graph.AllSimplePaths(origin, destination, Adder <TEdge> .Default, maxDepth));
        }
        DijkstraShortestPaths <TVertex, TEdge>(
            this IWeightedDirectedGraph <TVertex, TEdge> graph,
            TVertex origin,
            IComparer <TEdge> comparer
            )
        {
            if (graph == null)
            {
                throw new ArgumentNullException(nameof(graph));
            }
            if (origin == null)
            {
                throw new ArgumentNullException(nameof(origin));
            }
            if (comparer == null)
            {
                throw new ArgumentNullException(nameof(comparer));
            }

            if (!graph.Vertices.Contains(origin))
            {
                throw new ArgumentException();
            }

            return(graph.DijkstraShortestPaths(origin, Adder <TEdge> .Default, comparer));
        }
 public WeightedDirectedDirectedPathCollection(
     IWeightedDirectedGraph <TVertex, TEdge> graph,
     TVertex origin,
     IDictionary <TVertex, Tuple <TEdge, TEdge> > edges
     ) : this(graph, origin, edges, Adder <TEdge> .Default)
 {
 }
 public DijkstraShortestWeightedDirectedPathEnumerator(
     IWeightedDirectedGraph <TVertex, TEdge> graph,
     TVertex origin,
     IComparer <TEdge> comparer
     ) : this(graph, origin, Adder <TEdge> .Default, comparer)
 {
 }
 public WeightedDirectedPath(
     IWeightedDirectedGraph <TVertex, TEdge> graph,
     TVertex origin
     ) : this(graph, origin, origin, new List <TVertex> {
     origin
 }, new List <TEdge>(), default)
 {
 }
 public DijkstraShortestWeightedDirectedPathAlgorithm(
     IWeightedDirectedGraph <TVertex, TEdge> graph,
     IAdder <TEdge> adder,
     IComparer <TEdge> comparer
     )
 {
     Graph    = graph;
     Adder    = adder;
     Comparer = comparer;
 }
Exemplo n.º 7
0
 public PathGeneticAlgorithm(
     int noOfGenerations,
     int minPopulationSize,
     int maxPopulationSize,
     double mutationProbability,
     IWeightedDirectedGraph <TVertex, TEdge> graph,
     TVertex origin,
     TVertex destination
     ) : this(noOfGenerations, minPopulationSize, maxPopulationSize, mutationProbability, graph, origin, destination, Adder <TEdge> .Default, Comparer <TEdge> .Default)
 {
 }
 public WeightedDirectedDirectedPathCollection(
     IWeightedDirectedGraph <TVertex, TEdge> graph,
     TVertex origin,
     IDictionary <TVertex, Tuple <TEdge, TEdge> > edges,
     IAdder <TEdge> adder
     ) : base(graph, origin)
 {
     Graph = graph;
     Edges = edges;
     Adder = adder;
 }
 public WeightedDirectedPath(
     IWeightedDirectedGraph <TVertex, TEdge> graph,
     TVertex origin,
     TVertex destination,
     IEnumerable <TVertex> vertices,
     IEnumerable <TEdge> edges,
     TEdge weight
     ) : base(graph, origin, destination, vertices)
 {
     Graph  = graph;
     Edges  = edges;
     Weight = weight;
 }
        public DijkstraShortestWeightedDirectedPathEnumerator(
            IWeightedDirectedGraph <TVertex, TEdge> graph,
            TVertex origin,
            IAdder <TEdge> adder,
            IComparer <TEdge> comparer
            )
        {
            Graph    = graph;
            Origin   = origin;
            Adder    = adder;
            Comparer = comparer;
            Heap     = new FibonacciHeap <TEdge, HeapEntry>(comparer);
            Visited  = new Dictionary <TVertex, IMinHeapVertex <TEdge, HeapEntry> >();

            Initialize();
        }
Exemplo n.º 11
0
 public PathGeneticAlgorithm(
     int noOfGenerations,
     int minPopulationSize,
     int maxPopulationSize,
     double mutationProbability,
     IWeightedDirectedGraph <TVertex, TEdge> graph,
     TVertex origin,
     TVertex destination,
     IAdder <TEdge> adder,
     IComparer <TEdge> comparer
     ) : base(noOfGenerations, minPopulationSize, maxPopulationSize, mutationProbability)
 {
     Graph       = graph;
     Origin      = origin;
     Destination = destination;
     Adder       = adder;
     Comparer    = comparer;
 }
 public DijkstraShortestWeightedDirectedPathAlgorithm(
     IWeightedDirectedGraph <TVertex, TEdge> graph,
     IComparer <TEdge> comparer
     ) : this(graph, Adder <TEdge> .Default, comparer)
 {
 }
        DijkstraShortestPaths <TVertex, TEdge>(
            this IWeightedDirectedGraph <TVertex, TEdge> graph,
            TVertex origin,
            IAdder <TEdge> adder,
            IComparer <TEdge> comparer
            )
        {
            if (graph == null)
            {
                throw new ArgumentNullException(nameof(graph));
            }
            if (origin == null)
            {
                throw new ArgumentNullException(nameof(origin));
            }
            if (adder == null)
            {
                throw new ArgumentNullException(nameof(adder));
            }
            if (comparer == null)
            {
                throw new ArgumentNullException(nameof(comparer));
            }

            if (!graph.Vertices.Contains(origin))
            {
                throw new ArgumentException();
            }

            // Constructs a dictionary which stores the graphs which contain the shortest path from the origin to
            // each of the vertices that is reachable from the origin by iteratively traversing successor endpoints.
            var graphs = new Dictionary <TVertex, IWeightedDirectedGraph <TVertex, TEdge> >();

            // Constructs a dictionary which stores the additions which represent the added edges which in turn
            // represent the shortest path from the origin to each of the vertices when added.
            var accumulations = new Dictionary <TVertex, TEdge>();

            var settledVertices   = new HashSet <TVertex>();
            var unsettledVertices = new HashSet <TVertex> {
                origin
            };

            while (unsettledVertices.Count > 0)
            {
                // Returns the unsettled vertex that is nearest to the origin by finding the shortest of all the
                // accumulated edges which form a path from the origin to each of the unsettled vertices. Calling
                // the `MinBy` method with only one unsettled vertex in the set of unsettled vertices will return
                // that unsettled vertex, hence it will always return the origin during the first iteration over
                // the unsettled vertices set, because the unsettled vertices set will only contain the origin.
                var nearestVertex = unsettledVertices.MinBy(vertex => accumulations[vertex], comparer);

                // Removes the nearest vertex from the set of unvisited vertices.
                unsettledVertices.Remove(nearestVertex);

                // Iterates over each of the successor endpoints of the nearest vertex.
                foreach (var endpoint in graph.SuccessorEndpoints(nearestVertex))
                {
                    // If the vertex of the endpoint is already settled, then continue to the next iteration.
                    if (settledVertices.Contains(endpoint.Vertex))
                    {
                        continue;
                    }

                    // If the dictionary of additions contains an addition for the nearest vertex, then add this
                    // addition and the endpoint edge together in order to calculate a single path from the origin
                    // to the endpoint vertex of the current iteration; otherwise, an addition for the nearest vertex
                    // does not exist so return the endpoint edge without adding.
                    var currentPath = accumulations.ContainsKey(nearestVertex)
                        ? adder.Add(accumulations[nearestVertex], endpoint.Edge)
                        : endpoint.Edge;

                    // Returns true if the dictionary of additions contains the endpoint vertex and the current path
                    // is less than the existing shortest path from the origin to the endpoint vertex; otherwise,
                    // false. The existing shortest path is taken from the addition of each of the endpoints from
                    // the origin to the endpoint vertex which represent the existing shortest path when added.
                    bool IsCurrentPathLessThanShortestPath()
                    {
                        return(accumulations.ContainsKey(endpoint.Vertex) &&
                               comparer.Compare(currentPath, accumulations[endpoint.Vertex]) < 0);
                    }

                    // If the dictionary of graphs does not contain a graph for the endpoint vertex or the current
                    // path is less than the existing shortest path, then update the graph of the endpoint vertex.
                    if (!graphs.ContainsKey(endpoint.Vertex) || IsCurrentPathLessThanShortestPath())
                    {
                        // If the dictionary of graphs contains a graph for the nearest vertex, then a shortest path
                        // from the origin to the nearest vertex already exists so return a copy of this graph;
                        // otherwise, such a shortest path does not exist so return a new empty graph.
                        var currentGraph = graphs.ContainsKey(nearestVertex)
                            ? graphs[nearestVertex].EndpointPairs.ToGraph()
                            : new WeightedDirectedGraph <TVertex, TEdge>();

                        // Adds an edge from the nearest vertex to the vertex of the endpoint. This means that the
                        // graph will now contain endpoint pairs from the origin to the endpoint vertex.
                        currentGraph.AddEdge(nearestVertex, endpoint.Vertex, endpoint.Edge);

                        // Updates the graph of the endpoint vertex with the current graph because the current graph
                        // contains a shorter path from the origin to the endpoint vertex than the existing graph.
                        graphs[endpoint.Vertex] = currentGraph;

                        // Updates the addition of the endpoint vertex with the current path for the same reason.
                        accumulations[endpoint.Vertex] = currentPath;
                    }

                    // Adds the endpoint vertex to the set of unsettled vertices.
                    unsettledVertices.Add(endpoint.Vertex);
                }

                // Adds the nearest vertex to the set of settled vertices.
                settledVertices.Add(nearestVertex);
            }

            return(graphs);
        }
        public static IEnumerable <IWeightedDirectedPath <TVertex, TEdge> > AllSimplePaths <TVertex, TEdge>(
            this IWeightedDirectedGraph <TVertex, TEdge> graph,
            TVertex origin,
            TVertex destination,
            IAdder <TEdge> adder,
            int maxDepth = int.MaxValue
            )
        {
            if (graph == null)
            {
                throw new ArgumentNullException(nameof(graph));
            }
            if (origin == null)
            {
                throw new ArgumentNullException(nameof(origin));
            }
            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }
            if (adder == null)
            {
                throw new ArgumentNullException(nameof(adder));
            }

            if (!graph.Vertices.Contains(origin))
            {
                throw new ArgumentException();
            }
            if (!graph.Vertices.Contains(destination))
            {
                throw new ArgumentException();
            }

            var visitedVertices = new Stack <TVertex>();
            var visitedEdges    = new Stack <TEdge>();
            var paths           = new HashSet <IWeightedDirectedPath <TVertex, TEdge> >();

            visitedVertices.Push(origin);

            var stack = new Stack <Tuple <TVertex, Queue <IWeightedEndpoint <TVertex, TEdge> > > >();

            stack.Push(new Tuple <TVertex, Queue <IWeightedEndpoint <TVertex, TEdge> > >(
                           origin,
                           graph.SuccessorEndpoints(origin).ToQueue()
                           ));

            while (stack.Count > 0)
            {
                var(vertex, successorEndpoints) = stack.Peek();

                if (Equals(vertex, destination) || successorEndpoints.Count == 0 || stack.Count > maxDepth)
                {
                    if (Equals(vertex, destination))
                    {
                        var weightedDirectedPath = new WeightedDirectedPath <TVertex, TEdge>(
                            graph,
                            origin,
                            destination,
                            new Stack <TVertex>(visitedVertices),
                            new Stack <TEdge>(visitedEdges),
                            visitedEdges.Aggregate(adder.Add)
                            );

                        paths.Add(weightedDirectedPath);
                    }

                    if (visitedVertices.Count > 0)
                    {
                        visitedVertices.Pop();
                    }
                    if (visitedEdges.Count > 0)
                    {
                        visitedEdges.Pop();
                    }

                    stack.Pop();
                }
                else
                {
                    var successorEndpoint = successorEndpoints.Dequeue();

                    visitedVertices.Push(successorEndpoint.Vertex);
                    visitedEdges.Push(successorEndpoint.Edge);

                    bool Predicate(IWeightedEndpoint <TVertex, TEdge> grandchildEndpoint)
                    {
                        return(!visitedVertices.Contains(grandchildEndpoint.Vertex));
                    }

                    stack.Push(new Tuple <TVertex, Queue <IWeightedEndpoint <TVertex, TEdge> > >(
                                   successorEndpoint.Vertex,
                                   graph.SuccessorEndpoints(successorEndpoint.Vertex).Where(Predicate).ToQueue()
                                   ));
                }
            }

            return(paths);
        }