Exemple #1
0
            public PathToNode GetReverse()
            {
                var ptn = new PathToNode();

                foreach (var p in Path)
                {
                    ptn.Path.Insert(0, p);
                }

                ptn.Weight = Weight;
                return(ptn);
            }
Exemple #2
0
        private IEnumerable <ThreadInfo> GetShortestPath(ThreadManager TM, int to)
        {
            var currentThread = TM.CurrentThread;

            // See if the start node is already in the goal location
            yield return(TM.MakeDbCall(currentThread, Program.ConnectionString, "spGetLocationNodes", new SqlParameter("@location", to)));

            using (var table = TM.GetResult <DataTable>(currentThread)) {
                if (table.Rows.Count == 0)
                {
                    // Error - no nodes in goal location
                    yield return(TM.Return(currentThread));
                }

                foreach (DataRow row in table.Rows)
                {
                    if (new Node(row).Id == _start.Id)
                    {
                        // Already at goal
                        yield return(TM.Return(currentThread));
                    }
                }
            }

            // Get the nodes on the boundary of the goal location
            var goalNodes = new Dictionary <int, SortedSet <Node> >();

            yield return(TM.MakeDbCall(currentThread, Program.ConnectionString, "spGetLocationBoundaryNodes", new SqlParameter("@location", to)));

            using (var table = TM.GetResult <DataTable>(currentThread)) {
                if (table.Rows.Count == 0)
                {
                    // Error - no nodes on goal location's boundary
                    yield return(TM.Return(currentThread));
                }

                foreach (DataRow row in table.Rows)
                {
                    var node = new Node(row);
                    if (!goalNodes.ContainsKey(node.Partition.Value))
                    {
                        goalNodes[node.Partition.Value] = new SortedSet <Node>(new NodeComparer());
                    }
                    goalNodes[node.Partition.Value].Add(node);
                }
            }

            // Get the possible partition paths
            Stack <PartitionPass> partitions = new Stack <PartitionPass>();

            partitions.Push(new PartitionPass(-1, _start, 0));
            yield return(TM.Await(currentThread, GetPartitionPaths(TM, partitions, goalNodes)));

            var passes = TM.GetResult <List <List <PartitionPass> > >(currentThread);

            SortedSet <TargetPath>         queue         = new SortedSet <TargetPath>(new TargetPathComparer());
            Dictionary <int, ShortestPath> shortestPaths = new Dictionary <int, ShortestPath>();

            shortestPaths[_start.Id] = new ShortestPath();
            foreach (var pass in passes)
            {
                queue.Add(new TargetPath(_start, 0, pass, queue, _settings));
            }

            while (true)
            {
                var currentPath = queue.First();

                _pathFindingDone = Math.Max(_pathFindingDone, currentPath.DistSoFar * currentPath.DistSoFar / (currentPath.BestDist * currentPath.BestDist));

                if (goalNodes.Any(kvp => kvp.Value.Contains(currentPath.CurrentNode)))
                {
                    var currentNode = currentPath.CurrentNode;
                    var prevNode    = shortestPaths[currentNode.Id].PrevNode;
                    _paths.Add(new DirectionPath(currentNode.Lat, currentNode.Lon, null, true, null, currentNode.Altitude, currentNode.Location, currentNode.Outside, shortestPaths[currentNode.Id].Id, shortestPaths[currentNode.Id].Forward));
                    while (currentNode.Id != _start.Id)
                    {
                        _paths.Insert(0, new DirectionPath(prevNode.Lat, prevNode.Lon, null, false, null, prevNode.Altitude, prevNode.Location, prevNode.Outside, shortestPaths[currentNode.Id].Id, shortestPaths[currentNode.Id].Forward));
                        currentNode = prevNode;
                        prevNode    = shortestPaths[currentNode.Id].PrevNode;
                    }
                    _paths.First().Flag = true;
                    yield return(TM.Return(currentThread));
                }

                yield return(TM.MakeDbCall(currentThread, Program.ConnectionString, "spGetPathsFromNode",
                                           new SqlParameter("@node", currentPath.CurrentNode.Id),
                                           new SqlParameter("@part", currentPath.PartitionsLeft.First().Partition)));

                using (var table = TM.GetResult <DataTable>(currentThread)) {
                    foreach (DataRow row in table.Rows)
                    {
                        var    path     = new PathToNode(row, currentPath.CurrentNode.Id, currentPath.PartitionsLeft.First().Partition);
                        double pathDist = _settings.WeightedDist(currentPath.CurrentNode, path.Node);

                        if (shortestPaths.ContainsKey(path.Node.Id))
                        {
                            if (shortestPaths[path.Node.Id].TotalDist > currentPath.DistSoFar + pathDist)
                            {
                                shortestPaths[path.Node.Id].SetPrevNode(currentPath.CurrentNode, pathDist, path.Path.Id, path.Forward, shortestPaths);
                            }
                            else if (shortestPaths[path.Node.Id].TotalDist < currentPath.DistSoFar + pathDist)
                            {
                                continue;
                            }
                            // TODO
                        }
                        else
                        {
                            shortestPaths[path.Node.Id] = new ShortestPath(currentPath.CurrentNode, pathDist, path.Path.Id, path.Forward, shortestPaths);
                            // TODO
                        }

                        if (path.Node.Id == currentPath.PartitionsLeft.First().Target.Id)
                        {
                            queue.Add(new TargetPath(path.Node, shortestPaths[path.Node.Id].TotalDist, currentPath.PartitionsLeft.Skip(1).ToList(), queue, _settings));
                        }
                        else
                        {
                            queue.Add(new TargetPath(path.Node, shortestPaths[path.Node.Id].TotalDist, currentPath.PartitionsLeft, queue, _settings));
                        }
                    }
                }

                queue.Remove(currentPath);
            }
        }
Exemple #3
0
        public static List <IEdge> GetShortestPath(this IGraph graph, INode start, INode end)
        {
            Dictionary <int, int>        nodes     = new Dictionary <int, int>();
            Dictionary <int, PathToNode> nodePaths = new Dictionary <int, PathToNode>();

            nodePaths.Add(start.Number, new PathToNode(start, 0, new List <IEdge>()));
            nodes.Add(start.Number, 0);
            while (nodes.Count > 0)
            {
                var currentNodeIndex = 0;
                var min = int.MaxValue;
                foreach (var node in nodes)
                {
                    if (node.Value < min)
                    {
                        min = node.Value;
                        currentNodeIndex = node.Key;
                    }
                }
                if (nodePaths[currentNodeIndex].Node == end)
                {
                    nodes.Remove(currentNodeIndex);
                    continue;
                }
                var iEdges = new List <IEdge>(nodePaths[currentNodeIndex].Node.IncidentEdges);
                iEdges.Sort((x, y) => x.Length.CompareTo(y.Length));
                foreach (var incidentEdge in iEdges)
                {
                    var icidentNodeIndex = incidentEdge.OtherNode(nodePaths[currentNodeIndex].Node).Number;
                    if (!nodePaths.ContainsKey(icidentNodeIndex))
                    {
                        var newPath = new List <IEdge>(nodePaths[currentNodeIndex].Path)
                        {
                            incidentEdge
                        };
                        nodes.Add(icidentNodeIndex, nodePaths[currentNodeIndex].MinimalLenght + incidentEdge.Length);
                        nodePaths.Add(icidentNodeIndex,
                                      new PathToNode(incidentEdge.OtherNode(nodePaths[currentNodeIndex].Node),
                                                     nodePaths[currentNodeIndex].MinimalLenght + incidentEdge.Length, newPath));
                    }
                    else if (!nodePaths[icidentNodeIndex].Viseted)
                    {
                        if (incidentEdge.Length + nodePaths[currentNodeIndex].MinimalLenght < nodePaths[icidentNodeIndex].MinimalLenght)
                        {
                            nodes[icidentNodeIndex] = nodePaths[currentNodeIndex].MinimalLenght + incidentEdge.Length;
                            var newPathToNode = new PathToNode(nodePaths[icidentNodeIndex].Node,
                                                               nodePaths[currentNodeIndex].MinimalLenght + incidentEdge.Length, new List <IEdge>(nodePaths[currentNodeIndex].Path));
                            newPathToNode.Path.Add(incidentEdge);
                            nodePaths[icidentNodeIndex] = newPathToNode;
                        }
                    }
                }
                var t = nodePaths[currentNodeIndex];
                t.Viseted = true;
                nodePaths[currentNodeIndex] = t;
                nodes.Remove(currentNodeIndex);
            }
            if (nodePaths.ContainsKey(end.Number))
            {
                return(nodePaths[end.Number].Path);
            }
            else
            {
                return(null);
            }
        }