単体法で解く
第1章 No.9 / 線形計画法を「手で回せるアルゴリズム」にする
No.1 では 2 変数の線形計画問題を グラフで解き、No.4 以降は Mathematica や Octave といった計算機に数値解を任せた。 では、その計算機は内部でいったい何をしているのだろうか。 その中心にあるのが、1947 年に G. ダンツィク(Dantzig)が考案した 単体法(シンプレックス法, simplex method)である。 ここでは単体法の考え方を説明し、実際に一つの問題を最後まで解いてみる。
1. なぜ単体法が必要か
グラフ(図示)で解けるのは変数が 2 個までである。変数が 3 個なら立体、 4 個以上になると人間には描けない。しかし線形計画問題には、 次の大切な性質がある。
線形計画問題の最適解は、必ず実行可能領域(制約を満たす範囲)の 頂点(かど)のどれかにある。
だから「すべての頂点を調べれば最適解が見つかる」。ところが頂点の数は 変数と制約が増えると爆発的に多くなり、全部は調べきれない。 そこで単体法は、ある頂点から出発し、目的関数がより良くなる隣の頂点へ 次々と移っていく。良くなる隣がなくなったら、そこが最適解である。 「かどからかどへ辺を伝って登っていく」イメージだ。
2. 標準形に直す — スラック変数
単体法は不等式のままでは扱えない。そこで各制約の「余り」を表す スラック変数 s を足して、不等式を等式にする。たとえば
3x1 + 2x2 ≦ 18 ⟹ 3x1 + 2x2 + s = 18 (s ≧ 0)s = 18 − 3x1 − 2x2 は「まだ使っていない資源の量」である。 目的関数 z も z − 3x1 − 5x2 = 0 の形にそろえて、変数とスラックをすべて等式で並べたものを 標準形と呼ぶ。
3. 単体表(タブロー)と手順
標準形の係数を表にしたものが単体表(タブロー)である。 単体法は、この表に対して次の 3 ステップを繰り返すだけの機械的な手続きだ。
- 入る変数を選ぶ:z の行で係数が最も負の列。最大化なら、 その変数を増やすと z が最も伸びる。
- 出る変数を選ぶ(比の検定):選んだ列で、 (右辺 ÷ その列の正の係数) が 最小になる行。負・ゼロの係数の行は見ない。
- ピボット(掃き出し):交点の要素を 1 にし、その列の他を 0 にする。 基底(いま値を持つ変数)が入れ替わり、一つ隣の頂点へ移る。
z の行に負の係数がなくなったら終了。それが最適解。
4. 実際に解いてみる
ある工場で製品 A を x1 個、製品 B を x2 個つくる。 1 個あたりの利益は A が 3 万円、B が 5 万円。工程の能力から次の制約がある。 利益 z を最大にする生産量を求めよ。
最大化 z = 3x1 + 5x2スラック変数 s1, s2, s3 を入れて標準形にする。
x1 + s1 = 42x2 + s2 = 12
3x1 + 2x2 + s3 = 18
z − 3x1 − 5x2 = 0 ① 初期タブロー
まず x1 = x2 = 0(何もつくらない原点)から出発する。 このとき基底は s1=4, s2=12, s3=18、利益 z = 0。
| 基底 | x1 | x2 | s1 | s2 | s3 | 右辺 | 比 |
|---|---|---|---|---|---|---|---|
| s1 | 1 | 0 | 1 | 0 | 0 | 4 | — |
| s2 | 0 | 2 | 0 | 1 | 0 | 12 | 12/2 = 6 |
| s3 | 3 | 2 | 0 | 0 | 1 | 18 | 18/2 = 9 |
| z | −3 | −5 | 0 | 0 | 0 | 0 |
z の行で最も負なのは x2 の −5 → x2 が入る変数。 比の検定は 12/2 = 6 と 18/2 = 9 で、最小の 6 の行、すなわち s2 が出る変数。ピボット要素は 2(オレンジのマス)。
② 1 回目のピボット後x2 の列を掃き出す(s2 行を 2 で割り、他の行から消す)。 x2 = 6 が基底に入り、z は 0 → 30 に増えた。
| 基底 | x1 | x2 | s1 | s2 | s3 | 右辺 | 比 |
|---|---|---|---|---|---|---|---|
| s1 | 1 | 0 | 1 | 0 | 0 | 4 | 4/1 = 4 |
| x2 | 0 | 1 | 0 | 1/2 | 0 | 6 | — |
| s3 | 3 | 0 | 0 | −1 | 1 | 6 | 6/3 = 2 |
| z | −3 | 0 | 0 | 5/2 | 0 | 30 |
まだ z の行に −3 が残っている → x1 が入る変数。 比の検定は 4/1 = 4 と 6/3 = 2 で、最小の 2 の行、 s3 が出る変数。ピボット要素は 3。
③ 2 回目のピボット後(最終)x1 の列を掃き出す。x1 = 2 が基底に入り、z = 36。
| 基底 | x1 | x2 | s1 | s2 | s3 | 右辺 |
|---|---|---|---|---|---|---|
| s1 | 0 | 0 | 1 | 1/3 | −1/3 | 2 |
| x2 | 0 | 1 | 0 | 1/2 | 0 | 6 |
| x1 | 1 | 0 | 0 | −1/3 | 1/3 | 2 |
| z | 0 | 0 | 0 | 3/2 | 1 | 36 |
z の行に負の係数がもうない。ここで単体法は終了する。
x1 = 2 個, x2 = 6 個 のとき、利益は最大 z = 36 万円。
(このとき s1 = 2、つまり第 1 工程の能力は 2 だけ余り、
第 2・第 3 工程は使い切っている。)
5. 頂点をたどる旅として見る
いま起きたことを No.1 のグラフで振り返ると、単体法は次のように 実行可能領域のかどを順にたどっていた。
(0, 0) → (0, 6) → (2, 6)z = 0 → z = 30 → z = 36
原点から出発し、利益が伸びる隣のかどへ 2 回移って頂上に着いた。 変数が 2 個なので今回は図でも確かめられるが、 単体法は変数がいくつあっても同じ手順で動く。だからこそ Mathematica や Octave は、何十・何百変数の問題でもこの掃き出しを 高速に繰り返して最適解を出せるのである。
同じ手順で、最大化 z = 4x1 + 3x2、制約 2x1 + x2 ≦ 10、x1 + 3x2 ≦ 15、 x1, x2 ≧ 0 を単体表で解いてみよ。 (答え:x1 = 3, x2 = 4, z = 24 … だけを確かめ、 途中のタブローも自分で書いてみること。)