0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

線形計画法:農家の利益最大化問題「Wikipedia の線形計画法の例を具体的な数値でお願いします。」をsympyでAI先生に教えてもらいました。

0
Last updated at Posted at 2026-07-25

オリジナル

・Wikipedia の線形計画法の例

・English

(本日の)Gemini先生へ

Wikipedia の線形計画法の例を具体的な数値でお願いします。

(途中省略)

# SymPy を使用して線形計画法の制約領域および最適解を算出・プロットするプログラム

import sympy as sp
from sympy.plotting import plot_implicit, PlotGrid

# 1. 変数と目的関数・制約条件の定義
x1, x2 = sp.symbols('x1 x2', real=True)

# 目的関数: Z = 3*x1 + 5*x2
Z = 3 * x1 + 5 * x2

# 制約条件の不等式群
inequalities = [
    x1 + x2 <= 10,       # 農地制限
    2 * x1 + x2 <= 16,   # 肥料制限
    x1 + 2 * x2 <= 18,   # 殺虫剤制限
    x1 >= 0,             # 非負制約 (x1)
    x2 >= 0              # 非負制約 (x2)
]

# 2. 実行可能領域の頂点(交点)を計算
# 境界線の方程式
eq1 = sp.Eq(x1 + x2, 10)
eq2 = sp.Eq(2 * x1 + x2, 16)
eq3 = sp.Eq(x1 + 2 * x2, 18)
eq4 = sp.Eq(x1, 0)
eq5 = sp.Eq(x2, 0)

# 交点候補の計算
candidates = [
    sp.solve([eq4, eq5], (x1, x2)),  # (0, 0)
    sp.solve([eq2, eq5], (x1, x2)),  # (8, 0)
    sp.solve([eq1, eq2], (x1, x2)),  # (6, 4)
    sp.solve([eq1, eq3], (x1, x2)),  # (2, 8)
    sp.solve([eq4, eq3], (x1, x2))   # (0, 9)
]

# 制約をすべて満たす頂点のみを抽出し、各点での利益 Z を評価
feasible_vertices = []
for pt in candidates:
    if all(ineq.subs(pt) for ineq in inequalities):
        z_val = Z.subs(pt)
        feasible_vertices.append((pt[x1], pt[x2], z_val))

# 3. 最適解の探索
optimal_point = max(feasible_vertices, key=lambda v: v[2])

print(f"実行可能頂点一覧 (x1, x2, Z): {feasible_vertices}")
print(f"最適解: 小麦 x1 = {optimal_point[0]}, 大麦 x2 = {optimal_point[1]}")
print(f"最大利益: {optimal_point[2]} 万円")

# 4. 実行可能領域の視覚化 (SymPy の plot_implicit を使用)
feasibility_region = sp.And(*inequalities)
p = plot_implicit(
    feasibility_region,
    (x1, -1, 12),
    (x2, -1, 12),
    title="Feasible Region (Linear Programming)",
    xlabel="x1 (Wheat)",
    ylabel="x2 (Barley)",
    show=True
)

実行結果

実行可能頂点一覧 (x1, x2, Z): [(0, 0, 0), (8, 0, 24), (6, 4, 38), (2, 8, 46), (0, 9, 45)]
最適解: 小麦 x1 = 2, 大麦 x2 = 8
最大利益: 46 万円

(計算過程のポイント省略)

作図して下さい。

image.png

(さらに)Gemini先生へ

Wikipedia「線形計画法」の農家の例 をおすすめのモジュールでsympyで教えて下さい。

SymPy には線形計画法を解くための最適化モジュール sympy.solvers.simplex が用意されており、その中の lpmax 関数 を使うのが最も直接的でおすすめです。
以前紹介した「交点をすべて解いて比較するコード」よりもシンプルに、問題の設定式をそのまま渡すだけで厳密な解(有理数解)を直接算出してくれます。
...
(途中抜粋)

・sympy.solvers.simplex.lpmax を使ったコード

# SymPy の最適化モジュール (simplex) を使用した線形計画法の解法

from sympy import symbols, Ge, Le
from sympy.solvers.simplex import lpmax

# 1. 変数の定義
x1, x2 = symbols('x1 x2', real=True)

# 2. 目的関数(最大化したい利益 Z)
Z = 3 * x1 + 5 * x2

# 3. 制約条件(不等式のリスト)
# Le は <= (Less than or Equal), Ge は >= (Greater than or Equal) を表します
constraints = [
    Le(x1 + x2, 10),      # 農地制限: x1 + x2 <= 10
    Le(2 * x1 + x2, 16),  # 肥料制限: 2*x1 + x2 <= 16
    Le(x1 + 2 * x2, 18),  # 殺虫剤制限: x1 + 2*x2 <= 18
    Ge(x1, 0),            # 非負制約: x1 >= 0
    Ge(x2, 0)             # 非負制約: x2 >= 0
]

# 4. 単体法(Simplex法)で最大値を計算
max_value, optimal_dict = lpmax(Z, constraints)

# 結果の表示
print(f"最大利益 (Z): {max_value} 万円")
print(f"最適解: 小麦 x1 = {optimal_dict[x1]} km², 大麦 x2 = {optimal_dict[x2]} km²")

実行結果

最大利益 (Z): 46 万円
最適解: 小麦 x1 = 2 km², 大麦 x2 = 8 km²

このモジュール(lpmax)のポイント
○直感的: 数式(目的関数と制約不等式の配列)をそのまま渡すだけで計算してくれます。
○厳密解(分数/整数): 数値計算ライブラリ(SciPy等)と異なり、シンボリック計算エンジンである SymPy のため、小数近似(2.00000001 など)ではなく「正確な整数・分数」として解を返してくれます。

いつもと違うおすすめです。

sympy のdoc

・sympy.solvers.simplex.lpmax(f, constr)
https://docs.sympy.org/latest/modules/solvers/solvers.html#sympy.solvers.simplex.lpmax

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?