algorithms-shortest-path.md
π‘Shortest Path : Bellman-Ford & Dijkstra (feat. μκ° λ³΅μ‘λ, Bellman-Ford μμ )
BFS is not enough : Real edges has weights
- λ λ Έλ μ¬μ΄μ κ°μ₯ 짧μ 거리λ₯Ό ꡬνλ λ°©λ²μλ BFS, Bellman-Ford λ²¨λ§ ν¬λ, Dijkstra λ€μ΅μ€νΈλΌ μκ³ λ¦¬μ¦μ΄ μμ΅λλ€.
0. BFS, Breath First Search
- μ΅λ¨ 거리 μ°μ νμ
- edgeμ κ°μ€μΉλ₯Ό κ³μ°ν μ μμ
1. Bellman-Ford algorithm
- μμλ₯Ό μ²λ¦¬ν μ μμ
2. Dijkstra
- λ²¨λ§ ν¬λλ³΄λ€ λΉ λ¦
- μμλ₯Ό μ²λ¦¬ν μ μμ
| μκ³ λ¦¬μ¦ | μ΅λ¨ κ²½λ‘ νμ λ°©λ² | μμ κ°μ€μΉ μ²λ¦¬ | μκ° λ³΅μ‘λ (μ΅μ μ κ²½μ°) | | -------------------- | -------------------------- | --------------------- | ------------------------- | | Dijkstra | κ°μ₯ μμ κ°μ€μΉ μ°μ νμ | μμ κ°μ€μΉ μ²λ¦¬ λΆκ° | O((V + E) log V) | | Bellman-Ford | λͺ¨λ κ°μ μ μννλ©° νμ | μμ κ°μ€μΉ μ²λ¦¬ κ°λ₯ | O(VE) | | BFS (λλΉ μ°μ νμ) | μ΅λ¨ 거리 μ°μ νμ | μμ κ°μ€μΉ μ²λ¦¬ λΆκ° | O(V + E) |
μκ° λ³΅μ‘λ
μκ° λ³΅μ‘λλ μκ³ λ¦¬μ¦μ μ€ν μλλ₯Ό λνλ΄λ μ§νμ λλ€. μκ° λ³΅μ‘λκ° μμμλ‘ μκ³ λ¦¬μ¦μ μ€ν μλκ° λΉ λ¦ λλ€
O, n, V, Eλ?
| μ©μ΄ | μμ΄ | μ€λͺ | μ¬μ© | | ---------------------------------------------------------------------------- | ------------------------- | ------------------------------------------------------------------ | -------------------- | | O | Order | μκ³ λ¦¬μ¦μ μκ° λ³΅μ‘λλ₯Ό λνλ΄λ νκΈ°λ² | | μ€ν μκ°μ΄ μ λ ₯ ν¬κΈ°μ λν΄ μ΄λ»κ² μ¦κ°νλμ§λ₯Ό νν (μ΅μ μ κ²½μ°λ₯Ό λνλ) | μκ³ λ¦¬μ¦ μκ° λ³΅μ‘λ νκΈ° | | n | Input Size | μκ³ λ¦¬μ¦μ μ λ ₯ ν¬κΈ°λ₯Ό λνλ΄λ λ³μ | μκ³ λ¦¬μ¦μ μ λ ₯ ν¬κΈ° | | V | Vertex | κ·Έλνμμμ μ μ (Vertex)μ μ, λ Έλ λλ κΌμ§μ | κ·Έλνμ μμ | | E | Edge | κ·Έλνμμμ κ°μ (Edge)μ μ, κ·Έλνμ Vertex μ μ λ€μ μ°κ²°νλ μ | κ·Έλνμ μμ |
μκ° λ³΅μ‘λμ μμ π€
| νκΈ°λ² | μ½λ λ² | μ©μ΄ | μμ΄ λ°μ | μ€λͺ | | ---------- | ------------------------ | -------------- | ----------------- | ------------------------------------------------- | | O(1) | O of one | μμ μκ° | constant time | μ λ ₯ ν¬κΈ°μ 무κ΄ν μ€ν μκ° | | O(log n) | O of log n | λ‘κ·Έ μκ° | logarithmic time | λ‘κ·Έ λ² μ΄μ€λ‘ μ λ ₯ ν¬κΈ°μ λΉλ‘νλ μ€ν μκ° | | O(n) | O of n | μ ν μκ° | linear time | μ λ ₯ ν¬κΈ°μ μ§μ μ μΌλ‘ λΉλ‘νλ μ€ν μκ° | | O(n log n) | O of n log n | μ ν λ‘κ·Έ μκ° | linearithmic time | μ λ ₯ ν¬κΈ°μ λ‘κ·Έ λ² μ΄μ€μ κ³±μ λΉλ‘νλ μ€ν μκ° | | O(n^2) | O of n squared | μ΄μ°¨ μκ° | quadratic time | μ λ ₯ ν¬κΈ°μ μ κ³±μ λΉλ‘νλ μ€ν μκ° | | O(n^3) | O of n cubed | μΌμ°¨ μκ° | cubic time | μ λ ₯ ν¬κΈ°μ μΈμ κ³±μ λΉλ‘νλ μ€ν μκ° | | O(2^n) | O of 2 to the power of n | μ§μ μκ° | exponential time | 2μ μ λ ₯ ν¬κΈ° μ κ³±μ λΉλ‘νλ μ€ν μκ° | | O(n!) | O of n factorial | ν©ν λ¦¬μΌ μκ° | factorial time | μ λ ₯ ν¬κΈ°μ ν©ν 리μΌμ λΉλ‘νλ μ€ν μκ° |
Dijkstra vs Bellman-Ford vs BFS π₯
- Dijkstra μκ³ λ¦¬μ¦:
- μκ° λ³΅μ‘λ: O((V + E) log V)
- Dijkstra μκ³ λ¦¬μ¦μ κ°μ₯ μμ κ°μ€μΉλ₯Ό μ°μ μΌλ‘ μ ννμ¬ μ΅λ¨ κ²½λ‘λ₯Ό μ°Ύμ΅λλ€. μκ° λ³΅μ‘λ O((V + E) log V)λ μ μ μ μ Vμ κ°μ μ μ Eμ λ°λΌ μ νμ μΌλ‘ μ¦κ°ν©λλ€. μκ³ λ¦¬μ¦μ΄ μ μ μ νμνκ³ κ°μ€μΉλ₯Ό μ λ°μ΄νΈνλ κ³Όμ μμ μ°μ μμ νλ₯Ό μ¬μ©νμ¬ μ΅μκ°μ μΆμΆνκΈ° λλ¬Έμ log Vμ μκ° λ³΅μ‘λκ° μΆκ°λ©λλ€.
- Bellman-Ford μκ³ λ¦¬μ¦:
- μκ° λ³΅μ‘λ: O(VE)
- Bellman-Ford μκ³ λ¦¬μ¦μ λͺ¨λ κ°μ μ μννλ©° μ΅λ¨ κ²½λ‘λ₯Ό νμν©λλ€. μκ° λ³΅μ‘λ O(VE)λ μ μ μ μ Vμ κ°μ μ μ Eμ λΉλ‘νμ¬ μ¦κ°ν©λλ€. μκ³ λ¦¬μ¦μ΄ κ°μ μ μννλ©° μ΅λ¨ 거리λ₯Ό κ°±μ νλ κ³Όμ μ V-1λ² λ°λ³΅νκΈ° λλ¬Έμ VEμ μκ° λ³΅μ‘λκ° λ°μν©λλ€.
- BFS (λλΉ μ°μ νμ):
- μκ° λ³΅μ‘λ: O(V + E)
- BFS μκ³ λ¦¬μ¦μ μ΅λ¨ 거리 μ°μ μΌλ‘ νμνλ λ°©μμ λλ€. μκ° λ³΅μ‘λ O(V + E)λ μ μ μ μ Vμ κ°μ μ μ Eμ μ νμ μΌλ‘ μ¦κ°ν©λλ€. μκ³ λ¦¬μ¦μ΄ λλΉ μ°μ μΌλ‘ μ μ μ νμνλ κ³Όμ μμ λͺ¨λ μ μ κ³Ό κ°μ μ ν λ²μ©λ§ λ°©λ¬Ένλ―λ‘ V + Eμ μκ° λ³΅μ‘λκ° νμν©λλ€.
bellman-Ford Algorithm
-
λ²¨λ§ ν¬λ - μλ°μ€ν¬λ¦½νΈ μμ νμΈνκΈ° + μ£Όμ λ¬κΈ°
// κ·Έλνμ κ°μ μ νννλ ν΄λμ€ class Edge { constructor(source, destination, weight) { // νμ¬ κ°μ μ μΆλ° μ μ this.source = source; // νμ¬ κ°μ μ λμ°© μ μ this.destination = destination; // κ°μ€μΉ this.weight = weight; } } // λ²¨λ§ ν¬λ μκ³ λ¦¬μ¦ ν¨μ function bellmanFord(graph, start) { const numVertices = graph.length; // κ·Έλνμ κΈΈμ΄ const distances = new Array(numVertices).fill(Infinity); // μ΅λ¨ 거리λ₯Ό μ μ₯νκΈ° μν λ°°μ΄ μ΄κΈ°ν distances[start] = 0; // μμ μ μ λΆν° (μ μ μ κ°μ - 1)λ² λ°λ³΅ for (let i = 0; i < numVertices - 1; i++) { // μ΄μ€ forλ¬ΈμΌλ‘ κ·Έλνμ λͺ¨λ κ°μ μ νμ // μμ μ μ μΌλ‘λΆν° λ€λ₯Έ μ μ κΉμ§μ μ΅λ¨ 거리λ₯Ό μ°¨λ‘λλ‘ κ³μ° for (let j = 0; j < graph.length; j++) { const edge = graph[j]; const { source, destination, weight } = edge; // νμ¬ κ°μ μ μΆλ° μ μ μ κ±°μ³ λμ°© μ μ κΉμ§μ 거리λ₯Ό κ³μ°νμ¬ μ΅μκ°μΌλ‘ κ°±μ // [κ°μ μ κ°μ€μΉ] if (distances[source] + weight < distances[destination]) { // νμ¬κΉμ§ μλ €μ§ μ΅λ¨ κ±°λ¦¬λ³΄λ€ λ 짧μ κ²½λ‘λ₯Ό μ°Ύμμ λ ν΄λΉ μ μ κΉμ§μ 거리λ₯Ό κ°±μ νλ μμ distances[destination] = distances[source] + weight } // μκ³ λ¦¬μ¦μ΄ μ μ§μ μΌλ‘ μ΅λ¨ 거리λ₯Ό μ λ°μ΄νΈ } // λ°λΌμ distances[destination]λ μ΅λ¨ κ²½λ‘ } // μμ μ¬μ΄ν΄ κ²μ¬ for (let i = 0; i < graph.length; i++) { const edge = graph[i]; const { source, destination, weight } = edge; // μμ μ¬μ΄ν΄μ΄ μ‘΄μ¬νλ©΄ μ΅λ¨ κ±°λ¦¬κ° κ³μν΄μ κ°±μ if (distances[source] + weight < distances[destination]) { console.log("μμ μ¬μ΄ν΄μ΄ μ‘΄μ¬ν©λλ€."); return; } } return distances; // μ΅λ¨ 거리 λ°°μ΄μ λ°ν } // κ·Έλν μμ± λ° μμ μ€ν const graph = [ new Edge(0, 1, 4), new Edge(0, 2, 3), new Edge(1, 3, 2), new Edge(1, 2, -5), // μμ κ°μ€μΉ μμ new Edge(2, 4, 1), new Edge(3, 4, 4) ] const startVertex = 0; const shortestDistances = bellmanFord(graph, startVertex); console.log("μ΅λ¨ 거리 λ°°μ΄:", shortestDistances); // μ΅λ¨ 거리 λ°°μ΄: [0, 4, 3, 5, 6]
Next