Beispiel #1
0
        /// <summary>
        /// 查找直达路线。
        /// </summary>
        /// <param name="startNode">开始节点。</param>
        /// <param name="endNode">结束节点。</param>
        /// <returns>乘车路线。</returns>
        private MetroPath FindDirectPath(MetroNode startNode, MetroNode endNode)
        {
            MetroPath path = new MetroPath();

            var startLines = startNode.Links.Select(c => c.Line).Distinct().ToList();
            var endLines   = endNode.Links.Select(c => c.Line).Distinct().ToList();

            var lines = startLines.Where(c => endLines.Contains(c)).ToList();

            if (lines.Count == 0)
            {
                return(path);
            }

            //查找直达路线
            List <MetroPath> pathList = new List <MetroPath>();

            foreach (var line in lines)
            {
                pathList.AddRange(FindShortestPaths(startNode, endNode, line));
            }

            //挑选最短路线
            return(GetShortestPath(pathList));
        }
Beispiel #2
0
        /// <summary>
        /// 合并路线。
        /// </summary>
        /// <exception cref="ArgumentNullException">如果path为空引用,则跑出该异常。</exception>
        public MetroPath Merge(MetroPath path)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }

            MetroPath newPath = new MetroPath();

            newPath.Links.AddRange(this.Links);
            newPath.Links.AddRange(path.Links);
            return(newPath);
        }
Beispiel #3
0
        /// <summary>
        /// 最佳一条新的Link,并返回一条新的路线。
        /// </summary>
        /// <exception cref="ArgumentNullException">如果link为空引用,则跑出该异常。</exception>
        public MetroPath Append(MetroLink link)
        {
            if (link == null)
            {
                throw new ArgumentNullException("link");
            }

            MetroPath newPath = new MetroPath();

            newPath.Links.AddRange(this.Links);
            newPath.Links.Add(link);
            return(newPath);
        }
Beispiel #4
0
        /// <summary>
        /// 从指定的路线列表中挑选一个最短的路线。
        /// </summary>
        /// <param name="pathList"></param>
        /// <returns></returns>
        private MetroPath GetShortestPath(List <MetroPath> pathList)
        {
            MetroPath minPath   = new MetroPath();
            int       minLength = int.MaxValue;

            foreach (var item in pathList)
            {
                if (item.Links.Count < minLength)
                {
                    minLength = item.Links.Count;
                    minPath   = item;
                }
            }
            return(minPath);
        }
Beispiel #5
0
        /// <summary>
        /// 查找乘车路线。
        /// </summary>
        /// <param name="startNodeName">起点的名称。</param>
        /// <param name="endNodeName">终点的名称。</param>
        public void FindPath(string startNodeName, string endNodeName)
        {
            if (!this.Graph.Nodes.Contains(startNodeName))
            {
                return;
            }
            if (!this.Graph.Nodes.Contains(endNodeName))
            {
                return;
            }

            this.StartNode = this.Graph.Nodes[startNodeName];
            this.EndNode   = this.Graph.Nodes[endNodeName];
            this.CurPath   = FindPath(this.StartNode, this.EndNode);

            Invalidate();
        }
Beispiel #6
0
        /// <summary>
        /// 重写OnMouseUp方法。
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            //选择起点或终点
            var node = GetNodeAt(e.Location);

            if (node != null && node.Name != "1" && node.Name != "2" && node.Name != "3")
            {
                if (this.StartNode == null)
                {
                    this.StartNode = node;
                }
                else
                {
                    this.EndNode = node;

                    //查找乘车线路
                    Cursor.Current = Cursors.WaitCursor;
                    try
                    {
                        m_curPath = FindPath(this.StartNode, this.EndNode);
                    }
                    finally
                    {
                        Cursor.Current = Cursors.Default;
                    }
                }
            }
            else if (Distance(e.Location, m_mouseDownPoint) < 3)//是否发生拖拽
            {
                this.StartNode = this.EndNode = null;
                this.CurPath.Links.Clear();

                if (CurPath.Links.Count > 0)
                {
                    this.BackColor = Color.White;
                }
                else
                {
                    this.BackColor = Color.WhiteSmoke;
                }
            }

            Invalidate();
        }
Beispiel #7
0
        /// <summary>
        /// 查找指定两个节点之间的最短路径。
        /// </summary>
        /// <param name="startNode">开始节点。</param>
        /// <param name="endNode">结束节点。</param>
        /// <param name="line">目标线路(为null表示不限制线路)。</param>
        /// <returns>乘车路线列表。</returns>
        private List <MetroPath> FindShortestPaths(MetroNode startNode, MetroNode endNode, MetroLine line)
        {
            List <MetroPath> pathtList = new List <MetroPath>();

            if (startNode == endNode)
            {
                return(pathtList);
            }

            //路径队列,用于遍历路径
            Queue <MetroPath> pathQueue = new Queue <MetroPath>();

            pathQueue.Enqueue(new MetroPath());

            while (pathQueue.Count > 0)
            {
                var path = pathQueue.Dequeue();

                //如果已经超过最短路径,则直接返回
                if (pathtList.Count > 0 && path.Links.Count > pathtList[0].Links.Count)
                {
                    continue;
                }

                //路径的最后一个节点
                MetroNode prevNode = path.Links.Count > 0 ? path.Links[path.Links.Count - 1].From : null;
                MetroNode lastNode = path.Links.Count > 0 ? path.Links[path.Links.Count - 1].To : startNode;

                //继续寻找后续节点
                //int Gx_min = int.MaxValue;
                //int Gx;
                foreach (var link in lastNode.Links.Where(c => c.To != prevNode && (line == null || c.Line == line)))
                {
                    /*Gx = Math.Abs(link.To.X - endNode.X) + Math.Abs(link.To.Y - endNode.Y) + 500 * path.Links.Count;
                     *
                     * if (Gx < Gx_min)
                     *  Gx_min = Gx;
                     * else
                     *  continue;*/

                    if (link.Weight == 2)
                    {
                        continue;
                    }

                    if (link.To == endNode)
                    {
                        MetroPath newPath = path.Append(link);
                        if (pathtList.Count == 0 || newPath.Links.Count == pathtList[0].Links.Count)
                        {//找到一条路径
                            pathtList.Add(newPath);
                        }
                        else if (newPath.Links.Count < pathtList[0].Links.Count)
                        {//找到一条更短的路径
                            pathtList.Clear();
                            pathtList.Add(newPath);
                        }
                        else
                        {
                            break; //更长的路径没有意义
                        }
                    }
                    else if (!path.ContainsNode(link.To))
                    {
                        pathQueue.Enqueue(path.Append(link));
                    }

                    link.Weight = 2;
                }
            }

            return(pathtList);
        }
Beispiel #8
0
        /// <summary>
        /// 查找乘车路线。
        /// </summary>
        /// <param name="startNode">起点。</param>
        /// <param name="endNode">终点。</param>
        /// <returns>乘车路线。</returns>
        public MetroPath FindPath(MetroNode startNode, MetroNode endNode)
        {
            MetroPath path = new MetroPath();

            if (startNode == null || endNode == null)
            {
                return(path);
            }
            if (startNode == endNode)
            {
                return(path);
            }

            foreach (var item in this.Graph.Nodes)
            {
                foreach (var link in item.Links)
                {
                    link.Weight = 3;
                }
            }

            //如果起点和终点拥有共同线路,则查找直达路线
            path = FindDirectPath(startNode, endNode);
            if (path.Links.Count > 0)
            {
                return(path);
            }

            //如果起点和终点拥有一个共同的换乘站点,则查找一次换乘路线
            //path = FindOneTransferPath(startNode, endNode);
            //if (path.Links.Count > 0) return path;

            //查找路径最短的乘车路线
            var pathList = FindShortestPaths(startNode, endNode, null);

            //查找换乘次数最少的一条路线
            int minTransfers = int.MaxValue;

            foreach (var item in pathList)
            {
                var curTransfers = item.Transfers;
                if (curTransfers < minTransfers)
                {
                    minTransfers = curTransfers;
                    path         = item;
                }
            }



            if (CurPath.Links.Count > 0)
            {
                this.BackColor = Color.White;
            }
            else
            {
                this.BackColor = Color.WhiteSmoke;
            }

            return(path);
        }