|
17 | 17 | import numpy as np
|
18 | 18 |
|
19 | 19 |
|
| 20 | +def pass_and_relaxation( |
| 21 | + graph: dict, |
| 22 | + v: str, |
| 23 | + visited_forward: set, |
| 24 | + visited_backward: set, |
| 25 | + cst_fwd: dict, |
| 26 | + cst_bwd: dict, |
| 27 | + queue: PriorityQueue, |
| 28 | + parent: dict, |
| 29 | + shortest_distance: float | int, |
| 30 | +) -> float | int: |
| 31 | + for nxt, d in graph[v]: |
| 32 | + if nxt in visited_forward: |
| 33 | + continue |
| 34 | + old_cost_f = cst_fwd.get(nxt, np.inf) |
| 35 | + new_cost_f = cst_fwd[v] + d |
| 36 | + if new_cost_f < old_cost_f: |
| 37 | + queue.put((new_cost_f, nxt)) |
| 38 | + cst_fwd[nxt] = new_cost_f |
| 39 | + parent[nxt] = v |
| 40 | + if nxt in visited_backward: |
| 41 | + if cst_fwd[v] + d + cst_bwd[nxt] < shortest_distance: |
| 42 | + shortest_distance = cst_fwd[v] + d + cst_bwd[nxt] |
| 43 | + return shortest_distance |
| 44 | + |
| 45 | + |
20 | 46 | def bidirectional_dij(
|
21 | 47 | source: str, destination: str, graph_forward: dict, graph_backward: dict
|
22 | 48 | ) -> int:
|
@@ -51,53 +77,36 @@ def bidirectional_dij(
|
51 | 77 | if source == destination:
|
52 | 78 | return 0
|
53 | 79 |
|
54 |
| - while queue_forward and queue_backward: |
55 |
| - while not queue_forward.empty(): |
56 |
| - _, v_fwd = queue_forward.get() |
57 |
| - |
58 |
| - if v_fwd not in visited_forward: |
59 |
| - break |
60 |
| - else: |
61 |
| - break |
| 80 | + while not queue_forward.empty() and not queue_backward.empty(): |
| 81 | + _, v_fwd = queue_forward.get() |
62 | 82 | visited_forward.add(v_fwd)
|
63 | 83 |
|
64 |
| - while not queue_backward.empty(): |
65 |
| - _, v_bwd = queue_backward.get() |
66 |
| - |
67 |
| - if v_bwd not in visited_backward: |
68 |
| - break |
69 |
| - else: |
70 |
| - break |
| 84 | + _, v_bwd = queue_backward.get() |
71 | 85 | visited_backward.add(v_bwd)
|
72 | 86 |
|
73 |
| - # forward pass and relaxation |
74 |
| - for nxt_fwd, d_forward in graph_forward[v_fwd]: |
75 |
| - if nxt_fwd in visited_forward: |
76 |
| - continue |
77 |
| - old_cost_f = cst_fwd.get(nxt_fwd, np.inf) |
78 |
| - new_cost_f = cst_fwd[v_fwd] + d_forward |
79 |
| - if new_cost_f < old_cost_f: |
80 |
| - queue_forward.put((new_cost_f, nxt_fwd)) |
81 |
| - cst_fwd[nxt_fwd] = new_cost_f |
82 |
| - parent_forward[nxt_fwd] = v_fwd |
83 |
| - if nxt_fwd in visited_backward: |
84 |
| - if cst_fwd[v_fwd] + d_forward + cst_bwd[nxt_fwd] < shortest_distance: |
85 |
| - shortest_distance = cst_fwd[v_fwd] + d_forward + cst_bwd[nxt_fwd] |
86 |
| - |
87 |
| - # backward pass and relaxation |
88 |
| - for nxt_bwd, d_backward in graph_backward[v_bwd]: |
89 |
| - if nxt_bwd in visited_backward: |
90 |
| - continue |
91 |
| - old_cost_b = cst_bwd.get(nxt_bwd, np.inf) |
92 |
| - new_cost_b = cst_bwd[v_bwd] + d_backward |
93 |
| - if new_cost_b < old_cost_b: |
94 |
| - queue_backward.put((new_cost_b, nxt_bwd)) |
95 |
| - cst_bwd[nxt_bwd] = new_cost_b |
96 |
| - parent_backward[nxt_bwd] = v_bwd |
97 |
| - |
98 |
| - if nxt_bwd in visited_forward: |
99 |
| - if cst_bwd[v_bwd] + d_backward + cst_fwd[nxt_bwd] < shortest_distance: |
100 |
| - shortest_distance = cst_bwd[v_bwd] + d_backward + cst_fwd[nxt_bwd] |
| 87 | + shortest_distance = pass_and_relaxation( |
| 88 | + graph_forward, |
| 89 | + v_fwd, |
| 90 | + visited_forward, |
| 91 | + visited_backward, |
| 92 | + cst_fwd, |
| 93 | + cst_bwd, |
| 94 | + queue_forward, |
| 95 | + parent_forward, |
| 96 | + shortest_distance, |
| 97 | + ) |
| 98 | + |
| 99 | + shortest_distance = pass_and_relaxation( |
| 100 | + graph_backward, |
| 101 | + v_bwd, |
| 102 | + visited_backward, |
| 103 | + visited_forward, |
| 104 | + cst_bwd, |
| 105 | + cst_fwd, |
| 106 | + queue_backward, |
| 107 | + parent_backward, |
| 108 | + shortest_distance, |
| 109 | + ) |
101 | 110 |
|
102 | 111 | if cst_fwd[v_fwd] + cst_bwd[v_bwd] >= shortest_distance:
|
103 | 112 | break
|
|
0 commit comments