地鐵線路圖高性能查找算法系統,最短路徑查詢地鐵網絡拓撲高效率算法-原創-附帶demo


離上次寫北京地鐵最短路程換乘已經有一些時間了,本來是昨天晚上寫的但是因為有點晚了所以沒寫! 寫在現在寫在這里。
 
 
 

話不多說 直接進入正題!

 

 

首先我給出demo   輸入比如   五道口,國貿 點擊按鈕搜索查詢即可!

 

現在我說說我的思路:

S1:加載全部換乘結點  方法Hashtable LoadDC() 

DCht.Add("XX", new double[] { -2, -1.4 });
 

上面是執行的一句代碼,XX的坐標即為(-1,-1.4)   用double類型后面要是地鐵換乘站在X之前增加了 那就直接寫上小於-1.4的,反之大於1.4! 否則若用int類型那耦合性太高了

這是不用int類型的好處!

 

S2:加載換乘站之間的關系{Relation for Node}  方法 HashSet<string[]> LoadDD()

            b1 = "begin";
            b2 = "end";
            len = "4.1";
            timem = "7";
            SWAP(backlist, ref arry, b1, b2, len, timem);

 len代表路程(數據來至百度),timem代表b1到b2的時間!

 

S3:現在我要查詢B到E的最短路程 搜索: B-E 開始

   S3_1:如果B,E都是換乘結點比如“西二旗”到“國貿” 那直接進行第四步S4

 S3_2:如果B,E中有一個不是換乘結點,執行方法 HashSet<string> GetPreOrNextNode(string stationname)

            string[] Linecp = { "西二旗", "生命科學園", "朱辛庄", "鞏華城", "沙河", "沙河高教園", "南邵" };
            int[] Linecpnode = { 1, 0, 0, 0, 0, 0, 1 };
            liststr.Add(Linecp);
            listint.Add(Linecpnode);

    1代表是換乘點或者是X號線的起點,0代表不是換乘結點

          hs = new HashSet<string>(tempstr);
                ///O(1)
                if (hs.Contains(stationname) == true)

      執行hash查找 最優情況下:O(1)

      while (pre > -1)
            {
                if (tint[pre] == 1)
                    break;
                pre = pre - 1;
            }
            int next = b;
            while (next < tint.Length)
            {
                if (tint[next] == 1)
                    break;
                next = next + 1;
            }

            HashSet<string> hr = new HashSet<string>();
            hr.Add(liststr[a][pre]);
            hr.Add(liststr[a][next]);
            return hr;

 

   現在返回可能值:(b1x,b1y),(b2x,b2y)  可能值共有C(2,2)+C(3,2)+C(4,2)=10種可能

  根據起點B和終點E查詢出來了BE附近的可能結點     然后用點到點的距離  找出最多10中可能值的最小值  返回min_b_node,min_e_node

S4:

現在已經有b_node,和e_node 起點和終點附近最短距離的換乘結點,(最短距離不代表最短路程,因為有可能它們之間沒有換乘關系) 但不要緊,請看下面:

 坐標中從一點出發到另一點的8種情況  直接上代碼:

        bool CK(bool isadd, double[] bxy, double[] exy)
        {
            if (dx >= 0 && dy >= 0 && exy[0] >= bxy[0] && exy[1] >= bxy[1] && exy[0] <= ex && exy[1] <= ey)     //1 x增大y增大
                isadd = true;
            else if (dx >= 0 && dy <= 0 && exy[0] >= bxy[0] && exy[1] <= bxy[1] && exy[0] <= ex && exy[1] >= ey)//2 x增大y減小
                isadd = true;
            else if (dx <= 0 && dy >= 0 && exy[0] <= bxy[0] && exy[1] >= bxy[1] && exy[0] >= ex && exy[1] <= ey)//3 x減小y增大
                isadd = true;
            else if (dx <= 0 && dy <= 0 && exy[0] <= bxy[0] && exy[1] <= bxy[1] && exy[0] >= ex && exy[1] >= ey)//4 x減小y減小
                isadd = true;
            else if (dx >= 0 && dy == 0 && exy[0] >= bxy[0] && exy[1] == bxy[1] && exy[1] == ey && exy[0] <= ex)//5 x增大y不變
                isadd = true;
            else if (dx == 0 && dy >= 0 && exy[0] == bxy[0] && exy[1] >= bxy[1] && exy[0] == ex && exy[1] <= ey)//6 x不變y增大
                isadd = true;
            else if (dx <= 0 && dy == 0 && exy[0] <= bxy[0] && exy[1] == bxy[1] && exy[1] == by && exy[0] >= ex)//7 x減小y不變
                isadd = true;
            else if (dx == 0 && dy <= 0 && exy[0] == bxy[0] && exy[1] <= bxy[1] && exy[0] == bx && exy[1] >= ey)//8 x不變 y減小
                isadd = true;
            else
                isadd = false;
            return isadd;
        }

 

 代碼我就不用解釋了,下面是核心代碼

          ///O(n)
                foreach (string strbegin in beginlist)
                {
                    if (strbegin.IndexOf("-") == -1 && mainht.ContainsKey(strbegin) == true)//have this key and first load data
                    {
                        bxy = (double[])DCht[strbegin];
                        earry = mainht[strbegin].ToString().Split(',');
                        foreach (string ar in earry)
                        {
                            exy = (double[])DCht[ar];
                            isadd = CK(isadd, bxy, exy);

                            if (isadd == true)
                            {
                                returnlist.Add(strbegin + "-" + ar);
                                isend = 0;
                            }
                        }
                    }
                    else if (strbegin.IndexOf("-") > -1 && mainht.ContainsKey(strbegin.Substring(strbegin.LastIndexOf("-") + 1)) == true)
                    {
                        temgstr = strbegin.Substring(strbegin.LastIndexOf("-") + 1);
                        bxy = (double[])DCht[temgstr];
                        earry = mainht[temgstr].ToString().Split(',');//exchange node
                        foreach (string ar in earry)
                        {
                            exy = (double[])DCht[ar];
                            isadd = CK(isadd, bxy, exy);

                            if (isadd == true)
                            {
                                if (!strbegin.Contains(ar))
                                    returnlist.Add(strbegin + "-" + ar);
                                isend = 0;
                            }
                        }
                    }

                }
            }
            earry = null;
            if (isend == 0)
                return GetF(returnlist, i);
            else
                return null;

 

到這里本人有個問題請教:

Code1: if (fresult.Contains(temp) == false)
       fresult.Add(temp);

Code2: fresult.Add(temp);

Code1和Code2有什么區別? freault為hashset     性能上的?????   我看了java中的實現過程 但是C#語言看不了實現過程  只看了過程的描述!

 

 

后面的實現過程就很簡單了!  找到BE之間盡量短的可能路線的集合然后找出其中最短的路徑 程序結束!

 

測試結果:

程序開始執行時間:20130515115735 734

LoadData begin:20130515115735 734
換乘站全集:Ux begin: 20130515115735734換乘站全集:Ux end: 20130515115735734
LoadData endss:20130515115735 734

GetF() begin:20130515115735:734
GetF() endss:20130515115735:734

五道口-知春路------------->北京西站:
五道口-知春路-西直門-車公庄-白石橋南-北京西站
五道口-知春路-西直門-國家圖書館-白石橋南-北京西站
五道口-知春路-海淀黃庄-國家圖書館-白石橋南-北京西站
count:3


最短路程為:五道口-知春路-海淀黃庄-國家圖書館-白石橋南-北京西站:11.3


程序結束執行時間:20130515115735 734

  

程序開始執行時間:20130515115844 812

LoadData begin:20130515115844 812
換乘站全集:Ux begin: 20130515115844812換乘站全集:Ux end: 20130515115844812
LoadData endss:20130515115844 812

GetF() begin:20130515115844:812
GetF() endss:20130515115844:812

五道口-知春路------------->國貿:
五道口-知春路-西直門-平安里-西單-東單-建國門-國貿
五道口-知春路-西直門-平安里-東四-東單-建國門-國貿
五道口-知春路-西直門-平安里-東四-朝陽門-建國門-國貿
五道口-知春路-西直門-平安里-東四-朝陽門-呼家樓-國貿
五道口-知春路-北土城-惠新西街南口-芍葯居-三元橋-呼家樓-國貿
五道口-知春路-西直門-鼓樓大街-雍和宮-東四-東單-建國門-國貿
五道口-知春路-西直門-鼓樓大街-雍和宮-東四-朝陽門-建國門-國貿
五道口-知春路-西直門-鼓樓大街-雍和宮-東四-朝陽門-呼家樓-國貿
五道口-知春路-西直門-鼓樓大街-雍和宮-東直門-朝陽門-建國門-國貿
五道口-知春路-西直門-鼓樓大街-雍和宮-東直門-朝陽門-呼家樓-國貿
五道口-知春路-西直門-車公庄-復興門-西單-東單-建國門-國貿
五道口-知春路-西直門-車公庄-平安里-西單-東單-建國門-國貿
五道口-知春路-西直門-車公庄-平安里-東四-東單-建國門-國貿
五道口-知春路-西直門-車公庄-平安里-東四-朝陽門-建國門-國貿
五道口-知春路-西直門-車公庄-平安里-東四-朝陽門-呼家樓-國貿
五道口-知春路-北土城-鼓樓大街-雍和宮-東四-東單-建國門-國貿
五道口-知春路-北土城-鼓樓大街-雍和宮-東四-朝陽門-建國門-國貿
五道口-知春路-北土城-鼓樓大街-雍和宮-東四-朝陽門-呼家樓-國貿
五道口-知春路-北土城-鼓樓大街-雍和宮-東直門-朝陽門-建國門-國貿
五道口-知春路-北土城-鼓樓大街-雍和宮-東直門-朝陽門-呼家樓-國貿
五道口-知春路-北土城-惠新西街南口-雍和宮-東四-東單-建國門-國貿
五道口-知春路-北土城-惠新西街南口-雍和宮-東四-朝陽門-建國門-國貿
五道口-知春路-北土城-惠新西街南口-雍和宮-東四-朝陽門-呼家樓-國貿
五道口-知春路-北土城-惠新西街南口-雍和宮-東直門-朝陽門-建國門-國貿
五道口-知春路-北土城-惠新西街南口-雍和宮-東直門-朝陽門-呼家樓-國貿
五道口-知春路-北土城-惠新西街南口-芍葯居-東直門-朝陽門-建國門-國貿
五道口-知春路-北土城-惠新西街南口-芍葯居-東直門-朝陽門-呼家樓-國貿
count:27


最短路程為:五道口-知春路-北土城-惠新西街南口-芍葯居-三元橋-呼家樓-國貿:16.8


程序結束執行時間:20130515115844 812

  

 

 

 

獻上測試鏈接   點擊我

 

SF 2013.05.15 

 

END

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM