Understand Dijkstra (Dijkstra algorithm) and JS code implementation of the shortest path algorithm

 1. Example illustration

Example one

        There are four points ABCD in the following figure, find the shortest path from A to each point:

  • First prepare a record (record finally), which is the shortest path from the final A to each point, initially empty
  •  A is the starting point, and you can directly reach B, C, and D from A. The path from A to B is 2, the path to C is 5, and the path to D is 3. "Record 1" is as follows:
  1. A→B:2
  2. A→C:5
  3. A→D:3

        Move the shortest path A→B: 2 to "record finally", then "record finally" is A→B: 2

  • Point B can go to C: B→C: 4, from A to C can choose to transfer from B: At this time A→C: 2+4=6, 6>5, so "record 1" is not updated ( assuming B→ C: 2, at this time A→C: 2+2=4, 4<5, then update "record 1": A→C: 4 )
  • Point D can go to C: D→C: 3, from A to C, you can choose to transfer from D: At this time, A→C: 3+3=6, 6>5, so "record 1" is not updated
  • There is no reachable point at point C, end the calculation
  • Merge "Record 1" into "Record finally"
  • Finally, the shortest path from A to each point is obtained: A→B: 2, A→C: 5, A→D: 3 ( if the assumption is true, the "record finally" is A→B: 2, A→C: 4. A → D: 3)

Example two

        As shown in the figure below, find the shortest path from A to each point:

        The records of instance one are finally recorded as a set S, and the initial S only contains the starting point. Record other points except the starting point in the set U, the adjacent nodes can record the path value, and the non-adjacent nodes are recorded as ∞. Then the following figure is represented as:

        S={ A(0) },U={ B(4), C(2), D(3), E(∞), F(∞), G(∞), H(∞), I(∞) }

 first step:

  • S={ A(0) }
  • U={ B(4), C(2), D(3), E(∞), F(∞), G(∞), H(∞), I(∞) }

 Step 2: The C path is the shortest in the previous step, which is 2

  • S={ A(0), C(2) }
  • U={ B(4), D(3), E(2+3=5), F(2+2=4), G(∞), H(∞), I(∞) }

 The third step: D path is the shortest in the previous step, which is 3

  • S={ A(0), C(2), D(3) }
  • U={ B(4), E(5), F(4), G(∞), H(∞), I(3+5=8) }

 Step 4: In the previous step, the paths B and F are the shortest, which is 4

  • S={ A(0), C(2), D(3), B(4)}
  • U={ E(5), F(4), G(4+5=9), H(∞), I(8) }

 Step 5: The F path in the previous step is the shortest, which is 4

  • S={ A(0), C(2), D(3), B(4), F(4) }
  • U={ E(5), G(9), H(4+2=6), I(8) }

 Step 6: The E path in the previous step is the shortest, which is 5

  • S={ A(0), C(2), D(3), B(4), F(4), E(5) }
  • U={ G(5+3=8), H(6), I(8) }

 Step 7: The H path in the previous step is the shortest, which is 6

  • S={ A(0), C(2), D(3), B(4), F(4), E(5), H(6) }
  • U={ G(6+1=7), I(8) }

 Step 8: The G path in the previous step is the shortest, which is 7

  • S={ A(0), C(2), D(3), B(4), F(4), E(5), H(6), G(7) }
  • U={ I(8) }

 Step 9: The I path in the previous step is the shortest, which is 8

  • S={ A(0), C(2), D(3), B(4), F(4), E(5), H(6), G(7),  I(8) }
  • U={ }

So far, the shortest path from A to each point has been obtained.

Two, JS code implementation

Take instance two as an example:

  • First define a graph array, which records the distance to each point, for example:
  1. A→A distance is 0, A→B distance is 4, A→C distance is 2, A→D distance is 3, A→E is not adjacent, so the distance is zero...
  2. B→A is irreversible, so the distance is zero, B→B distance is 0, B→C distance is 1, B→D is not adjacent, so the distance is zero...

        and so on

let graph = [
    [0,4,2,3,0,0,0,0,0],
    [0,0,1,0,0,0,5,0,0],
    [0,0,0,0,3,2,0,0,0],
    [0,0,1,0,0,1,0,0,5],
    [0,0,0,0,0,0,3,2,0],
    [0,0,0,0,1,0,0,2,0],
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,1,0,0],
    [0,0,0,0,0,0,0,1,0]
]
  • Define a currentMinPth array, which records the currently known shortest path, and the initial value is infinity; define a visited array, records whether it has been visited, and the next cycle that has been visited will not visit
    let currentMinPth = [];
    let visited = [];
    for(let i = 0; i < graph.length;i++){
        currentMinPth.push(INF);
        visited.push(false);
    }
  • The starting point is A, A→A is 0, so currentMinPth[0] is 0
  • Find the nearest node from the currently known nodes, and return the index value minIndex (starting from the shortest path each time)
function getMinIndex(currentMinPth,visited){
    let min = INF;
    let minIndex = -1;
    for(let i = 0; i < currentMinPth.length;i++){
        if(!visited[i]&&currentMinPth[i]<min){
            min = currentMinPth[i];
            minIndex = i;
        }
    }
    return minIndex
}
  • Set the closest node that has been obtained as visited:
visited[minIndex] = true;
  • Find the adjacent node, that is, the node where graph[minIndex][i] !== 0, and update the path value to the adjacent node to currentMinPth, but only if this value is smaller than the current value:
if(!visited[i]&&
   graph[minIndex][i] !== 0 && 
   currentMinPth[minIndex] + graph[minIndex][i] < currentMinPth[i]){
   currentMinPth[i] = currentMinPth[minIndex] + graph[minIndex][i];
}
  • Repeat the above process for each item of currentMinPth, length - 1 is enough, there is no need to check when there is only the last one left, the complete code is as follows:
let graph = [
    [0,4,2,3,0,0,0,0,0],
    [0,0,1,0,0,0,5,0,0],
    [0,0,0,0,3,2,0,0,0],
    [0,0,1,0,0,1,0,0,5],
    [0,0,0,0,0,0,3,2,0],
    [0,0,0,0,1,0,0,2,0],
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,1,0,0],
    [0,0,0,0,0,0,0,1,0]
]
let INF = Number.MAX_SAFE_INTEGER;
function handlePath(){
    let currentMinPth = [];
    let visited = [];
    for(let i = 0; i < graph.length;i++){
        currentMinPth.push(INF);
        visited.push(false);
    }
    currentMinPth[0] = 0
    for(let j = 0; j < currentMinPth.length - 1;j++){
        let minIndex = getMinIndex(currentMinPth,visited);
        visited[minIndex] = true;
        for(let i = 0; i < currentMinPth.length;i++){
            if(!visited[i]&&
               graph[minIndex][i] !== 0 && 
               currentMinPth[minIndex] + graph[minIndex][i] < currentMinPth[i]){
               currentMinPth[i] = currentMinPth[minIndex] + graph[minIndex][i];
            }
        }
    }
    
    return currentMinPth
}
function getMinIndex(currentMinPth,visited){
    let min = INF;
    let minIndex = -1;
    for(let i = 0; i < currentMinPth.length;i++){
        if(!visited[i]&&currentMinPth[i]<min){
            min = currentMinPth[i];
            minIndex = i;
        }
    }
    return minIndex
}
console.log(handlePath())

Summarize

        This article records the simple understanding of Dijkstra's shortest path principle and the code implementation of js. If there is any error, please correct me!

Guess you like

Origin blog.csdn.net/sxww_zyt/article/details/129835779