Rex)
1. Overview
In the past two days, some people in the blog Park talked about the implementation of the subway map. Before that, I used an android subway map application with neoragex2002. Therefore, for the subway mapAlgorithmI think it is necessary to write a special blog to provide our solutions for your reference. The time complexity of the algorithm described in this article is O (| E | log | E |), where | E | is the number of edges.
2. Concepts
1) vertices and edges
The basic elements are vertices (subway stations) and edges (directed tracks between two adjacent stations ).
For example, there are lines 1 and 5 on the xinzhuang station, 4 on the sides of the xinzhuang station, 4 on the Century Avenue station, and 8 on the sides of the Century Avenue station.
2) Operation Section
On the basis of edges, there is also the concept of operation segments, that is, a set of continuous edges.
For example, line 1 includes xinzhuang-Fujin Road (departure interval: 8 points), xinzhuang-Shanghai Railway Station (departure interval: 6 points), and Shanghai South Railway Station-Fujin Road (departure interval: 8 points) shanghai South Railway Station-Shanghai Railway Station (departure interval of 6 points), Fujin Road-xinzhuang (departure interval of 8 points), Shanghai Railway Station-xinzhuang (departure interval of 6 points) and other operation sections.
3) Cost
The search algorithm can be based on any non-negative cost, such as time, transfer times, and number of passing edges. Here we focus on modeling time.
Each side has a time cost, which indicates the time required to take the subway over the side.
Each operation segment has a waiting time cost. It is generally assumed that the waiting time is the maximum departure time) or half of the departure interval (the mathematical expectation of waiting time ).
There is a transfer time cost matrix at each point, indicating the time required for the transfer between any two sides. The relationships between the two sides are directly connected, transferred, and not connected. The cost of the transfer time is 0, the transfer time is the transfer time + the waiting time, and the cost of the transfer time is + ∞. This matrix can be represented by a sparse matrix. The two sides that are not connected do not appear. Because of the subway design, we do not need to consider turning back along a line. We can consider one side and its opposite side as not connecting, rather than switching, which can reduce the complexity of the image.
3. Algorithm
1) Ideas
There are many traditional shortest path algorithms, such
Dijkstra algorithm, but this algorithm cannot solve the transfer time cost problem.
The breadth-first algorithm cannot obtain the optimal solution in the weighted graph.
The restricted depth-first algorithm can obtain results, but the algorithm takes a long time.
We can consider a natural phenomenon where snow melts on the mountain and then flows through the valley. Each site is the point in the valley, and the transfer site is the intersection of the valley into multiple shares.
Assume that the starting point is a mountain, and the water spreads along each side. When it passes through one side, it is the same as the ride time on the edge. from one side to the other side, you need to wait for the transfer time. The water flow keeps pouring at the starting point. When the water reaches the ending point, the water flow path is the shortest path we need.
The problem with this model is that water can flow with multiple streams at the same time, but our algorithm should have a sequence. we can assume that there is a water flow tangent that represents the front position of all streams. When any side e is covered by the water flow, and the end point is not covered by the water flow, add E to the tangent edge List C (implemented by the red/black tree or the Balance Tree) in the price order ), record the top side of e-> flow. If the water flow continues, the end point of the first edge e in C is first covered by the water flow and removed from C. When we reach the end point of pathfinding, we can trace the last side from the last side, and then the top side from the top side until the start point of pathfinding. In this way, we can obtain the desired path.
The algorithm can also not end at the end until the flow covers all points on the map, which has no significant impact on the performance.
2) Example
1:
Figure 1 (a) time cost figure 1 (B) search order
To simplify the problem, we assume that line 2 (green) and line 9 (water color) do not exist. We only consider Line 4 (dark blue) and line 6 (purple red ).
Figure 1 (a) shows the time cost of the edges of Line 4 and line 6. The white color indicates the waiting time, and the yellow color indicates the ride time.
We assume that each transfer station will take 4 minutes for the transfer.
Figure 1 (B) shows the search order. For the same price, the search order is variable, which is determined by the implementation of the tangent edge list C.
In this example, the starting point is Century Avenue and the ending point is Shanghai Children's Medical Center.
The change of the tangent edge list C is as follows:
{1, 2, 3, 5}
{2, 3, 4, 5}
{3, 4, 5, 6}
{4, 5, 6, 9}
{5, 6, 7, 9}
{6, 7, 8, 9}
{7, 8, 9, 10 ,..,..}
{8, 9, 10 ,..,..,..}
{9, 10 ,..,..,..,..}
{10 ,..,..,..,..,..}
Note that when 6 is eliminated, three sides are added to the reverse side of 10, (Blue Village Road, pond Bridge), and 9. When 9 is eliminated, the reverse side of 6 is added.
When 9 is deleted, 10 is searched again. The time cost is 13 + 4 + 8 = 25, but since 10 has recorded the top side, C is no longer added.
3) Implementation
PseudoCodeAs follows:
Record Vertex // Point Inedges: List <edge> // Inbound Outedges: List <edge> // Outbound Connection: Map <tuple <edge, edge>, edgeconnection> // EDGE connection matrix, which includes the transfer time cost. It does not exist when it is not connected. Record edge // Edge Start: vertex // Start Point End: vertex // Endpoint Cost: int // Ride time cost Ranges: List <range> // Operation Section Record range // Operation Section Edges: List <edge> // Edge Cost: int // Waiting Time Taggedunion edgeconnection connected: Unit // Direct Connection Transferable: int // Transfer, walking time cost Calculateroute (START: vertex, end: vertex): List <Edge> If Start = End Return New List <edge> () // Starting point and ending point overlap Let previous <- New Map <edge, edge> () // Ing from edge to top Let CMP <-(comparer <edge> )(...) // The path cost comparison function is provided below Let cutedges <- New Redblacktree <edge> (CMP) // Water Flow tangent edge list Foreach O In Start. outedges cutedges <-Cutedges + O previous <-Previous + (O, Null ) Let E <-(Edge )( Null )// Final edge While Cutedges. Count> 0 Let I <- Cutedges. First cutedges <-Cutedges- I let s <- I. End If S = End E <- I Break Foreach OIn S. outedges If ! S. Connection. containskey (I, O )) Continue If Previous. containskey (o) Continue Previous <-Previous + (O, I) cutedges <-Cutedges + O If E = Null Return Null // No path Let L <- New List <edge> () While E! = Null L <-L + E <- Previous (e) Return L. Reverse ()
The following is a comparison function when the pathfinding is based on time.
Let time <-New Map <edge, int> () Let range <- New Map <edge, range> () Let getbestrange <-L: List <range >=> L. orderby (r => R. Cost). firstlet gettime <- E => If E = Null Return 0 If Time. containskey (E) Return Time (e) Let p <- Previous (e) Let V <- Gettime (P) If P! = Null Let C <- E. Start. Connection (P, e )) If C | Connected-> Let rgold <- Range (p) Let RG <-Getbestrange (P. Ranges. Intersect (E. ranges) Range <-Range + (E, RG) If Rgold! = RG v <-V-rgold. Cost + RG. Cost | Transferable T-> Let RG <- Getbestrange (E. ranges) Range <-Range + (E, RG) V <-V + RG. Cost + T Else Let RG <- Getbestrange (E. ranges) Range <-Range + (E, RG) V <-V + RG. Cost v <-V + E. Cost time <-Time + (E, V) Return Vlet CMP <- (L: edge, R: edge) => Return Gettime (l)-gettime (r)
The following is a comparison function for finding a path based on the number of transfer times.
Let transfercount <-New Map <edge, int> () Let gettransfercount <- E => If E = Null Return 0 If Transfercount. containskey (E) Return Transfercount (e) Let p <- Previous (e) Let V <- Gettransfercount (P) If P! = Null Let C <- E. Start. Connection (P, e )) If C | Connected-> () | Transferable _-> V + = 1 Transfercount <-Transfercount + (E, V) Return Vlet CMP <- (L: edge, R: edge) => Return Gettransfercount (l)-gettransfercount (r)
The following is a comparison function for finding a path based on the number of passing edges.
Let stopcount <- New Map <edge, int> () Let getstopcount <- E => If E = Null Return 0 If Stopcount. containskey (E) Return Stopcount (e) Let p <- Previous (e) Let V <-Getstopcount (p) + 1 Stopcount <-Stopcount + (E, V) Return Vlet CMP <- (L: edge, R: edge) => Return Getstopcount (l)-getstopcount (r)
4. algorithm complexity
It is believed that the inbound and outbound sides of a vertex are few, and the operation segments covering each edge are few. It is noted that the recursive part of the gettime runtime will always be cached in the time variable, the complexity of the time comparison function is O (1 ).
The complexity of cutedges's red/Black Tree insertion and deletion is O (log | E | ).
All edges can enter and exit cutedges at most once. We can see that the complexity of the entire algorithm is O (| E | log | E | ).
5. Results
The algorithm described in this article can quickly obtain the global optimal path in O (| E | log | E |) time.
On a 1 GHz mobile phone with a single CPU, the time for finding a route between any two sites of Shanghai Metro (11 lines and 214 stations) is less than Ms.
Finally, we will introduce our application.
Vector subway (Shanghai Edition)
Supports bidirectional scaling, dynamic path finding, and local map display. Although we are only a small team, we only make the best subway map! If you have any questions or suggestions, please leave us a message!
Micro Blog http://weibo.com/vmetro
Head market http://apk.gfan.com/Product/App292947.html
Android marketing http://static.apk.hiapk.com/html/2012/07/690064.html
Application sink http://www.appchina.com/app/proj.VectorMetro/