{"componentChunkName":"component---src-templates-blog-post-js","path":"/algorithm/벨만-포드-bellman-ford/","result":{"data":{"site":{"siteMetadata":{"title":"Bottlehs Tech Blog","description":"웹·앱·AI 개발자 전병훈(bottlehs)의 기술 블로그. AI·LLM, JavaScript·Vue, Spring Boot, 알고리즘, 블록체인 실무 가이드를 다룹니다","siteUrl":"https://www.bottlehs.dev","author":{"name":"Jeon Byung Hun","summary":"개발을 즐기는 bottlehs - Engineer, MS, AI, FE, BE, OS, IOT, Blockchain, 설계, 테스트"},"social":{"github":"bottlehs","codepen":"bottlehs"}}},"markdownRemark":{"id":"691b2cf0-a703-595f-98c6-8683fb98ad0a","excerpt":"벨만-포드 알고리즘 (Bellman-Ford) 벨만-포드는 음수 가중치가 있는 그래프에서도 작동하는 최단 경로 알고리즘으로, 음수 사이클도 감지할 수 있다. 정의 다익스트라와 달리 음수 가중치를 허용하는 최단 경로 알고리즘이다. 핵심 아이디어는 “최단 경로는 최대 V-…","html":"<p><img src=\"/assets/algorithm.png\" alt=\"벨만-포드 알고리즘 (Bellman-Ford)\" title=\"벨만-포드 알고리즘 (Bellman-Ford)\"></p>\n<p>벨만-포드는 음수 가중치가 있는 그래프에서도 작동하는 최단 경로 알고리즘으로, 음수 사이클도 감지할 수 있다.</p>\n<h2 id=\"정의\" style=\"position:relative;\"><a href=\"#%EC%A0%95%EC%9D%98\" aria-label=\"정의 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>정의</h2>\n<p>다익스트라와 달리 음수 가중치를 허용하는 최단 경로 알고리즘이다. 핵심 아이디어는 “최단 경로는 최대 V-1개의 간선을 사용한다”는 점이다. 시작점에서 어떤 정점까지 가려면 최대 V-1개의 간선만 사용하면 되기 때문이다. 따라서 간선의 수 E만큼 반복해 모든 정점의 거리를 갱신하는 과정을 V-1번 반복하면 최단 거리가 확정된다.</p>\n<p>V-1번 반복 후에도 거리가 갱신되면 음수 사이클이 존재한다고 판단할 수 있다. 음수 사이클이 있으면 그 사이클을 계속 돌며 거리를 무한정 줄일 수 있기 때문이다. 다익스트라는 이런 경우 작동하지 않지만, 벨만-포드는 음수 가중치가 있어도 안정적으로 최단 거리를 구할 수 있다.</p>\n<h2 id=\"구현\" style=\"position:relative;\"><a href=\"#%EA%B5%AC%ED%98%84\" aria-label=\"구현 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>구현</h2>\n<p>거리 배열을 초기화하고 시작점의 거리를 0으로 설정한다. 이후 V-1번 반복하며 모든 간선을 확인해 더 짧은 경로를 찾으면 거리를 갱신한다. 각 반복에서 “한 정점을 거쳐 가는 더 짧은 경로”를 발견하면 갱신하는데, V-1번 반복하면 최악의 경우에도 모든 정점까지의 최단 거리가 계산된다.</p>\n<p>음수 사이클 감지를 위해 V-1번 이후에 한 번 더 모든 간선을 확인해 거리가 줄어드는지 체크한다. 값이 줄어들면 음수 사이클이 존재하므로 null이나 특수 값을 반환한다. 구현 시 그래프가 방향 그래프인지 무방향인지, 그리고 자기 자신으로 가는 간선이 있는지도 고려해야 한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span> <span class=\"token function\">bellmanFord</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">graph<span class=\"token punctuation\">,</span> start</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> n <span class=\"token operator\">=</span> graph<span class=\"token punctuation\">.</span>length\n  <span class=\"token keyword\">const</span> <span class=\"token constant\">INF</span> <span class=\"token operator\">=</span> <span class=\"token number\">1e18</span>\n  <span class=\"token keyword\">const</span> dist <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Array</span><span class=\"token punctuation\">(</span>n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">fill</span><span class=\"token punctuation\">(</span><span class=\"token constant\">INF</span><span class=\"token punctuation\">)</span>\n  dist<span class=\"token punctuation\">[</span>start<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n  \n  <span class=\"token comment\">// V-1번 반복</span>\n  <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">let</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> n <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">let</span> u <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> u <span class=\"token operator\">&lt;</span> n<span class=\"token punctuation\">;</span> u<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>dist<span class=\"token punctuation\">[</span>u<span class=\"token punctuation\">]</span> <span class=\"token operator\">===</span> <span class=\"token constant\">INF</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">continue</span>\n      <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> to<span class=\"token punctuation\">,</span> w <span class=\"token punctuation\">}</span> <span class=\"token keyword\">of</span> graph<span class=\"token punctuation\">[</span>u<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>dist<span class=\"token punctuation\">[</span>u<span class=\"token punctuation\">]</span> <span class=\"token operator\">+</span> w <span class=\"token operator\">&lt;</span> dist<span class=\"token punctuation\">[</span>to<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n          dist<span class=\"token punctuation\">[</span>to<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> dist<span class=\"token punctuation\">[</span>u<span class=\"token punctuation\">]</span> <span class=\"token operator\">+</span> w\n        <span class=\"token punctuation\">}</span>\n      <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span>\n  \n  <span class=\"token comment\">// 음수 사이클 감지</span>\n  <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">let</span> u <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> u <span class=\"token operator\">&lt;</span> n<span class=\"token punctuation\">;</span> u<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>dist<span class=\"token punctuation\">[</span>u<span class=\"token punctuation\">]</span> <span class=\"token operator\">===</span> <span class=\"token constant\">INF</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">continue</span>\n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> to<span class=\"token punctuation\">,</span> w <span class=\"token punctuation\">}</span> <span class=\"token keyword\">of</span> graph<span class=\"token punctuation\">[</span>u<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>dist<span class=\"token punctuation\">[</span>u<span class=\"token punctuation\">]</span> <span class=\"token operator\">+</span> w <span class=\"token operator\">&lt;</span> dist<span class=\"token punctuation\">[</span>to<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token keyword\">null</span> <span class=\"token comment\">// 음수 사이클 존재</span>\n      <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span>\n  \n  <span class=\"token keyword\">return</span> dist\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">// 예시 그래프</span>\n<span class=\"token keyword\">const</span> graph <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span>\n  <span class=\"token punctuation\">[</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">to</span><span class=\"token operator\">:</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">w</span><span class=\"token operator\">:</span> <span class=\"token number\">4</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">to</span><span class=\"token operator\">:</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">w</span><span class=\"token operator\">:</span> <span class=\"token number\">5</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token comment\">// 0</span>\n  <span class=\"token punctuation\">[</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">to</span><span class=\"token operator\">:</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">w</span><span class=\"token operator\">:</span> <span class=\"token operator\">-</span><span class=\"token number\">3</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>                  <span class=\"token comment\">// 1</span>\n  <span class=\"token punctuation\">[</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">to</span><span class=\"token operator\">:</span> <span class=\"token number\">3</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">w</span><span class=\"token operator\">:</span> <span class=\"token number\">2</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>                   <span class=\"token comment\">// 2</span>\n  <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span>                                    <span class=\"token comment\">// 3</span>\n<span class=\"token punctuation\">]</span>\n\nconsole<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token function\">bellmanFord</span><span class=\"token punctuation\">(</span>graph<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token comment\">// [0, 4, 1, 3]</span>\n\n<span class=\"token comment\">// 음수 사이클이 있는 경우</span>\n<span class=\"token keyword\">const</span> graphWithCycle <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span>\n  <span class=\"token punctuation\">[</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">to</span><span class=\"token operator\">:</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">w</span><span class=\"token operator\">:</span> <span class=\"token number\">1</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token comment\">// 0</span>\n  <span class=\"token punctuation\">[</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">to</span><span class=\"token operator\">:</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">w</span><span class=\"token operator\">:</span> <span class=\"token number\">2</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token comment\">// 1</span>\n  <span class=\"token punctuation\">[</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">to</span><span class=\"token operator\">:</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">w</span><span class=\"token operator\">:</span> <span class=\"token operator\">-</span><span class=\"token number\">5</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">]</span> <span class=\"token comment\">// 2 (음수 사이클: 0→1→2→0)</span>\n<span class=\"token punctuation\">]</span>\n\nconsole<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token function\">bellmanFord</span><span class=\"token punctuation\">(</span>graphWithCycle<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token comment\">// null (음수 사이클)</span></code></pre></div>\n<h2 id=\"데모\" style=\"position:relative;\"><a href=\"#%EB%8D%B0%EB%AA%A8\" aria-label=\"데모 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>데모</h2>\n<p><a href=\"https://codepen.io/pen/?template=yLgbWPj\">https://codepen.io/pen/?template=yLgbWPj</a></p>","tableOfContents":"<ul>\n<li><a href=\"/algorithm/%EB%B2%A8%EB%A7%8C-%ED%8F%AC%EB%93%9C-bellman-ford/#%EC%A0%95%EC%9D%98\">정의</a></li>\n<li><a href=\"/algorithm/%EB%B2%A8%EB%A7%8C-%ED%8F%AC%EB%93%9C-bellman-ford/#%EA%B5%AC%ED%98%84\">구현</a></li>\n<li><a href=\"/algorithm/%EB%B2%A8%EB%A7%8C-%ED%8F%AC%EB%93%9C-bellman-ford/#%EB%8D%B0%EB%AA%A8\">데모</a></li>\n</ul>","wordCount":{"words":184},"fields":{"slug":"/algorithm/벨만-포드-bellman-ford/","image":"/assets/algorithm.png","faq":[]},"frontmatter":{"title":"벨만-포드 알고리즘 (Bellman-Ford)","date":"2025년 11월 1일","dateISO":"2025-11-01T00:00:00.000Z","updatedISO":null,"category":"algorithm","description":"음수 가중치가 있는 그래프에서 최단 경로를 구할 수 있는 알고리즘. 음수 사이클 감지도 가능하며, 시간복잡도는 O(VE)이다.","tags":["벨만-포드","Bellman-Ford","최단 경로","알고리즘","Algorithm","JavaScript"]}}},"pageContext":{"slug":"/algorithm/벨만-포드-bellman-ford/","previous":{"fields":{"slug":"/algorithm/병합-정렬-merge-sort/"},"frontmatter":{"title":"병합 정렬 (Merge Sort)","tags":["병합 정렬","Merge Sort","정렬","알고리즘","Algorithm","JavaScript"]}},"next":{"fields":{"slug":"/algorithm/kmp-알고리즘-kmp-algorithm/"},"frontmatter":{"title":"KMP 알고리즘 (Knuth-Morris-Pratt)","tags":["KMP 알고리즘","Knuth-Morris-Pratt","문자열 검색","알고리즘","Algorithm","JavaScript"]}}}},"staticQueryHashes":["213619243","3262363727"]}