100本ノック / シミュレーション / シミュレーション100本ノック
製造業のエージェントベースシミュレーション入門|Pythonで学ぶABM実践10選
製造現場を「個の動き」から読み解く:エージェントベース・シミュレーション実践10本
本記事では、設備・作業者・搬送車・取引先をそれぞれ意思決定する主体(エージェント)として扱い、局所的な行動が工場全体の安全性、納期、在庫、利益にどう波及するかを No.051〜No.060 の10本で確認します。平均値だけでは見えにくい混雑、連鎖停止、改善活動の浸透を、再現可能な架空データと Python で検討します。
[!NOTE] 本資料は、数理工房 (もしくは代表である和山個人) が過去に企業研修において使用した notebook を企業様の許可を得て再構成・編集のうえ公開しています。 掲載データはすべて架空のものであり、実在する企業・工場・数値とは一切関係ありません。
はじめに:この記事で扱う製造業の実務課題
対象は、多品種部品を組み立てる架空の工場です。現場には技能の異なる作業者、複数の AGV、納期や供給安定性の異なる取引先が存在します。検討したい意思決定は、①安全な動線、②搬送ルール、③仕入先分散、④改善行動の定着、⑤自律制御の導入です。
現場でよくある状況
月次平均の稼働率は適正でも、休憩明けだけ通路が混雑することがあります。平均需要を満たす発注量でも、一社の遅延がライン停止を起こします。また、標準作業を通知しても、現場の相談関係によって浸透速度は異なります。個体差と相互作用を消して集計すると、これらの現象を説明できません。
なぜこの問題は判断が難しいのか
エージェント の状態を 、行動を 、近傍を とすると、更新は概念的に
と表せます。全体 KPI は ですが、 が非線形で近傍も変化するため、平均的な一主体を調べるだけでは全体結果を推定できません。ABM は予言装置ではなく、「どの仮定なら、どの結果が起きるか」を比較する実験装置です。
今回扱うノックの全体像
| No. | テーマ | 製造業での判断 |
|---|---|---|
| 051 | ABMとは | 集計モデルと個体モデルの使い分け |
| 052 | エージェント設計 | 状態・行動・ルールの定義 |
| 053 | 群集 | 避難・通路混雑の評価 |
| 054 | 交通流 | AGV密度と搬送能力 |
| 055 | 市場 | 価格・品質・納期の受注影響 |
| 056 | 感染症 | 接触を介した欠勤リスク |
| 057 | サプライチェーン | 発注連鎖とブルウィップ |
| 058 | 組織 | 改善行動の浸透 |
| 059 | 強化学習との融合 | 状態別搬送ルールの学習 |
| 060 | Mesa入門 | モデル実装の標準形 |
Python 環境の準備
乱数生成器は default_rng に統一し、各実験で seed を明示します。グラフは比較可能な単位と軸を付けます。
import sys
import numpy as np
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
from dataclasses import dataclass
try:
import japanize_matplotlib # 日本語フォント設定
except ImportError:
pass
pd.set_option("display.precision", 2)
print(f"Python {sys.version.split()[0]}")
print(f"numpy {np.__version__} / pandas {pd.__version__} / matplotlib {matplotlib.__version__}")
Python 3.13.1
numpy 2.5.1 / pandas 3.0.3 / matplotlib 3.11.0
架空データの作成
30名の作業者に、技能、歩行速度、改善への受容性、所属班を付与します。これは個人評価ではなく、個体差を持つモデルの入力例です。実務では匿名化、粒度、利用目的を労使で合意する必要があります。
rng = np.random.default_rng(1606)
n_workers = 30
workers = pd.DataFrame({
"worker_id": [f"W{i:02d}" for i in range(1, n_workers + 1)],
"team": rng.choice(list("ABC"), n_workers),
"skill": np.clip(rng.normal(0.75, 0.12, n_workers), 0.4, 1.0),
"walk_speed_m_s": np.clip(rng.normal(1.25, 0.15, n_workers), 0.8, 1.6),
"improvement_receptivity": rng.beta(3, 2, n_workers),
})
workers.head()
| worker_id | team | skill | walk_speed_m_s | improvement_receptivity | |
|---|---|---|---|---|---|
| 0 | W01 | B | 0.81 | 1.48 | 0.82 |
| 1 | W02 | A | 0.64 | 1.32 | 0.79 |
| 2 | W03 | B | 0.78 | 0.81 | 0.49 |
| 3 | W04 | B | 0.73 | 1.46 | 0.53 |
| 4 | W05 | C | 0.45 | 1.33 | 0.74 |
No.051:ABMとは
実務での意味
集計値では消える異質性を残し、局所ルールから全体 KPI が創発する過程を観察します。工場では、同じ平均処理能力でも技能の偏りや応援行動によって滞留が変わります。
分析・モデル化の考え方
各作業者に技能を与え、処理成功をベルヌーイ試行として再現します。均質モデルと異質モデルの平均だけでなく、日別の下振れリスクを比較します。
Pythonで確認する
rng = np.random.default_rng(51)
days, jobs = 500, 120
hetero = np.array([(rng.random(jobs) < rng.choice(workers.skill, jobs)).sum() for _ in range(days)])
mean_skill = workers.skill.mean()
homogeneous = rng.binomial(jobs, mean_skill, days)
result_051 = pd.DataFrame({"model": ["異質な作業者", "平均的な作業者"], "平均完成数": [hetero.mean(), homogeneous.mean()], "5%点": [np.quantile(hetero,.05), np.quantile(homogeneous,.05)]})
display(result_051.round(1))
plt.figure(figsize=(7, 3.5)); plt.hist(hetero, bins=15, alpha=.65, label="異質"); plt.hist(homogeneous, bins=15, alpha=.55, label="均質")
plt.title("日別完成数の分布"); plt.xlabel("完成数 [個/日]"); plt.ylabel("日数"); plt.grid(alpha=.3); plt.legend(); plt.tight_layout(); plt.show()
| model | 平均完成数 | 5%点 | |
|---|---|---|---|
| 0 | 異質な作業者 | 83.6 | 75.0 |
| 1 | 平均的な作業者 | 83.1 | 75.0 |

結果の読み取り
平均完成数が近くても下側分位点が違えば、納期保証に必要な余力は異なります。ABM の価値は平均を精密に当てることより、異質性が生む裾のリスクを意思決定に載せる点にあります。
No.052:エージェント設計
実務での意味
モデルの説明可能性は、誰が、何を観測し、どう動くかを業務用語で定義できるかに左右されます。属性を増やすほど良いのではなく、意思決定に必要な差だけを残します。
分析・モデル化の考え方
作業者を skill、fatigue、available の状態と、作業する・休むという行動で表します。疲労は生産性を下げ、休憩で回復する単純な状態遷移です。
Pythonで確認する
@dataclass
class WorkerAgent:
skill: float
fatigue: float = 0.0
produced: int = 0
def step(self, rng):
if self.fatigue > 0.75:
self.fatigue = max(0, self.fatigue - 0.35); return "休憩"
success = rng.random() < self.skill * (1 - 0.35*self.fatigue)
self.produced += int(success); self.fatigue = min(1, self.fatigue + 0.08)
return "生産"
rng = np.random.default_rng(52); agents = [WorkerAgent(s) for s in workers.skill[:8]]
records=[]
for t in range(40):
for i,a in enumerate(agents): records.append((t,i,a.step(rng),a.fatigue,a.produced))
trace_052=pd.DataFrame(records,columns=["時点","agent","行動","疲労","累積生産"])
display(trace_052.groupby("行動").size().rename("回数").to_frame())
avg=trace_052.groupby("時点").疲労.mean(); plt.figure(figsize=(7,3.5)); plt.plot(avg.index,avg.values)
plt.title("平均疲労の時間推移"); plt.xlabel("時点"); plt.ylabel("疲労度"); plt.grid(alpha=.3); plt.tight_layout(); plt.show()
| 回数 | |
|---|---|
| 行動 | |
| 休憩 | 48 |
| 生産 | 272 |

結果の読み取り
休憩ルールにより疲労が周期的に下がることを確認できます。実務では疲労度を恣意的に推定せず、休憩記録、作業負荷、人間工学上の根拠を使い、個人監視ではなく工程設計に利用します。
No.053:群集シミュレーション
実務での意味
交替時や避難時には、最短経路を全員が選ぶとかえって出口が詰まります。ピーク密度と避難完了時間を比較し、通路幅や誘導方針の投資判断に使います。
分析・モデル化の考え方
2つの出口に作業者が集中する簡易モデルです。出口ごとの処理能力を持たせ、近い出口へ90%集中する場合と、混雑を見て分散する場合を比較します。
Pythonで確認する
def evacuate(seed, adaptive, n=120):
rng=np.random.default_rng(seed); queues=[0,0]; done=[]
for _ in range(n):
choice=int(np.argmin(queues)) if adaptive and rng.random()<.85 else int(rng.random()>.8)
queues[choice]+=1; done.append(queues[choice]/[3.0,2.5][choice])
return max(done), max(queues)
rows=[]
for policy in [False,True]:
vals=[evacuate(s,policy) for s in range(300)]
rows.append(["固定誘導" if not policy else "混雑分散",np.mean(vals,0)[0],np.quantile(np.array(vals)[:,0],.95),np.mean(vals,0)[1]])
result_053=pd.DataFrame(rows,columns=["方針","平均避難時間","95%避難時間","最大待ち人数"]); display(result_053.round(1))
plt.figure(figsize=(6,3.5)); plt.bar(result_053.方針,result_053["95%避難時間"]); plt.title("誘導方針別の避難時間"); plt.xlabel("誘導方針"); plt.ylabel("95%避難時間 [分]"); plt.grid(axis="y",alpha=.3); plt.tight_layout(); plt.show()
| 方針 | 平均避難時間 | 95%避難時間 | 最大待ち人数 | |
|---|---|---|---|---|
| 0 | 固定誘導 | 32.0 | 34.3 | 96.0 |
| 1 | 混雑分散 | 23.9 | 24.0 | 60.2 |

結果の読み取り
混雑分散で95%点が短縮するなら、床面表示やデジタルサイネージの価値を定量化できます。ただし安全設計は本モデルだけで確定せず、法令、実地訓練、専門家レビューを優先します。
No.054:交通流シミュレーション
実務での意味
AGVを増やせば搬送量が比例して増えるとは限りません。交差点干渉や追従による速度低下を含め、台数追加の限界効果を見ます。
分析・モデル化の考え方
密度 に対して速度が と低下する基本図式を、個々のAGVの速度差を残して再現します。流量は です。
Pythonで確認する
rng=np.random.default_rng(54); rows=[]
for n in range(2,31,2):
density=n/100
speeds=np.clip(rng.normal(1.5*(1-density/.38),.06,n),.05,None)
rows.append((n,speeds.mean(),density*speeds.mean()*3600))
result_054=pd.DataFrame(rows,columns=["AGV台数","平均速度_m_s","流量_台時"]); display(result_054.loc[result_054.流量_台時.nlargest(3).index].round(2))
plt.figure(figsize=(7,3.5)); plt.plot(result_054.AGV台数,result_054.流量_台時,marker="o"); plt.title("AGV台数と搬送流量"); plt.xlabel("AGV台数 [台]"); plt.ylabel("流量 [台・通過/時]"); plt.grid(alpha=.3); plt.tight_layout(); plt.show()
| AGV台数 | 平均速度_m_s | 流量_台時 | |
|---|---|---|---|
| 8 | 18 | 0.80 | 515.30 |
| 10 | 22 | 0.65 | 515.08 |
| 9 | 20 | 0.71 | 511.15 |

結果の読み取り
曲線の頂点を越える増車は、速度低下により逆効果になり得ます。実導入では交差点占有時間、充電、故障、優先制御を追加し、台数だけでなく経路分離も候補にします。
No.055:市場シミュレーション
実務での意味
製造業の受注は価格だけでなく、品質と納期に反応する顧客群の構成で変わります。値下げと品質投資のどちらが粗利に効くかを顧客単位で比較します。
分析・モデル化の考え方
顧客 の効用を とし、競合より効用が高い場合に受注します。嗜好重みは顧客ごとに異なります。
Pythonで確認する
rng=np.random.default_rng(55); n=1000
w=rng.dirichlet([3,4,2],n); competitor=-w[:,0]*100+w[:,1]*82-w[:,2]*8
scenarios={"現状":(102,85,7,35),"値下げ":(96,85,7,29),"品質投資":(102,92,6,33)}; rows=[]
for name,(p,q,l,margin) in scenarios.items():
utility=-w[:,0]*p+w[:,1]*q-w[:,2]*l+rng.normal(0,2,n)
share=(utility>competitor).mean(); rows.append((name,share,share*n*margin))
result_055=pd.DataFrame(rows,columns=["施策","受注率","粗利指数"]); display(result_055.round(2))
plt.figure(figsize=(6,3.5)); plt.bar(result_055.施策,result_055.粗利指数); plt.title("市場施策別の期待粗利"); plt.xlabel("施策"); plt.ylabel("粗利指数"); plt.grid(axis="y",alpha=.3); plt.tight_layout(); plt.show()
| 施策 | 受注率 | 粗利指数 | |
|---|---|---|---|
| 0 | 現状 | 0.66 | 23240.0 |
| 1 | 値下げ | 0.94 | 27202.0 |
| 2 | 品質投資 | 0.94 | 30954.0 |

結果の読み取り
受注率最大と粗利最大は一致しない場合があります。顧客セグメント別の重みを実績から校正し、競合条件を振っても施策順位が頑健か確認することが重要です。
No.056:感染症シミュレーション
実務での意味
感染拡大は従業員の健康だけでなく、同時欠勤による技能不足と納期遅延につながります。班間接触を減らす施策の事業継続効果を評価します。
分析・モデル化の考え方
SIR型の個体モデルで、感受性 S、感染 I、回復 R を持たせます。各日、感染者との接触回数に応じて感染確率 を計算します。
Pythonで確認する
def outbreak(seed, split, n=80, days=35):
rng=np.random.default_rng(seed); state=np.zeros(n,int); state[0]=1; age=np.zeros(n,int); peak=1
for _ in range(days):
inf=np.where(state==1)[0]; new=[]
for i in np.where(state==0)[0]:
contacts=sum((rng.random(len(inf)) < (0.035 if split else 0.07)))
if rng.random()<1-(1-.12)**contacts:new.append(i)
age[inf]+=1; state[np.array(new,int)]=1; state[(state==1)&(age>=6)]=2; peak=max(peak,(state==1).sum())
return peak,(state==2).sum()
rows=[]
for split in [False,True]:
a=np.array([outbreak(s,split) for s in range(400)])
rows.append(("通常" if not split else "班分離",a[:,0].mean(),np.quantile(a[:,0],.95),a[:,1].mean()))
result_056=pd.DataFrame(rows,columns=["勤務方式","平均ピーク感染者","95%ピーク感染者","平均累計感染者"]); display(result_056.round(1))
plt.figure(figsize=(6,3.5)); plt.bar(result_056.勤務方式,result_056["95%ピーク感染者"]); plt.title("勤務方式別の同時感染リスク"); plt.xlabel("勤務方式"); plt.ylabel("95%ピーク感染者 [人]"); plt.grid(axis="y",alpha=.3); plt.tight_layout(); plt.show()
| 勤務方式 | 平均ピーク感染者 | 95%ピーク感染者 | 平均累計感染者 | |
|---|---|---|---|---|
| 0 | 通常 | 52.7 | 61.0 | 77.1 |
| 1 | 班分離 | 20.1 | 36.0 | 46.0 |

結果の読み取り
班分離はピークを抑え、重要技能の同時欠勤を減らす可能性があります。これは医療予測ではありません。実際の対策は公的ガイダンスと産業医の助言に従い、モデルはBCPの要員余力検討に限定します。
No.057:サプライチェーンシミュレーション
実務での意味
各段階が自社在庫だけを見て発注すると、需要の小さな揺れが上流で増幅します。欠品削減と在庫増加のトレードオフを確認します。
分析・モデル化の考え方
小売・卸・工場の3段階が目標在庫との差を補充する order-up-to ルールを使います。情報共有の有無で発注量の分散、すなわちブルウィップ比を比較します。
Pythonで確認する
def chain(seed, shared, T=100):
rng=np.random.default_rng(seed); demand=np.maximum(0,rng.normal(20,3,T)); inv=np.array([40.,40.,40.]); orders=[]
prev=np.array([20.,20.,20.])
for t,d in enumerate(demand):
signal=np.repeat(d,3) if shared else np.r_[d,prev[:2]]
order=np.maximum(0,20+.55*(40-inv)+.45*(signal-20)); inv+=prev-order; prev=order; orders.append(order)
return demand,np.array(orders)
rows=[]
for shared in [False,True]:
d,o=chain(57,shared); rows.append(("個別判断" if not shared else "需要共有",*(o.var(0)/d.var())))
result_057=pd.DataFrame(rows,columns=["方式","小売ブルウィップ比","卸ブルウィップ比","工場ブルウィップ比"]); display(result_057.round(2))
plt.figure(figsize=(7,3.5)); x=np.arange(3); plt.bar(x-.18,result_057.iloc[0,1:],.36,label="個別判断"); plt.bar(x+.18,result_057.iloc[1,1:],.36,label="需要共有"); plt.xticks(x,["小売","卸","工場"]); plt.title("発注変動の増幅"); plt.xlabel("段階"); plt.ylabel("発注分散 / 需要分散"); plt.grid(axis="y",alpha=.3); plt.legend(); plt.tight_layout(); plt.show()
| 方式 | 小売ブルウィップ比 | 卸ブルウィップ比 | 工場ブルウィップ比 | |
|---|---|---|---|---|
| 0 | 個別判断 | 0.32 | 0.17 | 0.11 |
| 1 | 需要共有 | 0.32 | 0.32 | 0.32 |

結果の読み取り
需要共有で上流の分散が下がれば、EDIや共通ダッシュボードの便益を在庫・能力計画に換算できます。リードタイム、最小ロット、供給制約を追加してから契約変更を判断します。
No.058:組織シミュレーション
実務での意味
改善策は内容が正しくても、相談関係や管理者の働きかけ次第で定着しません。研修対象者の選び方と現場リーダーの配置を検討します。
分析・モデル化の考え方
作業者間のネットワーク上で、採用済みの同僚比率と本人の受容性から次期の採用確率を決めます。無作為な初期教育と、つながりの多い人への教育を比較します。
Pythonで確認する
rng=np.random.default_rng(58); n=30; A=(rng.random((n,n))<.12).astype(int); A=np.triu(A,1); A=A+A.T; degree=A.sum(1)
def diffuse(seed, targeted):
rng=np.random.default_rng(seed); adopted=np.zeros(n,bool); initial=np.argsort(degree)[-3:] if targeted else rng.choice(n,3,False); adopted[initial]=True; hist=[adopted.sum()]
for _ in range(15):
ratio=(A@adopted)/np.maximum(degree,1); p=np.clip(.03+.55*ratio+workers.improvement_receptivity.to_numpy()*.12,0,1)
adopted |= rng.random(n)<p; hist.append(adopted.sum())
return hist
h_random=np.mean([diffuse(s,False) for s in range(200)],0); h_target=np.mean([diffuse(s,True) for s in range(200)],0)
result_058=pd.DataFrame({"週":range(16),"無作為教育":h_random,"中心者教育":h_target}); display(result_058.tail().round(1))
plt.figure(figsize=(7,3.5)); plt.plot(result_058.週,result_058.無作為教育,label="無作為教育"); plt.plot(result_058.週,result_058.中心者教育,label="中心者教育"); plt.title("改善行動の平均採用人数"); plt.xlabel("週"); plt.ylabel("採用人数 [人]"); plt.grid(alpha=.3); plt.legend(); plt.tight_layout(); plt.show()
| 週 | 無作為教育 | 中心者教育 | |
|---|---|---|---|
| 11 | 11 | 29.9 | 30.0 |
| 12 | 12 | 30.0 | 30.0 |
| 13 | 13 | 30.0 | 30.0 |
| 14 | 14 | 30.0 | 30.0 |
| 15 | 15 | 30.0 | 30.0 |

結果の読み取り
中心者への先行教育が初期浸透を速める可能性があります。ただしネットワーク分析を人事評価に転用せず、本人同意とプライバシー保護の下で、公式な支援役を設計する材料にします。
No.059:強化学習との融合
実務での意味
固定ルールでは、通常時と混雑時の両方に適した搬送判断を作りにくいことがあります。シミュレータを安全な試行環境として、状態別ルールを学習します。
分析・モデル化の考え方
待ち行列を状態、通常搬送・迂回を行動、遅延と迂回費を負の報酬とする Q-learning の最小例です。更新式は です。
Pythonで確認する
rng=np.random.default_rng(59); Q=np.zeros((3,2)); alpha=.12; gamma=.9; eps=.15; rewards=[]
for ep in range(3000):
s=rng.integers(0,3); a=rng.integers(0,2) if rng.random()<eps else np.argmax(Q[s]); congestion=[1,4,9][s]
delay=(congestion+rng.normal(0,.7)) if a==0 else (3.2+rng.normal(0,.4)); r=-delay-(.8 if a==1 else 0)
ns=min(2,max(0,s+rng.choice([-1,0,1],p=[.2,.6,.2]))); Q[s,a]+=alpha*(r+gamma*Q[ns].max()-Q[s,a]); rewards.append(r)
policy=pd.DataFrame({"混雑状態":["低","中","高"],"選択行動":np.where(Q.argmax(1)==0,"通常経路","迂回"),"通常Q":Q[:,0],"迂回Q":Q[:,1]}); display(policy.round(2))
roll=pd.Series(rewards).rolling(150).mean(); plt.figure(figsize=(7,3.5)); plt.plot(roll); plt.title("学習中の移動平均報酬"); plt.xlabel("エピソード"); plt.ylabel("平均報酬"); plt.grid(alpha=.3); plt.tight_layout(); plt.show()
| 混雑状態 | 選択行動 | 通常Q | 迂回Q | |
|---|---|---|---|---|
| 0 | 低 | 通常経路 | -23.11 | -25.20 |
| 1 | 中 | 迂回 | -32.70 | -30.13 |
| 2 | 高 | 迂回 | -39.13 | -33.02 |

結果の読み取り
高混雑時だけ迂回する方針が得られれば、条件分岐として人が検証できます。本番設備へ直接接続せず、制約違反を許さない安全層、オフライン評価、手動切替、監視 KPI を用意します。
No.060:Mesa入門
実務での意味
ABMを継続利用するには、エージェント、モデル、スケジューラ、データ収集を分離した実装が必要です。Mesaはこの構造を提供するPythonフレームワークです。
分析・モデル化の考え方
追加依存なしで動く MiniModel に、Mesaと同じ発想の step とデータ収集を実装します。実案件では Mesa の Agent、Model、DataCollector に置き換えられます。
Pythonで確認する
class MiniModel:
def __init__(self, seed=60, n=20):
self.rng=np.random.default_rng(seed); self.agents=[WorkerAgent(float(s)) for s in workers.skill[:n]]; self.history=[]
def step(self):
actions=[a.step(self.rng) for a in self.agents]
self.history.append({"step":len(self.history),"total_output":sum(a.produced for a in self.agents),"resting":actions.count("休憩")})
model=MiniModel()
for _ in range(50): model.step()
result_060=pd.DataFrame(model.history); display(result_060.tail())
fig,ax1=plt.subplots(figsize=(7,3.5)); ax1.plot(result_060.step,result_060.total_output,label="累積生産"); ax1.set_xlabel("ステップ"); ax1.set_ylabel("累積生産 [個]"); ax2=ax1.twinx(); ax2.plot(result_060.step,result_060.resting,color="tab:orange",alpha=.6,label="休憩者"); ax2.set_ylabel("休憩者 [人]"); ax1.set_title("モデルのKPI収集"); ax1.grid(alpha=.3); fig.tight_layout(); plt.show()
| step | total_output | resting | |
|---|---|---|---|
| 45 | 45 | 462 | 0 |
| 46 | 46 | 474 | 0 |
| 47 | 47 | 483 | 0 |
| 48 | 48 | 483 | 20 |
| 49 | 49 | 494 | 0 |

結果の読み取り
モデル構造とKPI収集を分離すると、ルール変更と検証が容易になります。Mesa採用自体を目的にせず、モデル仕様書、seed管理、単体テスト、感度分析、実績との校正を含む運用工程を設計します。
対象ノックを通して見える実務上の示唆
10本に共通するのは、平均値よりも「ばらつき・接触・局所判断」を明示することです。ABMは、増車、班分離、情報共有、教育対象の選定といった施策を、現場へ投入する前に比較できます。一方、結果は仮定の帰結です。単一の予測値ではなく、複数 seed の分布、下側・上側分位点、施策順位が変わる境界を報告すべきです。
実務導入する場合に必要なこと
- 意思決定を先に定義する:何を何月までに決め、誤判断の費用はいくらかを定めます。
- 境界と粒度を合意する:工程、時間単位、主体、状態、行動、外生条件を仕様書にします。
- 校正と妥当性確認を分ける:一部期間でパラメータを合わせ、別期間・別シフトで再現性を確認します。
- 感度分析を行う:接触率や処理能力など不確かな入力を振り、結論が反転する条件を示します。
- 現場レビューを組み込む:モデルにない例外、暗黙知、安全制約を作業者と管理者が確認します。
- 運用責任を決める:データ更新、版管理、承認、監視、廃止基準まで定義します。
まとめ
No.051〜060では、ABMの基本から、群集、交通、市場、感染、サプライチェーン、組織、強化学習、実装構造までを製造業の意思決定に結び付けました。最初は説明可能な小さなモデルから始め、実績とのずれを学びながら段階的に詳細化することが、投資対効果と現場の信頼を両立させます。
法人向けのご相談
数理工房では、工場内物流、生産・在庫、サプライチェーン、要員配置などを対象に、課題整理からモデル設計、PoC、現場運用まで支援します。「データが十分か分からない」「市販ツールと内製のどちらがよいか」といった段階からご相談いただけます。
📩 お問い合わせ: surikobo.co.jp/contact まずはお気軽にご相談ください。