Graph ๊ธ ์ฐธ๊ณ ํ๊ธฐ
Queue ๊ธ ์ฐธ๊ณ ํ๊ธฐ
SPFA(Shortest Path Faster Algorithm)
The Shortest Path Faster Algorithm (SPFA)๋ BellmanโFord algorithm ์ ๊ฐ์ ํ ์๊ณ ๋ฆฌ์ฆ ์ผ๋ก์, ๋ฐฉํฅ ๊ฐ์ค์น ๊ทธ๋ํ์์ ๋จ์ผ ์ถ๋ฐ ์ ์ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ(Single source shortest path distance) ๊ณ์ฐํ๋ค. ๋ค๋ฅธ ์ฌํ BellmanโFord algorithm ์ด๋ Dijkstraโs algorithm ๊ณผ ๊ฐ์ Single source shortest path algorithm ์ฒ๋ผ SPFA๋ ๋ณ ๊ฒฝ๊ฐ(Edge relaxation)์ ํต์ฌ ์ฐ์ฐ์ผ๋ก ํ์ฌ ๋์ํ๋ค.
์ด SPFA๋ ๋ฌด์์ ํฌ์ ๊ทธ๋ํ์์ ์ ๋์ํ๋ค๊ณ ์๋ ค์ ธ ์๊ณ , ์์ ๊ฐ์ค์น ๊ฐ์ (Nagative weighted edge)์ ๊ฐ์ง ๊ทธ๋ํ์์๋ ์ ํฉํ๋ค. ๊ทธ๋ฌ๋ ์ต์ ์๊ฐ๋ณต์ก๋๋ $O(|V|\cdot|E|)$ ๋ก์ BellmanโFord algorithm๊ณผ ๊ฐ๊ธฐ ๋๋ฌธ์, ์์ ๊ฐ์ค์น ๊ฐ์ ์ด ์๋ ๊ทธ๋ํ์ ๊ฒฝ์ฐ์๋ ์ต์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ณ ๋ คํ๋ค๋ฉด Dijkstraโs algorithm์ด ๋ ์ ํฉํ๋ค๊ณ ๋ณผ ์ ์๋ค.
Algorithm
๋ฐฉํฅ ๊ฐ์ค์น ๊ทธ๋ํ๊ฐ ์ฃผ์ด์ง๊ณ $G = (V, E)$ ๊ทธ๋ฆฌ๊ณ ์ถ๋ฐ ์ ์ ์ $s$๋ผ๊ณ ํ์. SPFA๋ ์ถ๋ฐ ์ ์ $s$์ผ๋ก๋ถํฐ ๋ค๋ฅธ ๋ชจ๋ ์ ์ $v$๋ก์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ๋๋ค. $s$๋ก ๋ถํฐ $v$๋ก์ ์ต๋จ ๊ฒฝ๋ก ๊ฑฐ๋ฆฌ๋ ๊ฐ ์ ์ $v$์ ๋ํ์ฌ $d(v)$์ ์ ์ฅ๋๋ค.
SPFA๋ ๊ฐ ์ ์ ์ ์ธ์ ์ ์ ์ ํ์ํ๋ค๋ฉด ๋ณ ๊ฒฝ๊ฐ(Edge relaxation)ํ๊ธฐ ์ํด ๊ฐ ์ ์ ์ ํ๋ณด์๋ก ์ฌ์ฉํ๋ค. ์ด ์ ์ BellmanโFord algorithm๊ณผ ๊ฐ๋ค. ํ์ง๋ง BellmanโFord algorithm๊ณผ ๋น๊ตํ์ ๋์ ๊ฐ์ ์ ์ ๋ชจ๋ ์ ์ ๋ค์ ๋ฌด์กฐ๊ฑด ์ ์ผ๋ก ์ฐ์ฐ์ ์๋ํ๊ธฐ ๋ณด๋ค๋ SPFA๋ ํ๋ณด์ ์ ์ ์ ๋ํ Queue๋ฅผ ๊ฐ์ง๊ณ , ์ด๋ค ์ ์ ์ ๋ํด ๊ทธ ์ ์ ์ด ๋ณ ๊ฒฝ๊ฐ ์ฐ์ฐ์ด ์ด๋ฃจ์ด์ก์ ๋๋ง ํ๋ณด์ ์ ์ ์ผ๋ก์ Queue์ ์ฝ์ ์ ํ๋ค. ์ด๋ฐ ํ๋๋ค์ ๋ณ ๊ฒฝ๊ฐ ์ฐ์ฐ์ด ์คํ๋ ์ ์ ์ด ์์ ๋๊น์ง ๋ฐ๋ณต๋๋ค.
๋ค์์ SPFA์ ์์ฌ์ฝ๋์ด๋ค.
Input: ๊ทธ๋ํ G, ์์ ์ ์ s
$Q$๋ ๋ณ ๊ฒฝ๊ฐ ์ฐ์ฐ์ด ๋๊ณ ๋ ํ์ ํ๋ณด์๋ฅผ ๋ด์ Queue๋ฅผ ์๋ฏธํ๋ค.
$w(u,v)$๋ ๊ฐ์ $(u,v)$์ ๊ฐ์ ๊ฐ์ค์น๋ฅผ ์๋ฏธํ๋ค.
Notice: Q ์์ v์ ์กด์ฌ ์ ๋ฌด๋ฅผ ํ๋จํ๊ธฐ ์ํด ๊ตฌํ ์์๋ ์ด๋ฅผ ์ถ์ ํ๊ธฐ ์ํ ์ถ๊ฐ์ ์ธ ์๋ฃ๊ตฌ์กฐ๊ฐ ์๊ตฌ๋๋ค.
0 procedure Shortest-Path-Faster-Algorithm(G, s)
1 for each vertex v โ s in V(G)
2 d(v) := โ
3 d(s) := 0
4 offer s into Q
5 while Q is not empty
6 u := poll Q
7 for each edge (u, v) in E(G)
8 if d(u) + w(u, v) < d(v) then
9 d(v) := d(u) + w(u, v)
10 if v is not in Q then
11 offer v into Q
ํ๋์ฉ ๋ณด์.
1 for each vertex v โ s in V(G)
2 d(v) := โ
๊ทธ๋ํ G์ ์ถ๋ฐ ์ ์ s๋ฅผ ์ ์ธํ ๋ชจ๋ ์ ์ v์ ๋ํ์ฌ s๋ก๋ถํฐ ๊ฐ v์ ๋ํ ์ต๋จ๊ฒฝ๋ก ๊ฑฐ๋ฆฌ d(v)๋ฅผ INF๋ก ์ด๊ธฐํ ํ๋ค.
3 d(s) := 0
4 offer s into Q
๋จผ์ ์ถ๋ฐ ์ ์ s์ ์ต๋จ๊ฒฝ๋ก ๊ฑฐ๋ฆฌ๋ฅผ 0์ผ๋ก ์ด๊ธฐํํ๊ณ s๋ฅผ Q์ ๋ฃ๋๋ค.
5 while Q is not empty
ํ๊ฐ ๋น ๋ ๊น์ง ์๋ ์ฐ์ฐ๋ค์ ๋ฐ๋ณตํ๋ค.
6 u := poll Q
7 for each edge (u, v) in E(G)
Q์์ ์ ์ ํ๋๋ฅผ ๊บผ๋ด u๋ผ ํ๊ณ , ๊ทธ๋ํ G์์ u์ ์ธ์ ํ ์ ์ v์์ ๊ฐ์ (u, v)์ ๋ํ์ฌ
8 if d(u) + w(u, v) < d(v) then
9 d(v) := d(u) + w(u, v)
s๋ก๋ถํฐ u๋ก์ ์ต๋จ๊ฒฝ๋ก ๊ฑฐ๋ฆฌ d(u) + ๊ฐ์ (u, v)์ ๊ฐ์ด s๋ก๋ถํฐ v๋ก์ ์ต๋จ๊ฒฝ๋ก ๊ฑฐ๋ฆฌ d(v)๋ณด๋ค ์๋ค๋ฉด d(v)๊ฐ์ d(u) + w(u, v)๋ก ์ ๋ฐ์ดํธ ํ๋ค. (Edge Relaxation)
10 if v is not in Q then
11 offer v into Q
๋ณ ๊ฒฝ๊ฐ ์ฐ์ฐ(Edge Relaxation)์ด ๋ ์ ์ v๊ฐ ํ์ฌ Q์ ์์ผ๋ฉด, v๋ฅผ Q์ ์ถ๊ฐํ๋ค.
Step by step
์ค์ ๊ทธ๋ํ๋ฅผ ์๋ก ๋ค์ด SPFA๊ฐ ์ด๋ป๊ฒ ๋์ํ๋์ง ์์๋ณด์.
0๋ฒ์ ์์ ์ ์ ์ผ๋ก ํ์ฌ 5๋ฒ ์ ์ ์ผ๋ก์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ๊ตฌํ๋ค.
ํด๋น ์ ์ ์ ์ฐ๊ฒฐ๋ ์ธ์ ์ ์ ์ด ์ฌ๋ฌ๊ฐ ์ผ ๋, ๋ฒํธ๊ฐ ์์ ๊ฒ์ ๋จผ์ ์ ํํ๋ค.
์์ ์ ์ ์ผ๋ก ๋ถํฐ ๋ชจ๋ ์ ์ ๊น์ง์ ์ต๋จ๊ฑฐ๋ฆฌ d(v)๋ฅผ ๋ฌดํ๋(INF)๋ก ์ด๊ธฐํ ํ๋ค.
d(s)๋ 0์ผ๋ก ์ด๊ธฐํ ํ๋ค.
Queue์ ์์ ์ ์ 0์ ๋ฃ๋๋ค.
Queue : [0]
Queue์์ ์์ ํ๋๋ฅผ popํ๋ค.
0๋ฒ ์ ์ ๊ณผ ์ธ์ ํ ์ ์ 1๋ฒ์ ๋ํ์ฌ d(0) + w(0, 1) < d(1): 0 + 4 < INF
์ด๋ฏ๋ก
d(1)์ 4๋ก ์
๋ฐ์ดํธ ํ๋ค.
์
๋ฐ์ดํธ ๋์์ผ๋ฏ๋ก 1๋ฒ ์ ์ ์ Queue์ ๋ฃ๋๋ค.
Queue : [1]
0๋ฒ ์ ์ ๊ณผ ์ธ์ ํ ์ ์ 2๋ฒ์ ๋ํ์ฌ d(0) + w(0, 2) < d(1): 0 + 2 < INF
์ด๋ฏ๋ก
d(2)์ 2๋ก ์
๋ฐ์ดํธ ํ๋ค.
์
๋ฐ์ดํธ ๋์์ผ๋ฏ๋ก 2๋ฒ ์ ์ ์ Queue์ ๋ฃ๋๋ค.
Queue : [1 2]
Queue์์ ์์ ํ๋๋ฅผ popํ๋ค.
1๋ฒ ์ ์ ๊ณผ ์ธ์ ํ ์ ์ 2๋ฒ์ ๋ํ์ฌ d(1) + w(1, 2) < d(2): 4 + 5 > 2
์ด๋ฏ๋ก
d(2)๋ฅผ ์
๋ฐ์ดํธ ํ์ง ์๋๋ค.
Queue : [2]
1๋ฒ ์ ์ ๊ณผ ์ธ์ ํ ์ ์ 3๋ฒ์ ๋ํ์ฌ d(1) + w(1, 3) < d(3): 4 + 10 < INF
์ด๋ฏ๋ก
d(3)์ 14๋ก ์
๋ฐ์ดํธ ํ๋ค.
์
๋ฐ์ดํธ ๋์์ผ๋ฏ๋ก 3๋ฒ ์ ์ ์ Queue์ ๋ฃ๋๋ค.
Queue : [2, 3]
Queue์์ ์์ ํ๋๋ฅผ popํ๋ค.
2๋ฒ ์ ์ ๊ณผ ์ธ์ ํ ์ ์ 4๋ฒ์ ๋ํ์ฌ d(2) + w(2, 4) < d(4): 2 + 3 < INF
์ด๋ฏ๋ก
d(4)์ 5๋ก ์
๋ฐ์ดํธ ํ๋ค.
์
๋ฐ์ดํธ ๋์์ผ๋ฏ๋ก 4๋ฒ ์ ์ ์ Queue์ ๋ฃ๋๋ค.
Queue : [3, 4]
Queue์์ ์์ ํ๋๋ฅผ popํ๋ค.
3๋ฒ ์ ์ ๊ณผ ์ธ์ ํ ์ ์ 5๋ฒ์ ๋ํ์ฌ d(3) + w(3, 5) < d(5): 14 + 11 < INF
์ด๋ฏ๋ก
d(5)์ 25๋ก ์
๋ฐ์ดํธ ํ๋ค.
์
๋ฐ์ดํธ ๋์์ผ๋ฏ๋ก 5๋ฒ ์ ์ ์ Queue์ ๋ฃ๋๋ค.
Queue : [4, 5]
Queue์์ ์์ ํ๋๋ฅผ popํ๋ค.
4๋ฒ ์ ์ ๊ณผ ์ธ์ ํ ์ ์ 3๋ฒ์ ๋ํ์ฌ d(4) + w(4, 3) < d(3): 5 + 4 < 14
์ด๋ฏ๋ก
d(3)์ 9๋ก ์
๋ฐ์ดํธ ํ๋ค.
์
๋ฐ์ดํธ ๋์์ผ๋ฏ๋ก 3๋ฒ ์ ์ ์ Queue์ ๋ฃ๋๋ค.
Queue : [5, 3]
Queue์์ ์์ ํ๋๋ฅผ popํ๋ค.
5๋ฒ ์ ์ ๊ณผ ์ธ์ ํ ์ ์ ์ด ์๋ค.
Queue : [3]
Queue์์ ์์ ํ๋๋ฅผ popํ๋ค.
3๋ฒ ์ ์ ๊ณผ ์ธ์ ํ ์ ์ 5๋ฒ์ ๋ํ์ฌ d(3) + w(3, 5) < d(5): 9 + 11 < 25
์ด๋ฏ๋ก
d(5)์ 20๋ก ์
๋ฐ์ดํธ ํ๋ค.
์
๋ฐ์ดํธ ๋์์ผ๋ฏ๋ก 5๋ฒ ์ ์ ์ Queue์ ๋ฃ๋๋ค.
Queue : [5]
Queue์์ ์์ ํ๋๋ฅผ popํ๋ค.
5๋ฒ ์ ์ ๊ณผ ์ธ์ ํ ์ ์ ์ด ์๋ค.
Queue : [ ]
ํ๊ฐ ๋น์์ผ๋ฏ๋ก SPFA๊ฐ ์๋ฃ๋์๋ค.
0๋ฒ ๋ถํฐ 5๋ฒ์ผ๋ก์ ์ต๋จ๊ฒฝ๋ก๋ ๋นจ๊ฐ์ ์ ๋ฐ๋ผ๊ฐ ๊ฒฝ๋ก์ด๊ณ ๊ทธ ๊ฑฐ๋ฆฌ๋ 20์ด๋ค.
Implementation
๋ค์์ ์ ์์ฌ์ฝ๋๋ฅผ ๋ฐํ์ผ๋ก SPFA๋ฅผ ๊ตฌํํ ์๋ฐ ๋ฉ์๋์ด๋ค.
static void shortestPathFasterAlgorithm(int s){
dist = new int[n];
onQueue = new boolean[n];
Arrays.fill(dist, INF);
Queue<Integer> queue = new LinkedList<>();
queue.offer(s);
dist[s] = 0;
onQueue[s] = true;
while (!queue.isEmpty()){
int cur = queue.poll();
onQueue[cur] = false;
for (Edge e : graph[cur]){
if (dist[cur] + e.cost < dist[e.to]){
dist[e.to] = dist[cur] + e.cost; // Edge Relaxation
}
}
}
}
ํ์ฌ Queue์์ ์ ์ $v$์ ์กด์ฌ ์ ๋ฌด๋ฅผ ์ถ์ ํ๊ธฐ ์ํด ์ ์ฝ๋์์๋ onQueue[]
๋ฅผ ์ฌ์ฉํ๋ค.
๊ทธ๋ํ์ ๊ฐ์ค์น ๊ฐ์ ์ ๋ณด๋ฅผ ๊ตฌ์ฑํ๊ธฐ ์ํด ์๋์ Edge ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ค.
to
๋ ๋ค์ ์ธ์ ์ ์ ์ ๋ฒํธ, cost๋ ๊ฐ์ ๋น์ฉ(๊ฐ์ค์น)๋ฅผ ๋ํ๋ธ๋ค.
...
// static ArrayList<Edge> [] graph;
...
static class Edge{
int to;
int cost;
// Constructor
public Edge(int to, int cost) {
this.to = to;
this.cost = cost;
}
}
๋ค์์ SPFA๋ฅผ ๊ตฌํํ ์๋ฐ ์ฝ๋์ด๋ค.
๊ทธ๋ํ์ ์
๋ ฅ์ ์์ ๊ทธ๋ํ๋ฅผ ์ฌ์ฉํ์๊ณ , ์ต๋จ๊ฒฝ๋ก๋ฅผ ์ถ์ ํ๊ณ ๊ตฌ์ฑํ๊ธฐ ์ํด pred[]๋ฐฐ์ด์ ์ ์ธํ ๋ค SPFA์ ์คํ ์ค์ ์ด๋ ํ ํฌ์ธํธ์์ ์ ์ u, v๊ฐ ์๊ณ (์ ์ v๊ฐ u์ ์ํด relaxation ๋์ด์ง๋ ์ ์ ), relaxation ๋์ด์ง ์ ์ v๊ฐ ์์ผ๋ฉด, ๊ทธ ์ ์ ์ relaxationํ๊ฒ ๋ง๋ ์ ์ u๊ฐ ์ต๋จ๊ฒฝ๋ก ์์ ์ด์ ๋
ธ๋ ์ด๋ฏ๋ก pred[e.to] = cur;
๋ฅผ ํ์ฌ ๊ฒฝ๋ก๋ฅผ ๊ตฌ์ถํ๋ค. ๊ทธ ๋ค์ printPathReconstruction
ํจ์๋ก ๊ฒฝ๋ก๋ฅผ ์ถ๋ ฅํ๋ค.
์ด ํ๋ก๊ทธ๋จ์ ์ต๋จ๊ฒฝ๋ก ๊ฑฐ๋ฆฌ์ ๊ทธ ๊ฒฝ๋ก๋ฅผ ์ถ๋ ฅํ๋ค.
- Input: Graph G, start vertex
- Output: Distance of shortest path of Graph G, shortest path of Graph G
์์ ์ ์ ์ 0๋ฒ์ด๋ค.
import java.io.*;
import java.util.*;
import java.util.LinkedList;
/**
* This program is to find Shortest path in weighted graph using SPFA.
* Time Complexity : Worst case : O(VE) same as Standard Bellman ford
* Average case : O(E) - not proved
*
* @author Lemidia(Gyeong)
*/
public class ShortestPathFasterAlgorithm{
// the number of vertices in Graph G
static int n;
// Shortest distance from s to each vertex v
static int dist[];
// for construct shortest path
static int pred[];
static ArrayList<Edge> [] graph;
static final int INF = Integer.MAX_VALUE;
// For check whether the vertex is on queue or not
static boolean onQueue[];
// Init Graph G
static void createGraph(){
graph = new ArrayList[n];
for (int i = 0; i < n; i++){
graph[i] = new ArrayList<>();
}
}
// Add weighted direct edges.
static void addEdge(int from, int to, int cost){
Edge e = new Edge(to, cost);
graph[from].add(e);
}
static void shortestPathFasterAlgorithm(int s){
dist = new int[n];
pred = new int[n];
onQueue = new boolean[n];
Arrays.fill(dist, INF);
Queue<Integer> queue = new LinkedList<>();
queue.offer(s);
dist[s] = 0;
onQueue[s] = true;
while (!queue.isEmpty()){
int cur = queue.poll();
onQueue[cur] = false;
for (Edge e : graph[cur]){
if (dist[cur] + e.cost < dist[e.to]){
dist[e.to] = dist[cur] + e.cost; // Edge Relaxation
pred[e.to] = cur; // store previous node
if (onQueue[e.to] == false){ // Node(e.to) is not in the queue
onQueue[e.to] = true;
queue.offer(e.to);
}
}
}
}
}
static void printPathReconstruction(int start, int end){
if (end == start) {
System.out.print(start);
return;
}
pathReconstruction(start, pred[end]);
System.out.print(" -> " + end );
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = 6;
int start = 0;
createGraph();
addEdge(0, 1, 4);
addEdge(0, 2, 2);
addEdge(1, 2, 5);
addEdge(1, 3, 10);
addEdge(2, 4, 3);
addEdge(3, 5, 11);
addEdge(4, 3, 4);
shortestPathFasterAlgorithm(start);
System.out.println("Shortest path distance : " + dist[5]);
System.out.print("Shortest path : ");
printPathReconstruction(start, 5);
}
static class Edge{
int to;
int cost;
public Edge(int to, int cost) {
this.to = to;
this.cost = cost;
}
}
}
Output:
Shortest path distance : 20
Shortest path : 0 -> 2 -> 4 -> 3 -> 5
Optimization techniques
Small Label First (SLF) technique.
๋ณ ๊ฒฝ๊ฐ(Edge relaxation) ๋์ด์ง ์ ์ $v$๋ฅผ ํญ์ Queue ๋ค์ ์ถ๊ฐํ์์ง๋ง ์ด technique์์๋ ๊ทธ ์ถ๊ฐ๋์ด์ง ์ ์ $v$์ $d(v)$์ Queue์ ๋งจ ์ ์ ์ ์ ๊ฑฐ๋ฆฌ $d(front(Q))$๋ฅผ ๋น๊ตํ๊ณ $d(v)$๊ฐ ๋ ์๋ค๋ฉด $d(v)$๋ฅผ Queue์ ๋งจ ์์ผ๋ก ๋ณด๋ธ๋ค. ์ด technique์ front์ ์์ ์ถ๊ฐ๋ฅผ ์๊ตฌํ๋ฏ๋ก front์ rear ์ ๋ถ pop(), offer()์ฐ์ฐ์ ์ง์ํ๋ Deque(๋ฐํฌ) ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ๊ตฌํํ ์ ์๋ค.
์ SPFA ์๋ฐ ๋ฉ์๋์์ Queue<Integer> queue = new LinkedList<>();
๋ฅผ Deque<Integer> queue = new LinkedList<>();
๋ก ํ์ฌ Deque๋ฅผ ์ฌ์ฉํ๋ค.
๋ค์์ ์ด technique์ ์์ฌ์ฝ๋์ด๋ค.
procedure Small-Label-First(G, Q)
if d(back(Q)) < d(front(Q)) then
u := pop back of Q
push u into front of Q
๋ค์์ SPFA์ ์ ์ต์ ํ๋ฅผ ์ ์ฉํ ์ฝ๋์ด๋ค.
static void shortestPathFasterAlgorithm(int s){
dist = new int[n];
pred = new int[n];
onQueue = new boolean[n];
Arrays.fill(dist, INF);
Deque<Integer> queue = new LinkedList<>();
queue.offer(s);
dist[s] = 0;
onQueue[s] = true;
while (!queue.isEmpty()){
int cur = queue.poll();
onQueue[cur] = false;
for (Edge e : graph[cur]){
if (dist[cur] + e.cost < dist[e.to]){
dist[e.to] = dist[cur] + e.cost; // Edge Relaxation
pred[e.to] = cur; // store previous node
if (onQueue[e.to] == false){ // Node(e.to) is not in the queue
onQueue[e.to] = true;
queue.offer(e.to);
// Optimization <Small Label First>
if (dist[e.to] < dist[queue.peekFirst()]){
queue.offerFirst(queue.pollLast());
}
}
}
}
}
}
Large Label Last (LLL) technique.
Queue์ front ์์์ ๊ฐ์ด ํ์ฌ Queue์ ๋ค์ด์๋ ๋ชจ๋ ์ ์ ์ ํ๊ท ๋ณด๋ค ์๊ฒ ํ๊ธฐ ์ํด, Queue์ ๋ค์ด์๋ ๋ชจ๋ ์ ์ $v$์ ํ๊ท ์ ๊ตฌํ๊ณ , Queue ์์์ ๋ถํฐ ํ๊ท ๋ณด๋ค ํฐ ๊ฐ์ ๊ฐ์ง ์ ์ $v$๋ค์ Queue์ ๋งจ ๋ค๋ก ๋ณด๋ด๋ ์ฐ์ฐ์ด๋ค. ํ๊ท ๋ณด๋ค ์์ ๊ฐ์ ๊ฐ์ง ์ ์ $v$๊ฐ ๋์ค๋ฉด loop๋ฅผ ๋น ์ ธ๋์จ๋ค.
๋ค์์ ์ด technique์ ์์ฌ์ฝ๋์ด๋ค.
procedure Large-Label-Last(G, Q)
x := average of d(v) for all v in Q
while d(front(Q)) > x
u := pop front of Q
push u to back of Q
Running time
The worst-case running time : $O(|V|\cdot|E|)$
SPFA์ ์ต์ ์คํ ์๊ฐ์ standard Bellman-Ford algorithm๊ณผ ๊ฐ์ $O(|V|\cdot|E|)$ ์ด๋ค.
The average running time : $O(|E|)$
์คํ์ผ๋ก ๋ณด์ฌ์ง๋ SPFA์ ํ๊ท ์คํ ์๊ฐ์ $O(|E|)$ ์์ค์ด๋ค. ๊ทธ๋ฌ๋ ํ๊ท ์คํ ์๊ฐ์ ์์ง ์ฆ๋ช ๋์ง ์์๋ค.
Leave a comment