100本ノック / 数理モデリング / 数理モデリング100本ノック

限られた設備・人員・予算を最も価値ある仕事へ配分する

限られた設備・人員・予算を最も価値ある仕事へ配分する

精密部品工場で学ぶ最適化のためのモデル化 No.081〜No.090

本記事では、製品別生産量、設備立上げ、検査員シフト、配送経路、改善投資を意思決定変数として定義し、目的関数と制約条件の下で最適化します。SciPyを使って線形計画・整数計画・二値選択を実行し、結果を現場の指示とリスクへ翻訳します。

[!NOTE] 本資料は、数理工房 (もしくは代表である和山個人) が過去に企業研修において使用した notebook を企業様の許可を得て再構成・編集のうえ公開しています。 掲載データはすべて架空のものであり、実在する企業・工場・数値とは一切関係ありません。

はじめに:この記事で扱う製造業の実務課題

架空の精密部品工場では、A・B・Cの3製品が共通設備、人員、材料を使います。全需要を満たす能力はなく、生産量と製品立上げを選ぶ必要があります。加えて、検査員の曜日別配置、顧客への巡回配送、DX改善案件の投資配分も決めなければなりません。

最適化は自動的に正解を出す魔法ではありません。変数、評価基準、守る条件を合意し、得られた解が現場で実行可能かを確認する意思決定支援です。

現場でよくある状況

  • 「できるだけ多く作る」の対象製品と評価基準が曖昧
  • 設備時間は守っても材料・人員制約を見落とす
  • 端数の生産数や0.4人という実行不能な解が出る
  • 製品を1個でも作ると発生する段取り費を連続式で扱う
  • シフト・配送・投資判断を担当者の経験だけで作る
  • 最適値だけが報告され、制約余力や代替案が示されない

なぜこの問題は判断が難しいのか

複数製品が共通資源を奪い合い、利益・納期・公平性がトレードオフになります。目的関数に入れない価値は最適化されず、制約に入れない現場条件は守られません。

連続変数、整数変数、二値変数を業務の性質に合わせ、解が少し変わったときの影響や制約余力も確認します。

今回扱うノックの全体像

No.テーマ工場での判断
081意思決定変数何をモデルが決めるか
082目的関数何を最大・最小にするか
083制約条件何を必ず守るか
084線形計画製品別生産量をどう配分するか
085整数変数個数・人数を整数で扱う
086二値変数製品立上げの有無を扱う
087シフト曜日別必要人数を満たす
088配送巡回距離を短くする
089予算配分改善案件を選択する
090結果翻訳最適解を実行指示へ変える

Python 環境の準備

外部データは使いません。SciPyの linprogmilp、NumPy、pandas、matplotlibを使用します。

%matplotlib inline
%config InlineBackend.figure_format = 'svg'
import itertools,platform,sys
import matplotlib, matplotlib.pyplot as plt
from matplotlib import font_manager
import numpy as np,pandas as pd,scipy
from scipy.optimize import linprog,milp,Bounds,LinearConstraint
from IPython.display import display

SEED=42; rng=np.random.default_rng(SEED)
fonts={f.name for f in font_manager.fontManager.ttflist}; plot_font=next((f for f in ["Hiragino Sans","Yu Gothic","Noto Sans CJK JP"] if f in fonts),"sans-serif")
plt.rcParams["font.family"]=plot_font; plt.rcParams["axes.unicode_minus"]=False
print(f"Python {sys.version.split()[0]} / NumPy {np.__version__} / pandas {pd.__version__} / SciPy {scipy.__version__}")
print(f"matplotlib {matplotlib.__version__} / font {plot_font} / seed {SEED} / {platform.platform()}")

Python 3.13.1 / NumPy 2.5.1 / pandas 3.0.3 / SciPy 1.18.0
matplotlib 3.11.0 / font Hiragino Sans / seed 42 / macOS-26.3-arm64-arm-64bit-Mach-O

架空データの作成

3製品の限界利益、設備時間、作業時間、材料、需要上限、最低供給、立上げ固定費を定義します。週次能力は設備6,000分、作業3,300分、材料2,250kgです。

products = pd.DataFrame(
    {
        "product": ["A", "B", "C"],
        "margin": [1800, 2700, 4400],
        "machine_min": [4, 7, 12],
        "labor_min": [2, 4, 6],
        "material_kg": [1.2, 1.8, 3.2],
        "demand_max": [800, 520, 280],
        "minimum_supply": [400, 250, 120],
        "setup_cost": [180000, 260000, 420000],
    }
)
capacities = {"machine_min": 6000, "labor_min": 3300, "material_kg": 2250}
display(products.style.format({"margin": {:,.0f}", "setup_cost": {:,.0f}"}))
print("週次能力:", capacities)
  product margin machine_min labor_min material_kg demand_max minimum_supply setup_cost
0 A ¥1,800 4 2 1.200000 800 400 ¥180,000
1 B ¥2,700 7 4 1.800000 520 250 ¥260,000
2 C ¥4,400 12 6 3.200000 280 120 ¥420,000
週次能力: {'machine_min': 6000, 'labor_min': 3300, 'material_kg': 2250}
full = products.copy()
for resource in capacities:
    full[resource + "_use"] = full[resource] * full["demand_max"]
resource_table = pd.DataFrame(
    {
        "資源": list(capacities),
        "全需要時使用量": [full[r + "_use"].sum() for r in capacities],
        "能力": list(capacities.values()),
    }
)
resource_table["負荷率"] = resource_table["全需要時使用量"] / resource_table["能力"]
display(resource_table.style.format({"負荷率": "{:.1%}"}))
fig, ax = plt.subplots()
ax.bar(resource_table["資源"], resource_table["負荷率"] * 100, color="#de2d26")
ax.axhline(100, color="black", linestyle="--", label="能力上限")
ax.set_title("全需要を生産した場合の資源負荷")
ax.set_xlabel("資源")
ax.set_ylabel("負荷率(%)")
ax.grid(True, axis="y", alpha=0.3)
ax.legend()
plt.tight_layout()
plt.show()
  資源 全需要時使用量 能力 負荷率
0 machine_min 10200.000000 6000 170.0%
1 labor_min 5360.000000 3300 162.4%
2 material_kg 2792.000000 2250 124.1%

svg


No.081:意思決定変数を定義する

実務での意味

意思決定変数はモデルが選べる値です。生産量、人数、立上げ有無を、担当者が変更できる範囲として定義します。

分析・モデル化の考え方

xpx_p を製品 pp の週次生産量とし、xA,xB,xC0x_A,x_B,x_C\ge0。単位、時間粒度、連続・整数の別を明示します。

Pythonで確認する

variables = pd.DataFrame(
    {
        "変数": ["x_A", "x_B", "x_C"],
        "意味": ["製品A生産量", "製品B生産量", "製品C生産量"],
        "単位": ["個/週"] * 3,
        "下限": products["minimum_supply"],
        "上限": products["demand_max"],
        "型": ["連続(後で整数化)"] * 3,
    }
)
display(variables)
candidate = np.array([600, 400, 200])
check = products[["machine_min", "labor_min", "material_kg"]].T @ candidate
print("候補計画", dict(zip(products["product"], candidate)), "資源使用", check.to_dict())
変数 意味 単位 下限 上限
0 x_A 製品A生産量 個/週 400 800 連続(後で整数化)
1 x_B 製品B生産量 個/週 250 520 連続(後で整数化)
2 x_C 製品C生産量 個/週 120 280 連続(後で整数化)
候補計画 {'A': np.int64(600), 'B': np.int64(400), 'C': np.int64(200)} 資源使用 {'machine_min': 7600.0, 'labor_min': 4000.0, 'material_kg': 2080.0}

結果の読み取り

変数表により、モデルが決める範囲と現場が入力するパラメータを分離できます。最低供給は変数ではなく制約です。


No.082:目的関数を定義する

実務での意味

目的関数は候補案の望ましさを一つの尺度へ変換します。今回は週次限界利益を最大化します。

分析・モデル化の考え方

maxZ=1800xA+2700xB+4400xC\max Z=1800x_A+2700x_B+4400x_C。品質・納期・公平性を無視しないよう、必要条件は制約やペナルティへ入れます。

Pythonで確認する

candidates = pd.DataFrame(
    {"案": ["A重視", "均衡", "C重視"], "A": [750, 600, 450], "B": [300, 400, 450], "C": [130, 180, 250]}
)
candidates["限界利益"] = candidates[["A", "B", "C"]].to_numpy() @ products["margin"].to_numpy()
display(candidates.style.format({"限界利益": {:,.0f}"}))
fig, ax = plt.subplots()
ax.bar(candidates["案"], candidates["限界利益"] / 1e6, color="#2c7fb8")
ax.set_title("候補計画の目的関数値")
ax.set_xlabel("候補案")
ax.set_ylabel("週次限界利益(百万円)")
ax.grid(True, axis="y", alpha=0.3)
plt.tight_layout()
plt.show()
  A B C 限界利益
0 A重視 750 300 130 ¥2,732,000
1 均衡 600 400 180 ¥2,952,000
2 C重視 450 450 250 ¥3,125,000

svg

結果の読み取り

利益が高くても制約違反なら採用できません。目的関数と実行可能性を分けて確認します。


No.083:制約条件を定義する

実務での意味

設備・人員・材料・需要・最低供給を数式化し、実行不能な案を除外します。

分析・モデル化の考え方

ptrpxpCr\sum_pt_{rp}x_p\le C_rlpxpupl_p\le x_p\le u_p。単位をそろえ、ハード制約と緩和可能な目標を区別します。

Pythonで確認する

A = products[["machine_min", "labor_min", "material_kg"]].T.to_numpy()
b = np.array(list(capacities.values()))
rows = []
for _, row in candidates.iterrows():
    x = row[["A", "B", "C"]].to_numpy(dtype=float)
    use = A @ x
    rows.append(
        {
            "案": row["案"],
            "設備余力": b[0] - use[0],
            "作業余力": b[1] - use[1],
            "材料余力": b[2] - use[2],
            "実行可能": bool(np.all(use <= b)),
        }
    )
feasibility = pd.DataFrame(rows)
display(feasibility.style.format({"設備余力": "{:+,.0f}", "作業余力": "{:+,.0f}", "材料余力": "{:+,.0f}"}))
  設備余力 作業余力 材料余力 実行可能
0 A重視 -660 -180 +394 False
1 均衡 -1,360 -580 +234 False
2 C重視 -1,950 -900 +100 False

結果の読み取り

負の余力は制約違反です。制約別余力は、どの資源を追加すれば案が実行可能になるかを示します。


No.084:線形計画問題として定式化する

実務での意味

線形な利益と資源制約なら、線形計画で最適な生産配分を高速に求められます。

分析・モデル化の考え方

SciPyは最小化なので利益係数を負にします。需要上限と最低供給は変数境界に設定します。

Pythonで確認する

margin = products["margin"].to_numpy()
bounds = list(zip(products["minimum_supply"], products["demand_max"]))
lp = linprog(-margin, A_ub=A, b_ub=b, bounds=bounds, method="highs")
lp_plan = pd.DataFrame({"製品": products["product"], "生産量": lp.x, "需要上限": products["demand_max"]})
display(lp_plan.style.format({"生産量": "{:,.1f}", "需要上限": "{:,.0f}"}))
print(f"最大週次限界利益: ¥{-lp.fun:,.0f}")
fig, ax = plt.subplots()
x = np.arange(3)
ax.bar(x - 0.2, lp_plan["需要上限"], 0.4, label="需要上限", color="#bdbdbd")
ax.bar(x + 0.2, lp_plan["生産量"], 0.4, label="最適量", color="#2ca25f")
ax.set_xticks(x, lp_plan["製品"])
ax.set_title("線形計画による製品別生産量")
ax.set_xlabel("製品")
ax.set_ylabel("生産量(個/週)")
ax.grid(True, axis="y", alpha=0.3)
ax.legend()
plt.tight_layout()
plt.show()
  製品 生産量 需要上限
0 A 702.5 800
1 B 250.0 520
2 C 120.0 280
最大週次限界利益: ¥2,467,500


svg

結果の読み取り

限界利益と資源消費の組み合わせに基づく配分です。端数は連続緩和の結果であり、実際の個数・ロットへは整数化が必要です。


No.085:整数変数を使って個数や人数を表現する

実務での意味

製品個数、パレット数、人数は整数です。単純な丸めで制約を破らないよう整数計画で解きます。

分析・モデル化の考え方

xpZ0x_p\in\mathbb{Z}_{\ge0} とし、同じ目的・制約を混合整数計画へ渡します。

Pythonで確認する

integer = milp(
    c=-margin,
    integrality=np.ones(3),
    bounds=Bounds(products["minimum_supply"], products["demand_max"]),
    constraints=LinearConstraint(A, -np.inf, b),
)
integer_plan = pd.DataFrame({"製品": products["product"], "連続解": lp.x, "整数解": integer.x})
display(integer_plan.style.format({"連続解": "{:.2f}", "整数解": "{:.0f}"}))
print(f"整数解利益: ¥{-integer.fun:,.0f} / 連続解との差: ¥{(-lp.fun)-(-integer.fun):,.0f}")
  製品 連続解 整数解
0 A 702.50 702
1 B 250.00 250
2 C 120.00 120
整数解利益: ¥2,466,600 / 連続解との差: ¥900

結果の読み取り

整数解は実行可能な個数を返します。連続解との差は整数化の代償で、ロット単位なら変数をロット数として定義します。


No.086:二値変数を使って選択を表現する

実務での意味

製品を作ると固定段取り費が発生する場合、立上げ有無を0/1で表します。

分析・モデル化の考え方

yp{0,1}y_p\in\{0,1\}xpMpypx_p\le M_py_p として、生産なしなら xp=0x_p=0。目的に固定費 Fpyp-F_py_p を加えます。

Pythonで確認する

M = products["demand_max"].to_numpy()
fixed = products["setup_cost"].to_numpy()
c_bin = np.r_[-margin, fixed]
A_res = np.c_[A, np.zeros((3, 3))]
A_link = np.c_[np.eye(3), -np.diag(M)]
A_bin = np.vstack([A_res, A_link])
ub = np.r_[b, np.zeros(3)]
binary = milp(
    c=c_bin,
    integrality=np.ones(6),
    bounds=Bounds(np.zeros(6), np.r_[M, np.ones(3)]),
    constraints=LinearConstraint(A_bin, -np.inf, ub),
)
binary_plan = pd.DataFrame(
    {"製品": products["product"], "生産量": binary.x[:3], "立上げ": binary.x[3:].round().astype(int), "固定費": fixed}
)
display(binary_plan.style.format({"生産量": "{:,.0f}", "固定費": {:,.0f}"}))
print(f"固定費控除後利益: ¥{-binary.fun:,.0f}")
  製品 生産量 立上げ 固定費
0 A 800 1 ¥180,000
1 B 400 1 ¥260,000
2 C 0 0 ¥420,000
固定費控除後利益: ¥2,080,000

結果の読み取り

固定費が大きい製品は、少量生産より立上げない方が有利になる場合があります。Big-Mは需要上限など妥当な小さい値を使います。


No.087:シフト作成問題を定式化する

実務での意味

曜日別必要人数を満たすよう、5日連続勤務パターンへ検査員を割り当てます。

分析・モデル化の考え方

パターン別人数を整数変数とし、各曜日のカバー人数が必要数以上になる条件で総人数を最小化します。

Pythonで確認する

days = ["月", "火", "水", "木", "金", "土", "日"]
coverage = np.zeros((7, 7), int)
for start in range(7):
    for k in range(5):
        coverage[(start + k) % 7, start] = 1
required = np.array([8, 9, 10, 10, 9, 6, 5])
shift = milp(
    c=np.ones(7),
    integrality=np.ones(7),
    bounds=Bounds(np.zeros(7), np.full(7, np.inf)),
    constraints=LinearConstraint(coverage, required, np.inf),
)
assigned = np.rint(shift.x).astype(int)
actual = coverage @ assigned
shift_table = pd.DataFrame({"曜日": days, "必要人数": required, "配置人数": actual, "余裕": actual - required})
display(shift_table)
fig, ax = plt.subplots()
x = np.arange(7)
ax.bar(x - 0.2, required, 0.4, label="必要", color="#bdbdbd")
ax.bar(x + 0.2, actual, 0.4, label="配置", color="#2c7fb8")
ax.set_xticks(x, days)
ax.set_title("曜日別の必要人数と最適配置")
ax.set_xlabel("曜日")
ax.set_ylabel("検査員数(名)")
ax.grid(True, axis="y", alpha=0.3)
ax.legend()
plt.tight_layout()
plt.show()
print(f"必要検査員総数: {assigned.sum()}名 / パターン人数: {assigned.tolist()}")
曜日 必要人数 配置人数 余裕
0 8 8 0
1 9 9 0
2 10 10 0
3 10 10 0
4 9 9 0
5 6 6 0
6 5 8 3

svg

必要検査員総数: 12名 / パターン人数: [3, 1, 3, 0, 2, 0, 3]

結果の読み取り

全曜日の必要人数を満たす整数配置です。希望休、スキル、夜勤回数、公平性を追加すると実務シフトになります。


No.088:配送計画問題を定式化する

実務での意味

工場から複数顧客を巡回する順序で距離が変わります。小規模例を全列挙し、最短経路を求めます。

分析・モデル化の考え方

工場を出発・帰着する巡回セールスマン問題です。6地点なら顧客5点の 5!=1205!=120 経路を比較できます。

Pythonで確認する

locations = pd.DataFrame(
    {"name": ["工場", "顧客A", "顧客B", "顧客C", "顧客D", "顧客E"], "x": [0, 2, 5, 6, 3, 1], "y": [0, 6, 5, 1, 2, 3]}
)
xy = locations[["x", "y"]].to_numpy()
dist = np.linalg.norm(xy[:, None, :] - xy[None, :, :], axis=2)
routes = []
for perm in itertools.permutations(range(1, 6)):
    route = (0,) + perm + (0,)
    routes.append((sum(dist[route[i], route[i + 1]] for i in range(6)), route))
best_distance, best_route = min(routes)
names = [locations.iloc[i]["name"] for i in best_route]
print(f"最短距離: {best_distance:.2f}km / 経路: {' → '.join(names)}")
fig, ax = plt.subplots()
route_xy = xy[list(best_route)]
ax.plot(route_xy[:, 0], route_xy[:, 1], marker="o")
for _, r in locations.iterrows():
    ax.annotate(r["name"], (r["x"], r["y"]), xytext=(4, 4), textcoords="offset points")
ax.set_title("顧客巡回配送の最短経路")
ax.set_xlabel("東西距離(km)")
ax.set_ylabel("南北距離(km)")
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
最短距離: 20.38km / 経路: 工場 → 顧客D → 顧客C → 顧客B → 顧客A → 顧客E → 工場


svg

結果の読み取り

小規模では全列挙できますが、地点数増加で組合せが急増します。車両容量、時間窓、複数車両を加える場合は専用ソルバーや近似法を使います。


No.089:予算配分問題を定式化する

実務での意味

改善案件の費用・必要工数・期待効果から、予算と人員内で採択案件を選びます。

分析・モデル化の考え方

案件採択 yj{0,1}y_j\in\{0,1\}maxjvjyj\max\sum_jv_jy_j、予算・工数制約を持つ0-1ナップサックです。

Pythonで確認する

projects = pd.DataFrame(
    {
        "案件": ["予知保全", "自動検査", "段取り短縮", "需要予測", "倉庫自動化", "教育基盤"],
        "費用_百万円": [22, 30, 14, 12, 28, 8],
        "工数_人月": [5, 7, 4, 3, 6, 2],
        "期待効果_百万円": [38, 48, 25, 22, 39, 13],
    }
)
A_proj = projects[["費用_百万円", "工数_人月"]].T.to_numpy()
budget = milp(
    c=-projects["期待効果_百万円"],
    integrality=np.ones(len(projects)),
    bounds=Bounds(np.zeros(len(projects)), np.ones(len(projects))),
    constraints=LinearConstraint(A_proj, -np.inf, [60, 15]),
)
projects["採択"] = np.rint(budget.x).astype(int)
display(projects)
selected = projects.query("採択==1")
print(
    f"採択: {', '.join(selected['案件'])} / 費用 {selected['費用_百万円'].sum()}百万円 / 効果 {selected['期待効果_百万円'].sum()}百万円"
)
fig, ax = plt.subplots()
colors = np.where(projects["採択"] == 1, "#2ca25f", "#bdbdbd")
ax.scatter(projects["費用_百万円"], projects["期待効果_百万円"], s=120, c=colors)
for _, r in projects.iterrows():
    ax.annotate(r["案件"], (r["費用_百万円"], r["期待効果_百万円"]), xytext=(4, 4), textcoords="offset points")
ax.set_title("改善案件の費用・期待効果と採択結果")
ax.set_xlabel("投資費用(百万円)")
ax.set_ylabel("期待効果(百万円)")
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
案件 費用_百万円 工数_人月 期待効果_百万円 採択
0 予知保全 22 5 38 1
1 自動検査 30 7 48 1
2 段取り短縮 14 4 25 0
3 需要予測 12 3 22 0
4 倉庫自動化 28 6 39 0
5 教育基盤 8 2 13 1
採択: 予知保全, 自動検査, 教育基盤 / 費用 60百万円 / 効果 99百万円


svg

結果の読み取り

単純な効果費用比だけでなく、予算と工数を同時に満たす組合せです。案件依存、リスク、戦略必須案件を追加します。


No.090:最適化モデルの結果を業務判断に翻訳する

実務での意味

最適値を、生産指示、制約余力、要員、配送、投資、注意事項へ翻訳して初めて実行できます。

分析・モデル化の考え方

解、目的値、制約使用率、余力、前提、代替案を意思決定表にまとめます。感度と現場制約を確認します。

Pythonで確認する

xopt = integer.x
uses = A @ xopt
decision_summary = pd.DataFrame(
    {
        "意思決定": ["製品A/B/C生産", "検査員", "配送", "改善投資"],
        "推奨": [
            f"{xopt[0]:.0f}/{xopt[1]:.0f}/{xopt[2]:.0f}個",
            f"{assigned.sum()}名",
            "→".join(names),
            ", ".join(selected["案件"]),
        ],
        "確認事項": [
            f"設備{uses[0]/b[0]:.1%}・作業{uses[1]/b[1]:.1%}・材料{uses[2]/b[2]:.1%}",
            "希望休・スキル制約",
            "時間窓・積載量",
            "効果不確実性・案件依存",
        ],
    }
)
display(decision_summary)
resource_use = pd.DataFrame({"資源": ["設備", "作業", "材料"], "使用量": uses, "能力": b})
resource_use["使用率"] = resource_use["使用量"] / resource_use["能力"]
fig, ax = plt.subplots()
ax.bar(resource_use["資源"], resource_use["使用率"] * 100, color="#756bb1")
ax.axhline(100, color="black", linestyle="--")
ax.set_title("最適生産計画の資源使用率")
ax.set_xlabel("資源")
ax.set_ylabel("使用率(%)")
ax.grid(True, axis="y", alpha=0.3)
plt.tight_layout()
plt.show()
bottleneck = resource_use.loc[resource_use["使用率"].idxmax()]
print(f"最も逼迫する資源: {bottleneck['資源']}{bottleneck['使用率']:.1%})")
意思決定 推奨 確認事項
0 製品A/B/C生産 702/250/120個 設備100.0%・作業94.7%・材料74.5%
1 検査員 12名 希望休・スキル制約
2 配送 工場→顧客D→顧客C→顧客B→顧客A→顧客E→工場 時間窓・積載量
3 改善投資 予知保全, 自動検査, 教育基盤 効果不確実性・案件依存

svg

最も逼迫する資源: 設備(100.0%)

結果の読み取り

生産量だけでなくボトルネックと未反映条件を示します。最適解をそのまま指示せず、丸め、段取り順、品質、納期、変更耐性を現場レビューします。


対象ノックを通して見える実務上の示唆

最適化では、意思決定変数・目的関数・制約の定義が結果を決めます。連続、整数、二値を業務単位に合わせ、シフト・配送・投資も同じ枠組みで扱えます。最適値だけでなく制約余力、前提、代替案、感度を提示することが重要です。

実務導入する場合に必要なこと

1. 意思決定の周期と単位を決める

日次・週次、個・ロット・人を統一します。

2. ハード制約と目標を区別する

安全・法令・契約は制約、納期希望などはペナルティ化を検討します。

3. パラメータ根拠を管理する

能力、工数、利益、需要上限、固定費の責任者と更新頻度を決めます。

4. 現行計画と並行比較する

利益だけでなく変更数、残業、納期、現場負荷を評価します。

5. infeasible時の運用を決める

どの制約を緩和し、誰が承認するかを定義します。

6. 結果を実行形式へ変換する

生産指示、シフト表、配送順、投資案件表として現場へ渡します。

まとめ

No.081〜090では、生産量、立上げ、シフト、配送、投資を最適化モデルとして表しました。数理最適化の価値は最大値を得ることだけでなく、資源競合とトレードオフを見える形にし、実行可能な判断を比較できることにあります。

法人向けのご相談

数理工房では、生産計画、要員シフト、配送、設備割当、投資配分の数理最適化PoCと運用設計を支援しています。

📩 お問い合わせ: surikobo.co.jp/contact まずはお気軽にご相談ください。