Dijkstra算法_北京地铁换乘_android实现-附带源码.apk
Dijkstra算法_北京地铁换乘_android实现 android 2.2+
直接上图片 如下:
Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。
Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。
其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。
初始时,S中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度。Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组dist作必要的修改。一旦S包含了所有V中顶点,dist就记录了从源到所有其它顶点之间的最短路径长度。
/**时间复杂度比较复杂,因为换乘结点的关系导致的 最坏情况下(每个站之间都有连线,但是地铁线路图实际上是不存在次情况的):O(2^n) 相反 最优情况下(之间只有唯一的连接点,次情况下也不是很现实的,有的地铁换乘是多个换乘点都在同一条线上的) 此时用hashtable所以是:O(1) */ private java.util.HashSet<String> GetF(java.util.HashSet<String> beginlist) { if (mainht == null || mainht.isEmpty()) { return null; } returnlist = new java.util.HashSet<String>(); if (beginlist.isEmpty()) { isend = 1; } else { /**O(n) */ for (String strbegin : beginlist) { if (strbegin.indexOf("-") == -1 && mainht.containsKey(strbegin) == true) //have this key and first load data { bxy = (double[])DCht.get(strbegin); earry = mainht.get(strbegin).toString().split("[,]", -1); for (String ar : earry) { exy = (double[])DCht.get(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.get(temgstr); earry = mainht.get(temgstr).toString().split("[,]", -1); //exchange node for (String ar : earry) { exy = (double[])DCht.get(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); } else { return null; } }
//East South West North Northeast Northwest Southeast Southwest private boolean CK(boolean isadd, double[] bxy, double[] exy) { return true; }
整个查询过程耗时不超过20毫秒
单源最短路径问题,即在图中求出给定顶点到其它任一顶点的最短路径。在弄清楚如何求算单源最短路径问题之前,必须弄清楚最短路径的最优子结构性质。
一.最短路径的最优子结构性质
该性质描述为:如果P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径,k和s是这条路径上的一个中间顶点,那么P(k,s)必定是从k到s的最短路径。下面证明该性质的正确性。
假设P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径,则有P(i,j)=P(i,k)+P(k,s)+P(s,j)。而P(k,s)不是从k到s的最短距离,那么必定存在另一条从k到s的最短路径P'(k,s),那么P'(i,j)=P(i,k)+P'(k,s)+P(s,j)<P(i,j)。则与P(i,j)是从i到j的最短路径相矛盾。因此该性质得证。
二.Dijkstra算法
由上述性质可知,如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点。那么(Vi...Vk)也必定是从i到k的最短路径。为了求出最短路径,Dijkstra就提出了以最短路径长度递增,逐次生成最短路径的算法。譬如对于源顶点V0,首先选择其直接相邻的顶点中长度最短的顶点Vi,那么当前已知可得从V0到达Vj顶点的最短距离dist[j]=min{dist[j],dist[i]+matrix[i][j]}。根据这种思路,
假设存在G=<V,E>,源顶点为V0,U={V0},dist[i]记录V0到i的最短距离,path[i]记录从V0到i路径上的i前面的一个顶点。
1.从V-U中选择使dist[i]值最小的顶点i,将i加入到U中;
2.更新与i直接相邻顶点的dist值。(dist[j]=min{dist[j],dist[i]+matrix[i][j]})
3.知道U=V,停止。