Dev Study
← アルゴリズムの手法 — CLRS を読むための地図
レッスン 9 / 13·約 9 分·第29期 アルゴリズムの手法 — CLRS を読むための地図

確定できないなら、全部の辺を回数分ゆるめる — Bellman-Ford 法

アプリと DB の下に何が積まれているか(左が下、右が上)
  1. 物理機リージョン/AZ
  2. ハイパーバイザVM exit で捕まえる
  3. VMゲストOS
  4. コンテナnamespace / cgroup
  5. プロセスアプリ / DB今ここ

最短路を、辺の重みが負になりうる場合まで広げます。使う構造は「最短路に同じ頂点は2度現れない」の1つです。

まず結論

負の辺があると「いま一番近い頂点の距離はもう下がらない」と言えなくなり、近い順に確定していく手が使えません。代わりに、全部の辺を順にゆるめる周回を V−1 回繰り返します(V は頂点の数)。

V−1 回で足りるのは、最短路が同じ頂点を2度通らず、辺が高々 V−1 本だからです。始点から到達できる負の閉路があるとこの前提が崩れ、V 周目でも値が下がります。それが検出の合図になります。

? 読む前に予測

頂点5・辺7のグラフで「全部の辺を1本ずつゆるめる」を1周とします。辺の並べ方を全 5,040 通り試したとき、距離が変わらなくなるまでに要る周回数の最大はいくつでしょうか(負の閉路は無いとします)。

当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。

抽象原理

近い順に確定できないなら、全部の辺を何度もゆるめる

始点から各頂点への距離を、暫定値 d で持つとします。始点は 0、他は無限大から始めます。基本の操作は1つです。

緩和(relaxation): 辺 u→v(重み w)について、d[u] + w が d[v] より小さければ d[v] を置き換える。

辺の重みが負でなければ、「暫定値がいちばん小さい頂点は、もう下がらない」と言えます。他の頂点を経由しても、足されるのは0以上だからです。だから近い順に確定していけます。

負の辺があると、これが崩れます。S→A が 1、S→B が 3、B→A が −5 なら、いちばん近いのは A(1)ですが、遠い B を経由すると 3 − 5 = −2 で A はさらに下がります。近いから確定、ができません。

そこで確定を諦め、全部の辺を順に緩和する周回を V−1 回繰り返します。 何回やれば足りるかは、次の構造で決まります。

1周で、最短路の辺が少なくとも1本ぶん先まで正しい値が伝わる
S = 0始点
1周目で少なくとも S→B が伝わる
B = 2辺1本の最短路
2周目で少なくとも B→A
A = −1辺2本
3周目・4周目で A→C、C→D
D = 1辺4本 = V−1
  • ・最短路は同じ頂点を2度通らないので、辺は高々 V−1 本
  • ・辺の並び順が経路の順と一致していれば、1周で端まで伝わることもある
具体実物

周回ごとの距離表と、並び順による周回数の違い

Bellman 1958 "On a Routing Problem" の Summary(AMS の PDF、2026-10-07 取得)はこう書いています。

The functional equation technique of dynamic programming, combined with approximation in policy space, yields an iterative algorithm which converges after at most (N − 1) iterations.

N は都市の数、つまり頂点の数です。これを実測します。頂点5・有向辺7で、負の辺を含み負の閉路の無いグラフです(Python 3.14.6 / macOS arm64、2026-10-07)。

S→A 4, S→B 2, B→A −3, A→C 3, B→C 6, C→D −1, B→D 8

正解は S=0, A=−1, B=2, C=2, D=1 です。最短路 S→B→A→C→D は辺4本で、ちょうど V−1 本です。

辺を逆順(C→D, A→C, B→A, S→B, S→A, B→C, B→D)に並べて周回すると、こうなります。

$ python3 ex9_bellman_ford.py(辺を逆順に並べた場合。出力から抜粋)コマンド出力
round 1: {'S': 0, 'A': 4, 'B': 2, 'C': 8, 'D': 10}
round 2: {'S': 0, 'A': -1, 'B': 2, 'C': 7, 'D': 7}
round 3: {'S': 0, 'A': -1, 'B': 2, 'C': 2, 'D': 6}
round 4: {'S': 0, 'A': -1, 'B': 2, 'C': 2, 'D': 1}
round 5: (no change)

A が2周目、C が3周目、D が4周目に正解へ届きます。1周に1本ずつ伝わっています。与えられた順のまま並べると、1周目で全部が正解になりました。

全 7! = 5,040 通りの並び順で、更新があった周回数を数えた分布です。

周回数1234
並び順の数2102,3102,310210

最大は 4 = V−1 で、最終の距離表はすべて一致しました。

✓ ここまでの確認

同じグラフで、辺を与えられた順に並べると1周で、逆順に並べると4周で距離が変わらなくなりました。ここから言えることはどれですか。

抽象原理

前提は「最短路に同じ頂点は2度現れない」——崩れると止まらない

V−1 で足りる理由をもう一度言うと、最短路は単純路で、頂点 V 個を通る道の辺は高々 V−1 本だからです。同じ頂点に戻る閉路は、重みが0以上なら回らなくても長くならないので、外して考えられます。

重みが負の閉路があると、この前提が崩れます。 回るたびに短くなるので、最短路そのものが定まりません。そして周回は止まりません。

B→C 6 を C→B −5 に置き換えて閉路 A→C→B→A(3 − 5 − 3 = −5)を作った実測です。

$ python3 ex9_bellman_ford.py(負の閉路あり、V=5 周で打ち切り。出力から抜粋)コマンド出力
round 1: {'S': 0, 'A': -1, 'B': -3, 'C': 2, 'D': 1}
round 2: {'S': 0, 'A': -6, 'B': -8, 'C': -3, 'D': -4}
round 3: {'S': 0, 'A': -11, 'B': -13, 'C': -8, 'D': -9}
round 4: {'S': 0, 'A': -16, 'B': -18, 'C': -13, 'D': -14}
round 5: {'S': 0, 'A': -21, 'B': -23, 'C': -18, 'D': -19}
after 2V=10 rounds: {'S': 0, 'A': -46, 'B': -48, 'C': -43, 'D': -44}

毎周5ずつ、閉路の重みと同じだけ下がります。 負の閉路が無ければ V−1 周で止まるはずなので、V 周目に更新が起きたら、始点から到達できる負の閉路があると分かります。V 周目の1回は、答えを作るためではなく検査のための周回です。

帰属も1つに決まりません。Shimbel "Structure in communication nets"(1955、Proceedings of the Symposium on Information Networks。二次情報による書誌)、Ford "Network Flow Theory"(RAND P-923、1956)、Bellman(1958)、Moore "The shortest path through a maze"(1959、Proceedings of an International Symposium on the Theory of Switching。二次情報による書誌)が並びます。Bellman 自身も追記に書いています。

Added in proof (December 1957): After this paper was written, the author was informed by Max Woodbury and George Dantzig that the particular iterative scheme discussed in Sec. 5 had been obtained by them from first principles.

具体実物

RIP と差分制約 — 止まらない更新をどう打ち切るか

① RIP。 RFC 1058 §1(2026-10-07 取得)はこう書きます。

This memo describes one protocol in a series of routing protocols based on the Bellman-Ford (or distance vector) algorithm.

続く段落は、名前の由来そのものが1つでないことを書いています。

The earliest description of this class of algorithms known to the author is in Ford and Fulkerson [6]. Because of this, they are sometimes known as Ford-Fulkerson algorithms. The term Bellman-Ford is also used. It comes from the fact that the formulation is based on Bellman's equation, the basis of "dynamic programming".

[6] は Ford and Fulkerson "Flows in Networks"(1962)です。「動的計画法」は第6回の主題です。この句は RFC 1058 にだけあり、RIP Version 2 の RFC 2453 §3.1 は based on Bellman's equation [4] で止まります。

RIP にも止まらない更新があります。向きは逆で、値が上がり続けます。§2.1 は到達不能を表す値を決めています。

In the existing implementation of RIP, 16 is used. This value is normally referred to as "infinity", since it is larger than the largest valid metric.

§2.2 はその理由です。

In that case, the metrics may increase slowly in a pattern like the one above until they finally reach infinity. For this reason, the problem is called "counting to infinity".

RIP は値の上限 16 で打ち切ります。引き換えに、RFC 1058 は the protocol was unlikely to be practical for networks with a diameter larger than 15 と書いています。

② 差分制約。 「B は A の3分後以降に始める」は x_A − x_B ≤ −3 と書け、辺 B→A(重み −3)になります。仮の始点から全変数へ重み0の辺を張って最短路を求めると、距離がそのまま開始時刻の候補になります。

3つの作業で「B は A の3分以上後」「C は B の2分以上後」「C は A から L 分以内」とした実測です(Python 3.14.6 / macOS arm64、2026-10-07、頂点4)。

$ python3 diff.py(差分制約。L=6 と L=4)コマンド出力
limit=6 round 1: {'A': -3, 'B': -2, 'C': 0}
limit=6 round 2: {'A': -5, 'B': -2, 'C': 0}
limit=6 round 3: {'A': -5, 'B': -2, 'C': 0} (no change)
limit=4 round 1: {'A': -3, 'B': -2, 'C': 0}
limit=4 round 2: {'A': -5, 'B': -2, 'C': -1}
limit=4 round 3: {'A': -5, 'B': -3, 'C': -1}
limit=4 round 4: {'A': -6, 'B': -3, 'C': -2}

L=6 では3周目で止まります。差だけの制約なので全部に5を足してよく、A=0, B=3, C=5 で全制約を満たします。L=4 では閉路 A→C→B→A が 4 − 2 − 3 = −1 になり、4周目(V 周目)にも下がりました。3分+2分=5分かかるのに4分以内と求めている、矛盾した制約です。

✓ ここまでの確認

「B は A の3分後以降に始める」型の制約を辺にして Bellman-Ford 法を回したところ、V 周目でも値が下がりました。何を意味しますか。

⇄ 2つを見比べる
具体例 A

差分制約(負の閉路)

制約が矛盾すると重みの合計が負の閉路ができ、値が下がり続けます。V−1 周で止まるはずなので、V 周目の更新を「矛盾あり」の報告に使います。

具体例 B

RIP(counting to infinity)

宛先に届かなくなると、距離が少しずつ上がり続けます。RFC 1058 は無限大を 16 と決め、そこに届いたら到達不能とみなします。網の直径が15までという制限と引き換えです。

片方は値が下がり続け、もう片方は上がり続けます。それでも同じ形だと言えるのはなぜでしょうか。

「止まらない原因は何か」と「何を上限にして打ち切っているか」を並べてください。

この章のまとめ

  • 負の辺があると、一番近い頂点を確定する手は使えない。代わりに全部の辺の緩和を V−1 周繰り返す。
  • V−1 で足りるのは、最短路は同じ頂点を2度通らず、辺が高々 V−1 本だから。Bellman 1958 も「at most (N − 1) iterations」と書く。
  • 辺の並び順は周回数だけを変える。5,040 通りで1〜4周に散らばり、結果は一致した。
  • 負の閉路があると V 周目でも下がる。これが検出の合図。差分制約では「制約が矛盾している」の意味になる。
  • RIP は同じ系統の算法で、上がり続ける更新(counting to infinity)を値の上限 16 で打ち切る。
  • 帰属は1つに決まらない。原論文は所要時間が正であることを前提にしている。
  • 既存クイズでは、「アルゴリズムとデータ構造 III(発展編)」の algorithm-3-4 がこの章の結論の一行版です。正解文は「負の重みを持つ辺があるグラフでも最短経路を求められる」で、「始点から到達できる負の閉路が無い場合に限る」という条件を省いています。
  • CLRS(『アルゴリズムイントロダクション』)の目次や索引で Bellman-Ford algorithm(単一始点最短路) を探すと、この回の内容に対応する章や節が見つかります。章の題と番号は版で変わるので、手元の目次で確かめてください。

自分の現場で確かめる

読んだだけでは身につきません。手元の環境で実際に見てみてください。

環境:

理解度チェック

読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。

問題 1 / 3正解: 0

Bellman-Ford 法で、全辺をゆるめる周回が V−1 回で足りる理由はどれですか。

用語集(5語)
緩和(relaxation)
辺 u→v(重み w)について、d[u] + w が d[v] より小さければ d[v] を置き換える操作。d は始点からの距離の暫定値。値は下がる向きにしか動かない。
負の閉路
辺の重みの合計が負になる閉路。始点から到達できると、回るたびに距離が下がるので最短路が定まらない。Bellman-Ford 法では V 周目にも更新が起きることで分かる。
単純路
同じ頂点を2度通らない道。頂点が V 個なら辺は高々 V−1 本。負の閉路が無ければ、最短路は単純路の中から選べる。
差分制約
「x_B − x_A ≥ 3」のように2つの変数の差を縛る制約の集まり。各制約を辺に直すと最短路の問題になり、負の閉路があれば制約が矛盾している。
counting to infinity
RIP で、到達できなくなった宛先の距離が少しずつ増えていき、無限大を表す 16 に届くまで続く現象。RFC 1058 がこの名で呼んでいる。