Mímisbrunnr知恵の泉

← 数理最適化 一覧

🎓 レベル:基礎 | 重要度:B(標準)

📎 前提:凸集合と凸関数二次計画(QP) | 関連:実装ツールの使い分け

要点(BLUF)

概念 ── モデリング言語の発想

scipy の linprog/minimize は「行列で問題を渡す」低レベル API。cvxpy は 数式に近い形で書け、内部で適切なソルバー(LP→シンプレックス/内点法、SOCP/SDP→内点法)へ自動変換する。人間は「何を最適化したいか」だけ書けばよい。

DCP(Disciplined Convex Programming)

cvxpy は、式が 凸性を保つ規則凸集合と凸関数 の演算規則)で組み立てられているかを検査する。たとえば:

DCP に従わない式(例:凸×凸、非凸な積)は その場でエラーになる。「解けたが実は非凸で局所解だった」という事故を未然に防ぐ ── これが DCP の安全性。

graph LR
  A["数式で記述 (Variable/Minimize/制約)"] --> B["DCP検査: 凸性が保たれるか"]
  B -->|"凸ならOK"| C["標準錐形式へ自動変換"]
  C --> D["ソルバー(内点法等)で求解"]
  B -->|"非凸ならエラー"| E["DCPError で警告"]

同じ書き方で LP・QP・SOCP

LP(生産計画、線形計画の標準形と幾何)・QP・SOCP を cvxpy の統一構文で解く。

import numpy as np
import cvxpy as cp

# --- LP: 生産計画 max 40xA+30xB ---
x = cp.Variable(2, nonneg=True)
lp = cp.Problem(cp.Maximize(40*x[0] + 30*x[1]),
                [2*x[0] + x[1] <= 120, x[0] + x[1] <= 100])
lp.solve()
print(f"[LP]   xA={x.value[0]:.1f}, xB={x.value[1]:.1f}, 利益={lp.value:.1f}")

# --- QP: min (x-1)^2+(y-2)^2 s.t. x+y<=2 ---
y = cp.Variable(2)
qp = cp.Problem(cp.Minimize(cp.sum_squares(y - np.array([1.0, 2.0]))),
                [y[0] + y[1] <= 2, y >= 0])
qp.solve()
print(f"[QP]   x={y.value[0]:.3f}, y={y.value[1]:.3f}, f={qp.value:.4f}")

# --- SOCP: min ||z||_2 s.t. sum(z)=3 ---
z = cp.Variable(3)
socp = cp.Problem(cp.Minimize(cp.norm(z, 2)), [cp.sum(z) == 3])
socp.solve()
print(f"[SOCP] z={np.round(z.value,3)}, ||z||={socp.value:.4f}")

実行結果:

[LP]   xA=20.0, xB=80.0, 利益=3200.0
[QP]   x=0.500, y=1.500, f=0.5000
[SOCP] z=[1. 1. 1.], ||z||=1.7321

3つの異なる錐の問題(錐計画(SOCP・SDP)入門)が、VariableMinimize/Maximize・制約リストという 同じ3点セットで書けた。これまでの章で scipy/PuLP を使って別々に解いた問題(LP=3200、QP=0.5、最小ノルム=√3)が、すべて再現している。

双対変数と実務の作法

# 制約の双対変数(影の価格)を取り出す
print(lp.constraints[0].dual_value)   # 機械時間の影の価格

数式の直観的意味

cvxpy(DCP)が体現するのは「凸最適化は 合成可能(composable)」という事実。凸性を保つ演算(凸集合と凸関数)だけを部品として与えれば、それらをどう組み合わせても凸性が保たれる ── だからユーザーは個々の式の凸性を証明せずとも、規則に従うだけで凸問題を構築できる。内部では問題を標準錐形式(錐計画(SOCP・SDP)入門)に変換し、内点法(内点法入門)で解く。「モデリング(人間)」と「求解(ソルバー)」を分離するこの設計が、最適化を専門家以外にも開いた。低レベル API(scipy/PuLP)との使い分けは 実装ツールの使い分け

⚠️ よくある誤解・落とし穴

関連ノート