Heap + Dijkstra stack optimization Dijkstra and heapdijkstra stack Optimization

Source: Internet
Author: User

Heap + Dijkstra stack optimization Dijkstra and heapdijkstra stack Optimization

As mentioned above, the "Native Dijkstra" adopts a greedy strategy. It is necessary to traverse all nodes when greedy to find the node that is currently shortest from the source node, this will inevitably lead to a decrease in efficiency. The time complexity is n ^ n. Therefore, when the data volume is large, it will take a long time. To improve Dijkstra's efficiency, we only need to improve Dijkstra's greedy policy.

Dijkstra adopts the greedy strategy to search for the shortest node and store it in the S collection of all the known shortest node, which can be associated with the data structure of the heap and priority queue, these structures can efficiently provide the node with the shortest distance from the current state. The practice can also prove that the two optimization methods significantly improve the efficiency of Dijkstra.

In addition, it should be mentioned that the priority queue optimization Dijkstra is similar to the heap optimization Dijkstra, but the priority queue optimization method is very good, because the java class library contains the PriorityQueue object, this object is the priority queue. However, the heap optimization is complicated because you need to implement the Minimum heap by yourself, which is both complex and error-prone. Therefore, if you want to optimize mongosra, priorityQueue + Dijkstra is the priority queue optimized Dijkstra.

The following uses the "shortest circuit" of the Blue Bridge cup as an example to show the Dijkstra of Heap + Dijkstra stack optimization.

Maximum short-circuit time limit for algorithm training: 1.0 s memory limit: 256.0 MB Problem description

Given n vertices and Directed Graphs of m edges (some edge weights may be negative, but there is no negative ring ). Calculate the shortest path (from vertex 1 to vertex n) from vertex 1 to other ).

Input Format

The first line has two integers, n and m.

In the next m row, each row has three integers u, v, l, indicating that u to v has an edge with a length of l.

There are n-1 lines in the output format. line I indicates the shortest path from Point 1 to point I + 1. Example input 3 3
1 2-1
2 3-1
3 1 2 sample output-1
-2 data scale and conventions

For 10% of the data, n = 2, m = 2.

For 30% of the data, n <= 5, m <= 10.

For 100% of data, 1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000, to ensure that all other vertices can be reached from any vertex.


The Dijkstra code for heap optimization is as follows:


Import java. util. hashMap; import java. util. iterator; import java. util. imports; import java. util. set;/*** the Heap + Dijkstra algorithm is used to find the single-source shortest path *. The graph data is stored in an adjacent table using an adjacent table structure: * Header Node -- Node object array * adjacent Node -- HashMap ** In the Node object @ author DuXiangYu **/public class constraint stra_link_heap {static int nodeCount; static int edgeCount; // array of the List headers of the adjacent table static Node [] firstArray; // Shortest Path array static int [] [] dist; static int [] ref; static int max = 1000000 ;/** * Node class ** @ author DuXiangYu */static class Node {// adjacent vertex mapprivate HashMap <Integer, Integer> map = null; public void addEdge (int end, int edge) {if (this. map = null) {this. map = new HashMap <Integer, Integer> ();} this. map. put (end, edge) ;}} public static void main (String [] args) {consumer SC = new consumer (System. in); nodeCount = SC. nextInt (); edgeCount = SC. nextInt (); firstArray = new Node [nodeCount + 1]; For (int I = 0; I <nodeCount + 1; I ++) {firstArray [I] = new Node () ;}for (int I = 0; I <edgeCount; I ++) {int begin = SC. nextInt (); int end = SC. nextInt (); int edge = SC. nextInt (); firstArray [begin]. addEdge (end, edge);} SC. close (); long begin = System. currentTimeMillis (); djst (); long end = System. currentTimeMillis (); System. out. println (end-begin + "ms");}/*** Heap + Dijkstra Algorithm Implementation */private static void Djst () {dist = new int [2] [nodeCount + 1]; ref = new int [nodeCount + 1]; Node tempNode = firstArray [1]; for (int I = 2; I <nodeCount + 1; I ++) {HashMap <Integer, Integer> tempMap = tempNode. map; dist [0] [I] = tempMap. containsKey (I )? TempMap. get (I): max; dist [1] [I] = I; ref [I] = I; minUp (I);} int flag = nodeCount; while (flag> = 2) {int index = dist [1] [2]; changeKey (2, flag); maxDown (2, -- flag ); // use the indx vertex to update the HashMap <Integer, Integer> m = firstArray [index] distance from its adjacent vertex to the start vertex. map; if (m = null) {continue;} Set <Integer> set = m. keySet (); Iterator <Integer> it = set. iterator (); while (it. hasNext () {int num = it. next (); if (m. get (num) + dist [0] [flag + 1] <dist [0] [ref [num]) {dist [0] [ref [num] = m. get (num) + dist [0] [flag + 1]; minUp (ref [num]) ;}}for (int I = 2; I <nodeCount + 1; I ++) {System. out. println (dist [0] [ref [I]);} /*** maximum sinking ** @ param index * @ param end */private static void maxDown (int index, int end) {int temp = dist [0] [index]; int left = index * 2-1; while (left <= end) {// determine the size of left and right subnodes if (left + 1 <= end & dist [0] [left + 1] <dist [0] [left]) {left ++;} // if the left and right subnodes are larger than temp, end the Sinking Operation if (dist [0] [left]> temp) {break ;} // swap subnode and parent node changeKey (index, left); index = left; left = index * 2-1 ;}} /*** small value increase ** @ param n */private static void minUp (int n) {int f = (n + 1)/2; while (f> = 2 & dist [0] [f]> dist [0] [n]) {changeKey (f, n); n = f; f = (n + 1)/2 ;}/ *** exchange two values ** @ param a * @ param B */private static void changeKey (int, int B) {int n = dist [1] [a]; int m = dist [1] [B]; int temp = ref [n]; ref [n] = ref [m]; ref [m] = temp; temp = dist [0] [a]; dist [0] [a] = dist [0] [B]; dist [0] [B] = temp; temp = dist [1] [a]; dist [1] [a] = dist [1] [B]; dist [1] [B] = temp ;}}


Performance test:

For the big test data in the "Native Dijkstra": 10000 nodes and 100000 edges, the Dijkstra execution of the optimization is 250 ms on average, the average execution of the data by no optimized Dijkstra is 2200 ms, and the performance is improved by 88%. It can be seen that the performance improvement is very obvious:




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.