예제 #1
0
        private SearchAlgorithmResult SearchShortestPaths(Graph graph, Guid origin, Guid destination, Guid nodeToNotInclude)
        {
            SearchAlgorithmResult result = null;
            var visitedNodes             = new List <Guid>();
            var unvisitedNodes           = new List <Guid>();
            var searchVertices           = new List <SearchVertex>();

            graph.Vertices.ForEach(id =>
            {
                if (!unvisitedNodes.Contains(id) && id != nodeToNotInclude)
                {
                    var distance = int.MaxValue;
                    if (id == origin)
                    {
                        distance = 0;
                    }

                    unvisitedNodes.Add(id);
                    searchVertices.Add(new SearchVertex(id, distance));
                }
            });

            DepthFirstSearch(graph, visitedNodes, unvisitedNodes, searchVertices);

            // Search from back to front ir order to build de path
            var lastVertex = searchVertices.FirstOrDefault(vertex => vertex.VertexId == destination);

            if (lastVertex != null && lastVertex.PreviousVertexId != Guid.Empty)
            {
                // The destination node is reachable from the origin
                var stack = new Stack <SearchVertex>();

                stack.Push(lastVertex);

                while (lastVertex != null && lastVertex.VertexId != origin && lastVertex.PreviousVertexId != Guid.Empty)
                {
                    var previousVertexId = lastVertex.PreviousVertexId;

                    lastVertex = searchVertices.FirstOrDefault(vertex => vertex.VertexId == previousVertexId);

                    if (lastVertex != null)
                    {
                        stack.Push(lastVertex);
                    }
                }

                result = new SearchAlgorithmResult();

                foreach (var searchVertex in stack)
                {
                    result.RouteVertex.Add(new Vertex(searchVertex.VertexId, searchVertex.DistanceToOrigin));
                    result.TotalDistance += searchVertex.DistanceToOrigin;
                }
            }

            return(result);
        }
예제 #2
0
        /// <inheritdoc />
        /// <summary>
        ///     Search the optimal path according to the parameters
        /// </summary>
        /// <param name="graph">The route graph to search</param>
        /// <param name="origin">The origin point to search</param>
        /// <param name="destination">The destination point</param>
        /// <param name="searchOptionsPath">
        ///     Defines if the search can be direct or needs at least one hop between origin and
        ///     destination
        /// </param>
        public SearchAlgorithmResult Search(Graph graph, Guid origin, Guid destination,
                                            SearchOptions.SearchOptionPath searchOptionsPath)
        {
            if (graph?.Vertices == null || origin == Guid.Empty || destination == Guid.Empty || origin == destination)
            {
                return(null);
            }

            SearchAlgorithmResult result = null;

            if (searchOptionsPath == SearchOptions.SearchOptionPath.Direct)
            {
                result = SearchShortestPaths(graph, origin, destination);
            }
            else
            {
                var neighbors = graph.Neighbors(origin);

                if (neighbors != null && neighbors.Any())
                {
                    foreach (var neighbor in neighbors)
                    {
                        if (neighbor.NodeId != destination)
                        {
                            var neighborResult = SearchShortestPaths(graph, neighbor.NodeId, destination, origin);

                            if (neighborResult == null)
                            {
                                continue;
                            }

                            neighborResult.RouteVertex.Insert(0, new Vertex(origin, 0));
                            neighborResult.TotalDistance += neighbor.DistanceToNode;

                            if (result == null || result.TotalDistance > neighborResult.TotalDistance)
                            {
                                result = neighborResult;
                            }
                        }
                    }
                }
            }

            return(result);
        }