こんにちは。Anagraftの伊藤です。
AI活用のご相談をいただくとき、話題の中心になるのは需要予測や異常検知といった「予測するAI」であることが多いように思います。一方で、予測した数字を受けて「では、いくつ発注するのか」「誰をどの時間帯に配置するのか」を決める工程は、いまも表計算ソフトと担当者の経験に委ねられている企業が少なくありません。この「決める」側を担う技術が数理最適化です。
数理最適化のプロジェクトで最も難しいのは、ソルバーの使い方でもアルゴリズムの理論でもなく、目の前の業務課題を数式の形に翻訳する定式化の工程です。ここを外すと、どれほど高性能なソルバーを使っても現場で使えない答えが返ってきます。逆に言えば、定式化の型をいくつか押さえておくだけで、自社のどの業務が最適化の対象になり得るかを見立てられるようになります。定式化という言葉は聞き慣れないかもしれませんが、その中身は「何を決めるのか」「何をもって良しとするのか」「何を守るのか」を書き出す作業であり、数学の問題を解くというより、業務の判断基準を言語化する工程に近いものです。
本コラムは、この定式化の型を、業務課題の側から整理した実践ガイドです。前半では、国内企業の導入事例、定式化の3点セット、問題クラスの見分け方、業務課題と型の対応表、条件を数式に載せる表現テクニックという順で、どの課題にも共通する土台を組み立てます。後半では、生産計画、シフト作成、拠点配置、輸送、在庫、投資選定、配送ルートという7つの業務課題を1章ずつ取り上げ、検算済みの例題で具体的な書き下し方を示したうえで、実務規模に広げるときの制約の足し方や運用上の論点まで踏み込みます。終盤の2章では、書き上げたモデルをPythonで動かして確かめる方法と、定式化をプロジェクトとして進めて運用に定着させるまでの判断を扱います。各章の末尾には、その章を深めたい方への参考書籍を1冊ずつ添えました。
扱う内容は、数量の計算だけにとどめていません。「設備をあと1時間増やしたら利益はいくら増えるのか」「勤務希望はどこまで通せるのか」「避けられない欠品はどの店舗に配るのか」といった、経営判断や現場との合意に直結する問いを、各章の後半に配置しています。前提知識としては、不等式と一次式が読めれば十分で、行列やアルゴリズムの知識は仮定していません。コードが登場するのは第13章だけで、それ以外の章は日本語と最小限の数式で読み通せます。
想定している読者は次のような方々です。
全14章は、事例と考え方の土台(第1章から第5章)、業務課題別の定式化パターン(第6章から第12章)、実装と運用(第13章と第14章)の三段構えです。業務課題別の7つの章には、2種類の製品の生産量、カフェのシフト、5つの候補地からの出店選定、2つの倉庫から3つの店舗への配分、部品の発注量、施策の選定、20地点の配送ルートというように、部門の打ち合わせでそのまま話題にできる規模の例題を、章ごとに1つずつ配置しました。解が出ないときの調べ方や、出てきた計画を現場に説明するときの見せ方といった、導入後に必ず突き当たる話題も本編に含めています。章は積み上げの順に並べていますが、各章はできるだけ独立して読めるように作りましたので、この後の「全体の地図」や第4章の対応表から自社の課題に近い章を引き当てて、そこから読み始めるという使い方も想定しています。数式は本質の理解に必要な最小限にとどめ、例題の数値はすべて検算を済ませたものだけを載せました。なお、本文の例題はいずれも架空の設定で作っており、実在の企業の取り組みとして扱っているのは、第1章で出典とともに紹介する事例だけです。巻末には、各章末で紹介した参考書籍の一覧と、本文で参照した出典をまとめています。
目次
予測の仕組みを導入した企業で、その先の工程がどうなっているかをたどると、投資の効果が途中で止まっている例に行き当たります。需要予測システムが来月の販売数を品目ごとに出力していても、発注量そのものは前年同月の実績を写した表で決められている、という運用は珍しくありません。シフト作成の担当者が毎月数日を勤務表づくりに費やしているのに、その組み方の基準はどこにも書かれておらず、後任に引き継げないという状態も、業種を問わず見られます。決め方の根拠が記録に残らないため、改善の議論も担当者の感覚を超えられないままになります。
予測の側では、実験段階の取り組みが日々の業務の道具へと移ってきました。決める側の工程が同じようには移っていないのは、そこに求められるものが違うからです。予測に必要なのは過去のデータですが、決定に必要なのは、守るべき条件と、何をもって良い計画とするかの基準です。前者はシステムに蓄積されていきますが、後者は多くの場合、担当者の頭の中にあって、どこにも書き出されていません。この非対称が、予測だけが先に進んだ理由にあたります。
この状態には、はっきりした費用が伴っています。計画の品質が作る人によって変わること。作れる人が限られるために、担当者の異動や退職がそのまま業務の危機になること。そして、計画を1つ作るのに長い時間がかかるため、条件を変えた案を並べて比較する検討がそもそもできないことです。予測の精度をさらに数ポイント上げる投資と、決める工程を計算で扱える形に直す投資を比べたとき、後者のほうが成果に近い位置にあるケースは少なくないと考えています。
決める工程を計算に載せる技術が数理最適化であり、その中心にあるのが、業務課題を数式の形に翻訳する定式化の工程です。第1章で確認するとおり、国内の導入事例で成果を生んだ要因は、高性能なソルバーそのものではなく、熟練者が頭の中で処理していた判断の条件を、明示的な言葉と式に書き出せたことにあります。数式の形に落ちてしまえば、解く作業は既存のソルバーが担ってくれます。その手前にある、何を決めるのか、何をもって良い計画とするのか、何を守るのかを書き出す部分こそが、プロジェクトの成否を分けます。
そして、この翻訳には型があります。実務で持ち込まれる計画業務の大半は、すでに名前が付き、解き方が確立された定番のパターンのどれかに収まります。ゼロから数式を発明する必要はなく、自社の課題がどの型に最も近いかを見立てて、その型の書き方に当てはめていけばよいということです。本コラムが一貫して扱うのは、この「どの業務課題が、どの定式化パターンに対応するか」という対応関係であり、全14章はこの軸に沿って組み立てています。
定式化と聞くと専門家だけの数学的な作業を想像されるかもしれませんが、実際の中身は、業務の判断基準を、関係者が読んで検証できる形に書き出す言語化の作業です。だからこそ、この工程の主役は分析の担当者だけではありません。条件を知っている現場と、何を良しとするかを決められる立場の方が加わって、はじめて成立します。本コラムを分析の専門家以外の方にも読める形で書いたのは、この理由によります。
定式化の型を知ることの価値は、自分でモデルを書けるようになることに限りません。どの業務が最適化に向くのかを見立てられること、社内の分析チームや外部ベンダーの提案の筋の良し悪しを判断できること、解が出なかったときにどこを疑えばよいかの当たりが付くこと。いずれも、発注側や意思決定側の立場でこそ効いてくる力です。
そのため本コラムでは、数式そのものよりも、数式の手前にある考え方の説明に重心を置きました。例題はいずれも小さな数値で作り、手元で検算できる形にしています。また、自社の課題から該当する章へ直接たどり着けるよう、章立ては業務課題の側から組みました。この後の「全体の地図」に、章と業務課題と型の対応を一覧にしています。
試すための環境も、年々整ってきています。無料で使えるソルバーの範囲は広がっており、定式化の検証を始める段階で費用の判断を迫られることは、ほとんどなくなりました。道具立ての詳細は第13章で扱います。着手の敷居が下がったいまこそ、成否を分ける定式化の考え方を押さえておく価値があると考えています。
Anagraftでは、AIプロジェクトの構想・課題設計から、データ分析・機械学習モデルの開発、AI人材の育成まで一貫したご支援を行っています。数理最適化の適用可否の見立てや定式化のご相談は、以下よりお問い合わせください。
お問い合わせ
本コラムの構成です。第1章から第5章が土台、第6章から第12章が業務課題別の型、第13章と第14章が実装と運用です。自社の課題に近い行からの逆引きも想定しています。ただし第6章から第14章は、第2章の3点セット、第3章の問題クラス、第5章の表現テクニックで置いた用語を前提に書いていますので、逆引きで読み始めて用語に詰まった場合は、その3章に戻っていただくのが早道です。
| 章 | 扱う業務課題 | 対応する定式化パターン | この章で解ける問い |
|---|---|---|---|
| 第1章 国内の導入事例 | 製鋼計画、生産スケジュール、当直シフトなど5事例 | 事例の観察 | 数理最適化は業務の何を変え、どの業務から着手すべきか |
| 第2章 定式化の3点セット | 全パターン共通の書き出し | 決定変数・目的関数・制約の3点セット | 業務課題をどう日本語で書き出せば数式に近づくか |
| 第3章 問題クラスの地図 | 計算時間と解ける規模の見通し | LP・MIP・ネットワーク型・非線形・ヒューリスティクス | この問題は現実的な時間で解けるのか |
| 第4章 業務課題との対応表 | 8つの業務課題の引き当てと部門別の逆引き | 業務課題と型の対応表 | 自社の課題はどの型のどの章に対応するか |
| 第5章 頻出の表現テクニック | 現場の条件を数式に載せる書き換え | 0か1を取る変数、big-M法、線形化、ソフト制約ほか7技法 | 複雑に見える業務条件をどう不等式にするか |
| 第6章 生産計画と資源配分 | 設備時間と原料の振り分け、配合、多期間計画 | 線形計画問題 | 設備をあと1時間増やしたら利益はいくら増えるか |
| 第7章 人員配置とシフト作成 | 勤務表の編成、要員のスキル別配置 | 割当問題+ソフト制約 | 法令を守りながら希望と公平性をどこまで通せるか |
| 第8章 拠点・設備の配置 | 出店、物流センター、保守拠点、統廃合 | 集合被覆問題、p-メディアン問題ほか | どの候補地を開けば最小費用で全域を守れるか |
| 第9章 輸送と配分 | 倉庫から店舗への配分、欠品時の優先順位 | 輸送問題、最小費用流問題 | どこからどこへ何個送るのが全体として最も安いか |
| 第10章 発注量と在庫水準 | 発注量と発注時期、安全在庫、需要予測との接続 | 経済発注量モデル、新聞売り子モデル | 1回にいくつ発注し、どこまで在庫を持つべきか |
| 第11章 投資と施策の選定 | 予算配分、設備投資、施策の組み合わせ | ナップサック問題 | 限られた予算でどの施策の組み合わせを選ぶか |
| 第12章 配送ルートと配車計画 | 訪問順序の決定、配車、労働時間規制への対応 | 巡回セールスマン問題、配車計画問題 | どの車両がどの順に回れば最短で回り切れるか |
| 第13章 モデルをPythonで動かす | 実装、ツールの選択、解が出ないときの切り分け | PuLP、OR-Tools、SciPyとソルバー | 解が返ってこないとき、どの順に何を確かめるか |
| 第14章 プロジェクトと運用定着 | 体制づくり、ヒアリング、効果測定、変更管理 | 進め方の指針 | 定式化をどう業務に定着させ、組織に残すか |
生産計画の立案、勤務表の編成、配送ルートの決定といった「計画を決める」業務は、多くの企業で毎日あるいは毎週繰り返されています。これらの業務では、扱う数字そのものは基幹システムに揃っているにもかかわらず、最終的な計画は担当者が表計算ソフトの上で組み立てているという状態が続いていることが少なくありません。決め方の根拠が担当者の頭の中にあるため、同じ条件でも作る人によって出来上がる計画が変わり、担当者が異動すると品質が落ちるという性質を持ちます。
この工程に数理最適化を適用した国内企業の取り組みを、本章で確認します。取り上げるのは、公開されている情報から成果の内容と数値をたどれるものに限りました。定式化の具体的な進め方は第2章で扱いますので、ここでは何が変わったのかという結果と、変化を生んだ要因の観察に絞ります。

企業のデータ活用は、実績データから将来の数字を推定する工程と、その数字を前提に行動を決める工程の2段構えになっています。前者が需要予測や故障予測といった予測の工程で、後者が発注量や人員配置を決める工程です。図はこの流れを表したもので、データから予測を経て最適化に進み、最終的な意思決定に至る順序になっています。
この2つは、扱う問いが根本的に異なります。予測が答えるのは「これから何が起きそうか」であり、最適化が答えるのは「それを前提に何をするか」です。来週の需要が1,000個と予測されたとして、では今日いくつ発注するのかは、予測値からは一意に決まりません。発注ロットの単位、倉庫の保管容量、リードタイム、欠品したときの損失と余ったときの廃棄費用といった条件が絡み、それらを踏まえて初めて発注量が決まります。予測の精度を上げることは、決める工程に渡す入力の質を上げることであって、決める工程そのものを代替するものではありません。
実務でこの区別が重要になるのは、投資の判断をするときです。予測精度が数ポイント改善しても、その予測を受けて決める工程が従来どおり担当者の勘に委ねられていれば、業務の成果はほとんど変わりません。逆に、予測精度が現状のままでも、決める工程の条件を整理して計算で決められるようにすれば、成果が動くことがあります。予測の当たり外れと、決め方の良し悪しは、別々に評価する必要があるということです。
決める工程が表計算ソフトに残りやすいのには、技術以外の理由もあります。予測は入力と出力がはっきりしており、精度という単一の尺度で良し悪しを議論できるため、システム化の対象として合意を取りやすい性格を持ちます。これに対して決める工程は、良い計画の条件が部門によって異なり、守るべき条件も現場ごとに違います。何を作るのかを定義する段階で関係者の調整が必要になるため、着手が後回しになりやすいという事情があります。裏を返せば、その調整さえ通れば、決める工程は繰り返し行われる業務であるだけに、効果が積み上がりやすい領域でもあります。
以下に挙げる事例は、いずれもこの後者、決める工程に手を入れたものです。
日本製鉄と日鉄ソリューションズは、製鋼工程の出鋼スケジューリングシステムを共同開発し、2023年10月に東日本製鉄所君津地区で本格運用を開始しました。週次計画の選択肢は単純計算で10の300乗にのぼり、従来は熟練技能者が暗黙知をもとに数時間かけて計画を組み立てていました。これを数理最適化によって定式化した結果、同等以上の計画案を数秒から数分で導出できるようになり、計画作成業務は70%以上削減されています。
この事例で目を引くのは、選択肢の数として示された10の300乗という桁です。この規模になると、すべての候補を並べて比較するという方法は原理的に成立しません。担当者が数時間で計画を組み立てられていたのは、全候補を調べていたからではなく、経験によって明らかに筋の悪い選択肢を最初から除外していたからです。つまり従来の運用は、熟練技能者が持つ絞り込みの基準に依存して成り立っていたことになります。その基準が言葉になっていない限り、同じ品質の計画を別の人が作ることはできません。
数時間かかっていた計画の作成が数秒から数分に短縮されたことの意味も、単なる時短にとどまりません。1回の計画作成に数時間かかる状態では、案を1つ作ってそれを通すという運用にならざるを得ませんが、数分で作れるのであれば、条件を変えた案を複数並べて比較できます。設備の稼働条件を変えたらどうなるか、優先する注文を入れ替えたらどうなるかといった検討が、机上の議論ではなく計算結果として出せるようになります。また、計画を立てた後に設備の不調や注文の変更が起きたとき、組み直しにかかる時間が短ければ、当初計画に固執せずに立て直すという判断が取りやすくなります。
計画作成業務が70%以上削減されたという数値についても、読み方には注意が必要です。削減されたのは計画を組み立てる時間であって、計画に関する判断が不要になったわけではありません。むしろ、組み立てに費やしていた時間が空くことで、その計画でよいかを検討する時間や、例外への対応に人手を回せるようになります。属人性の解消という観点では、熟練技能者の退職や異動によって計画の品質が落ちるという構造的なリスクに、システムという形で手当てがなされたという点が本質的です。
あわせて、成果が「同等以上の計画案」という言い方で示されている点にも触れておきます。この種の取り組みで最初に問われるのは、人が作っていた計画より優れているかどうかではなく、人が作っていた計画と同じ水準に届いているかどうかです。現場から見れば、既存の運用で回っているものを置き換える以上、少なくとも同じ品質が出ることが前提条件になります。同等の水準に達したうえで作成時間が短くなり、そこから先の改善余地が見えてくるという順序をたどるのが、実際の進み方に近いといえます。導入の目標を最初から人を上回る品質に置くと、判定の基準が曖昧になりやすく、評価が長引きます。
ライオンは、NTTデータ数理システムのNuorium Optimizerを用いた生産スケジューラを構築しました。扱ったのは多品目多段階多ラインのロットスケジューリング問題で、中間品の製造を考慮しながらボトルネックとなる包装ラインの計画を立てる必要がありました。導入後は6か月分の生産計画を1日で作成できるようになり、副次的に18か月先までの中長期計画の立案も可能になったと報告されています。
多品目多段階多ラインという表現は、この課題の難しさをそのまま表しています。品目が多いということは、どの製品をどれだけ作るかの組み合わせが多いということです。多段階とは、原料から中間品を作り、その中間品を使って最終製品を仕上げるというように工程が連なっていることを指し、後工程の計画は前工程の完成時期に縛られます。多ラインは、同じ作業を複数の設備で分担できることを意味し、どのラインに割り振るかという選択が加わります。これらが同時に絡むため、1つの工程だけを見て良い計画を作っても、前後の工程で辻褄が合わなくなります。
ボトルネックとなる包装ラインに合わせて計画を立てるという方針は、この種の課題に共通する考え方です。全工程を均等に扱うのではなく、最も余裕のない工程の稼働を軸に据え、他の工程はそこへ供給が間に合うように組む形になります。どの工程がボトルネックかは業務側が把握していることが多く、その知識を計画の構造として書き込めたことが、成果につながっている部分だと考えられます。
6か月分の生産計画を1日で作成できるという結果は、対象期間の長さと作成時間の両方を含んでいます。長い期間をまとめて計画できるということは、月をまたぐ在庫の持ち方や、需要の山谷に対する作り置きの判断を、期間全体を見渡したうえで決められるということです。そして、副次的に18か月先までの中長期計画が立てられるようになったという点は、同じ仕組みを期間を延ばして使えたことを示しています。中長期の計画は、設備投資や要員計画の議論に使われる性格のもので、日々の生産計画とは目的が異なります。日次の運用のために作った仕組みが、経営判断の材料を出す用途にも広がったという形です。
大阪ガスでは、当直シフトの編成に数理最適化を適用し、従来1週間かかっていたシフト作成作業を4時間まで短縮した事例が公開されています。
勤務表の編成は、条件が言語化されにくい業務の代表格です。労働時間や休憩の確保のように法令や社内規程で明文化されている条件がある一方で、特定の資格を持つ人を各時間帯に必ず1名置く、夜勤が続いた翌日は軽い勤務にする、負担が特定の人に偏らないようにするといった条件は、担当者の判断として運用されていることが多くあります。前者だけを条件として書いても現場が使える勤務表にはならず、後者を含めて書き出せるかどうかが成否を分けます。
作成に1週間かかっていた状態では、勤務表の確定そのものが遅れ、当事者が自分の予定を立てられる時期も後ろにずれます。また、いったん確定した後に欠勤や急な予定変更が生じても、組み直しに再び長い時間がかかるため、部分的な手直しで凌ぐことになります。作成時間が4時間になれば、変更が生じた時点で全体を組み直すという選択肢が現実的になり、手直しの積み重ねによって当初の条件が崩れていくという事態を避けやすくなります。この課題を数式として書き下す方法は、第7章で扱います。
勤務表にはもう1つ、結果が個人の生活に直結するという特徴があります。生産計画や配送計画であれば、出てきた計画が合理的であることが示せれば納得は得られますが、勤務表の場合は、割り当てられた本人が不公平だと感じれば、計算の上でどれほど良い解であっても運用に乗りません。誰にどれだけ負担が寄っているかを数字で示せる形にしておくことが、この種の業務では成果の一部になります。作成時間の短縮は、その説明の材料を作る余裕を生むという意味でも効いてきます。
ソフトバンクは、LPガスの配送を対象としたサービスRoutifyを2022年6月に発表しました。公表資料によれば、AIがLPガス容器内の残量を予測し、その予測に基づいて最適な配送計画とルートを自動で策定する仕組みです。使用するデータとして、LPガス事業者が保有する検針データ、車両の数や種別、配送員数や物件情報のデータに加え、道路情報や天候などの外部データが挙げられています。実際の配送現場でのフィールドテストでは、配送員が1時間当たりに交換したガスの容量として定義されるガス納入能力が、25%向上したと報告されています。
この事例は、前節で述べた予測する工程と決める工程の関係が、1つのサービスの中で連結している形になっています。残量の予測が答えるのは「どの家庭のガスがいつ切れそうか」であり、配送計画が答えるのは「では今日、どの配送員がどの順番で回るか」です。残量を高い精度で予測できても、回る順番と担当の割り振りを決めなければ、配送員は動けません。逆に、残量の見込みが外れていれば、どれほど効率の良いルートを組んでも、まだ余裕のある家庭を訪問して空振りに終わります。両方が噛み合って初めて、1時間当たりの納入量という現場の指標が動きます。
成果指標の取り方にも触れておきます。ここで測られているのは、走行距離でも訪問件数でもなく、配送員が1時間当たりに交換したガスの容量です。配送業務の目的が顧客にガスを届けることである以上、時間当たりにどれだけ届けられたかで測るのは、業務の目的に沿った指標の置き方だといえます。
東京ガスの開栓業務を対象とした事例が、NTTデータ数理システムの事例ページで2025年7月に公開されています。開栓業務とは、新たにガスの利用を開始する際にガスメータを開通させる作業を指します。この作業を誰にいつ担当させるかを管理者が割り振る差配業務が対象で、繁忙期には1日に1,000件以上を差配することもあると記載されています。差配にあたっては、案件の指定時間、地理的な巡回のしやすさ、作業員の資格を考慮する必要があるとされ、プロトタイプツールの適用により1日あたり30%から90%の業務時間の削減が見られたと報告されています。
ここで注目したいのは、考慮すべき条件が3つ明示的に挙げられている点です。訪問時間の指定は顧客との約束であり、破ることができません。地理的な巡回のしやすさは、移動時間を短くするための効率の問題です。作業員の資格は、その作業を担当できる人が限られるという制限を表します。性格の異なる3種類の条件が、業務ルールとして言葉になっている状態だったからこそ、計算で割り振れる形に持ち込めたと読むことができます。
はじめに挙げた製鋼工程、生産スケジュール、当直シフトの3件から確認します。
3つの事例に共通しているのは、ソルバーの性能そのものよりも、熟練者が頭の中で処理していた条件を明示的な制約として書き下せたことが成果につながっている点です。日本製鉄の事例では、暗黙知の形式知化がシステム開発の中核に位置づけられています。定式化は、単に数式を書く作業ではなく、業務の判断基準を言語化する作業でもあるということです。
この観察は、後半で挙げた配送計画と開栓業務の2つの事例にも当てはまります。開栓業務の差配で挙げられていた3つの考慮事項は、いずれも管理者が経験として持っていたものを条件として並べ直したものです。配送計画のサービスで使われているデータの一覧も、熟練の配送員が「あの家はそろそろだ」「あの通りは朝は混む」という形で持っていた判断材料を、検針データや道路情報として扱える形にしたものと見ることができます。
言語化がなぜ成果に直結するのかは、書き出された後に何が可能になるかを考えると分かります。第一に、条件が文書として存在すれば、担当者以外がその計画の妥当性を検証できます。「なぜこの順番なのか」という問いに、担当者の記憶ではなく条件表で答えられるようになります。第二に、条件が揃っていれば、担当者が不在でも同じ品質の計画が出ます。属人性の解消は、システムを導入した効果というより、条件を書き出した効果です。第三に、書き出す過程で条件そのものの妥当性が議論になります。法令に由来する条件と、いつからか続いている慣習に由来する条件が分離され、後者については「この条件を外すとどれだけ改善するか」を試算できるようになります。
逆に、書き出せない条件が残ることも珍しくありません。関係者の間で意見が割れる、あるいは状況によって判断が変わるという性質の条件は、無理に数式へ押し込むより、計算した結果を人が見て調整するという設計にしたほうが実務に馴染みます。ここまでを機械が決め、ここから先は人が決めるという線引きを明示的に置くことも、形式知化の一部です。
もう1つ付け加えると、言語化の効果はシステムが動き出す前から現れます。何を決めているのか、何を守っているのか、何をもって良い計画とするのかを関係者で確認する作業自体が、部門間の認識のずれを表に出します。この整理を実務としてどう進めるかは、第14章で扱います。
自社のどの業務を対象にするかを考えるとき、判断の軸になるのは3つです。決定の頻度、その決定が動かす金額、そして守るべき条件がどれだけ明確になっているかです。
頻度は、効果が積み上がる速さを決めます。毎日あるいは毎週繰り返される意思決定であれば、1回あたりの改善が小さくても年間では大きな差になり、運用に乗せた後の学習も早く進みます。反対に、年に1回しか行わない意思決定は、改善効果の検証に何年もかかるうえ、過去のデータも件数が揃いません。本章で挙げた5つの事例は、いずれも週次あるいは日次で繰り返される業務でした。
金額は、その意思決定が左右する費用または売上の桁で測ります。目安としては、対象となる金額の総額に対して数パーセントの改善が起きたときの額を見ます。年間の輸送費が数十億円規模であれば、数パーセントの改善でも投資に見合う額になりますが、金額の小さい業務では、担当者の作業時間の削減が主な効果になります。作業時間の削減も立派な効果ですが、費用対効果の説明の仕方が変わりますので、着手前にどちらを主たる効果として説明するかを決めておくと、後の評価がぶれません。
3つ目の、条件の明確さが、実際には難易度を最も大きく左右します。法令、契約、設備の能力といった条件は、文書や数値として存在するため書き出しやすい種類です。一方で、担当者の判断としてのみ運用されている条件が多い業務は、書き出す工数が事前に読めません。ただし、条件が言葉になっていないこと自体は、着手を見送る理由にはなりません。本章の事例が示しているのは、まさにその言葉になっていない条件を書き出したことが成果につながったという点です。読めないのは工数であって、効果ではないという整理になります。
この3つに加えて、現状の所要時間と担当者の人数を確認しておくと、着手先の優先順位が付けやすくなります。作成に長時間かかっており、かつ作れる人が限られている業務は、頻度と条件の明確さの条件を満たしていれば、有力な候補です。逆に、一回限りの意思決定や、条件が関係者の力関係で決まる性格の意思決定は、計算で決める対象としては向きません。
本章の5つの事例を、この3つの軸に当てはめてみると、いずれも同じ位置に並びます。製鋼工程の計画は週次、生産スケジュールは期間をまとめて作るとはいえ継続的な業務、当直シフトも配送計画も開栓業務の割り振りも、日次または週次で繰り返される業務です。動かす金額という点では、製造と物流の計画は原価と輸送費に直結し、勤務表と作業の割り振りは人件費と対応します。そして守るべき条件については、納期、設備能力、資格要件、訪問時間の指定というように、業務ルールとして名前の付いた条件が存在していました。着手先を探すときは、この3つが揃っている業務を先に洗い出すのが近道になります。

どの業務がどの型の問題に対応するかという対応表は、第4章で示します。
次章では、定式化の3点セットを扱います。
『入門オペレーションズ・リサーチ』(松井泰子、根本俊男、宇野毅明、東海大学出版会):本章で見た計画立案や配置の課題が、学問としてどう体系づけられてきたかを確認できます。個別の解法に入る前に、業務課題を数理的な問題として捉える視点そのものを整理したい方に向いています。
発注量を決める、勤務表を組む、出店先を選ぶといった業務は、扱う対象も担当する部門も異なりますが、最適化の対象として整理するときに最初に通る工程は共通しています。担当者が経験にもとづいて処理してきた判断を、他人が読んでも同じ結論に辿り着ける形に書き出す工程です。第1章で取り上げた国内5件の取り組みで成果を分けたのも、ソルバーの性能ではなくこの工程の出来でした。
この書き出しには、対象の業務が何であっても変わらない枠組みがあります。3つの問いに順に答えていくと、業務課題は最適化問題の形になります。書き上がった問題がどの型に属し、どの解き方が使えるのかを見分ける話は第3章で、条件を数式に翻訳する個別の技法は第5章で扱います。本章が受け持つのは、その手前にある日本語での書き出しです。
どのような最適化問題も、まず次の3つを日本語で書き出すところから始まります。数式に落とすのはその後です。

| 要素 | 問い | 例 |
|---|---|---|
| 決定変数 | 何を決めるのか | 商品ごとの発注量、スタッフごとの担当シフト、出店する候補地 |
| 目的関数 | 何を最大化または最小化するのか | 利益の最大化、総輸送コストの最小化、走行距離の最小化 |
| 制約 | 守るべき条件は何か | 予算上限、人員の上限、需要の充足、労働時間規制 |
この3点セットが揃わないうちにコードを書き始めると、たいてい途中で手が止まります。とくに制約は現場に埋もれていることが多いため、定式化の工程は現場ヒアリングとセットで設計するのが確実です。
3つの要素は互いに独立ではなく、書き出す順番にも意味があります。決定変数が決まらないと、目的関数も制約も式として書きようがありません。何を決めるのかが定まって初めて、その決め方の良し悪しを測る尺度(目的関数)と、選んではいけない決め方を排除する条件(制約)が定義できるからです。逆に、目的関数と制約を先に議論し始めると、話が「あるべき姿」の抽象論に流れ、いつまでも数式に近づかないという状態に陥りやすくなります。
もう一つ、3点セットは業務側と分析側の共通言語としても働きます。決定変数は「この意思決定は誰の裁量で、どの単位で行われているのか」を問う項目であり、目的関数は「その部門は何で評価されているのか」を問う項目、制約は「破ると何が起きるのか」を問う項目です。いずれも本来は業務側が答えを持っている問いであり、分析側が机上で埋められるものではありません。3点セットを埋める会議は、モデルを作る作業であると同時に、業務の判断基準を関係者の間で明文化する作業でもあります。
決定変数は、意思決定の自由度そのものを表します。ここで最初に確認したいのは、その項目が本当に「これから決められるもの」なのかという点です。実務のヒアリングでは、すでに決まっている値や、他部門が決めていて動かせない値が、変数の候補として挙がってくることがよくあります。来月の生産計画を立てる場面で、設備の稼働可能時間は所与の条件であって決定の対象ではありません。決められないものは変数ではなく定数として扱い、制約の右辺に置くのが正しい扱いです。この切り分けを曖昧にしたまま進めると、現場が実行できない計画が出力されます。
次に決めるのが粒度です。同じ「発注量を決める」という課題でも、商品単位で決めるのか商品カテゴリ単位で決めるのか、日次で決めるのか週次で決めるのかによって、変数の数も、必要なデータも、出力される計画の使い勝手も変わります。粒度を細かくすれば現実に近い計画になりますが、変数の数が増えて計算が重くなり、入力すべきマスタデータも増えます。粗くすれば軽くなりますが、現場がその出力をそのまま実行できず、結局は手作業で細分化することになります。粒度は「その計画を受け取った人が、追加の判断なしに実行に移せるか」を基準に決めるのが実務的です。
粒度が決まれば、変数は自然と添字の形で書けます。商品ごとの発注量であれば商品を表す添字 \(i\) を付けて \(x_i\)、倉庫から店舗への輸送量のように2つの対象の組み合わせで決まる量であれば \(x_{i,j}\) と書きます。添字が1つ増えるたびに変数の数は掛け算で増えていきますので、「商品×店舗×週」のように3つの添字を並べた時点で、変数の総数がどれくらいになるかを概算しておくと、後で計算時間に驚かずに済みます。
変数が取りうる値の範囲も、この段階で言葉にしておきます。発注量のように連続量として扱ってよいものか、人数のように整数でなければ意味をなさないものか、開設するかしないかのように2つの選択肢しかないものかで、問題の性質が大きく変わるためです。選択の有無を数式に載せる書き方は第5章で扱います。
この段階で決めておきたいのが、何をもって「良い解」とするかです。コストと納期のように複数の指標が競合する場合、どちらを目的関数に置き、どちらを制約として扱うのかは業務判断であり、数学が決めてくれるものではありません。
目的関数を選ぶ際に確認しておきたいのは、それがその業務の評価指標と一致しているかという点です。物流部門が輸送コストで評価されているのに、モデルの目的関数を走行距離の最小化にしてしまうと、距離は短いが高速道路料金と人件費がかさむ計画が最適解として返ってきます。距離とコストが比例するなら結果は変わりませんが、比例しないからこそコストで評価しているはずです。目的関数は、その計画の良し悪しを最終的に判定する人が使っている尺度に合わせるのが原則です。
金額に換算できる指標であれば、目的関数は比較的すんなり書けます。難しいのは、サービス水準や公平性のように金額に直しにくい指標が主役になる場合です。この場合の実務的な進め方は2つあります。1つは、その指標を測れる代理変数を定義してしまうことです。公平性であれば「担当者ごとの勤務回数の最大値と最小値の差」のように、数えられる量に置き換えます。もう1つは、その指標を目的関数ではなく制約に回すことです。サービス水準であれば「欠品率は3%以下」という形で条件として書き、目的関数はコスト最小化に絞ります。どちらを採るかで出てくる計画の性格が変わりますので、関係者に両方の案を見せて選んでもらうのが確実です。
目的関数を1つに決められない場面もあります。条件が厳しく、そもそも全部を満たす計画を作れるかどうかが焦点になっている場合です。このときは無理に最大化や最小化の対象を決めず、制約をすべて満たす計画を1つ見つけることを当面の目的に据えます。目的関数を置かずに解いても、条件を満たす答えが存在するかどうかは判定できます。まず成立する計画を1つ得て、それを出発点に改善したい指標を目的関数へ据えるという二段構えにすれば、最初から条件と目標を同時に詰め込むより早く結論に届きます。
目的関数の符号にも注意が必要です。最大化と最小化はマイナスを掛ければ相互に変換できますが、業務の会話では「利益を最大にしたい」と「損失を最小にしたい」が同じ意味で使われる一方、集計の対象が微妙に違っていることがあります。売上から変動費だけを引いた粗利を最大化するのか、固定費まで引いた営業利益を最大化するのかで、選ばれる計画は変わります。目的関数に載せる金額が、どの費目まで含んだ数字なのかを書き出しの段階で確定させておきます。
3点セットのうち、最も抜けが出やすいのが制約です。決定変数と目的関数は「何を決めたいか」「何が嬉しいか」という前向きな問いなので比較的すぐに答えが返ってきますが、制約は普段意識せずに守られている条件であるほど言葉になりません。熟練者ほど、その条件を守ることが体に染みついているため、質問されるまで存在に気づかないという性質があります。
洗い出しの取っかかりとして、制約を性質で分類しておくと漏れに気づきやすくなります。実務でよく出てくるのは次の4種類です。
この4分類に沿って現場に質問していくと、「言われてみればそうだ」という条件が出てきます。とくに4つ目は、法令に基づくものと社内の慣習に基づくものが混在していることが多く、両者を分けて記録しておくことが後で効いてきます。法令由来の条件は動かせませんが、慣習由来の条件は、その条件を外すとどれだけ改善するかを試算して見せることで、業務ルールそのものの見直しにつながる場合があるためです。定式化の副産物として「その制約は本当に必要か」という議論が起きるのは、健全な兆候だと考えています。
洗い出した条件は、決定変数を使った文に書き直せるかどうかで検算できます。制約は最終的に「決定変数の組み合わせがこの水準を超えない」「この水準を下回らない」「この値と等しい」のいずれかの形になりますので、決定変数の言葉で言い換えられない条件が残っていれば、決定変数の定義が足りていないという合図です。たとえば「同じ担当者を2日連続で夜勤に入れない」という条件は、担当者と日付の両方を添字に持つ変数がなければ書けません。制約が書けないときは制約の側を諦めるのではなく、変数の定義に戻って粒度や添字を見直します。
もう一つ記録しておきたいのが、条件の厳しさの度合いです。同じ「守るべき条件」でも、絶対に破れないものと、できれば守りたい程度のものが混在しています。この違いを書き出しの段階で区別しておかないと、後で条件をすべて同時に満たす解が存在しない状態になったときに、どこを緩めればよいかが判断できなくなります。破ってもよい条件として書く方法は第5章で扱います。
ここまでの内容を、実際の進め方として順に並べます。1回のヒアリングで完成させようとせず、書き出しと確認を2往復させる前提で組むのが現実的です。
6番目の検算は省かれがちですが、定式化の誤りを最も早く見つけられる工程です。過去の実績が自分で書いた制約を満たさないのであれば、そのモデルは現場を表現できていません。逆に、実績が制約をすべて満たしたうえで目的関数の値が改善の余地を残しているなら、そのモデルには使える見込みがあります。
3点セットを埋めるための設問を、要素別に整理しました。専門用語を使わずに聞くのが要点で、「決定変数は何ですか」と尋ねても答えは返ってきません。
| 埋めたい要素 | 設問の例 |
|---|---|
| 決定変数 | この作業で、あなたが数字を書き込む欄はどこですか。/その数字は毎週決めますか、毎日決めますか。/その欄を空欄のまま次の工程に渡すと、誰が困りますか。/その数字を決めるとき、選択肢はいくつありますか。 |
| 目的関数 | この計画が良くできた月と、うまくいかなかった月の違いは何で分かりますか。/上司にこの計画を説明するとき、最初に見せる数字は何ですか。/同じコストで2つの案が出てきたら、どちらを選びますか。その理由は何ですか。 |
| 制約 | この計画で絶対にやってはいけないことは何ですか。/過去にやり直しになった計画は、何が原因でしたか。/新人が作った計画を見て、まず確認するのはどこですか。/その条件を破ると、誰にどんな迷惑がかかりますか。 |
制約の欄にある「過去にやり直しになった計画は、何が原因でしたか」という設問は、暗黙の条件を引き出す効果が高いものです。守られていて当たり前の条件は言語化されませんが、破って問題になった経験は記憶に残っているためです。同様に、「新人が作った計画を見て、まず確認するのはどこか」という問いも、熟練者が無意識に行っているチェック項目を表に出す助けになります。
設問の答えは、その場で数式に直さず、日本語のまま一覧に残します。数式に直す作業を同席者の目の前で行うと、内容の確認より記号の説明に時間を取られ、肝心の条件の聞き取りが浅くなります。書き出しが終わってから、分析側で数式に翻訳し、その結果を日本語に戻して読み合わせるという往復にすると、業務側が内容を検証できる形を保てます。
実務の課題では、良くしたい指標が1つだけということはまずありません。コストは下げたいが納期も守りたい、在庫は減らしたいが欠品も避けたい、といった具合に、片方を良くすると片方が悪くなる関係にある指標が並びます。数理最適化のモデルは、目的関数を1つに絞ることを前提に組み立てられていますので、この競合をどう処理するかを定式化の段階で決めておく必要があります。
最も扱いやすいのは、片方を目的関数に置き、もう片方を制約に回す方法です。納期を守ることを制約として書き、その条件のもとでコストを最小化する、という形にします。この方法の利点は、出てきた答えの解釈が容易なことです。「納期を全件守ったうえで、達成できる最小のコストはこれです」と説明でき、関係者の合意も取りやすくなります。制約に回した側の水準を何段階か変えて計算し直せば、「納期遵守率を95%まで許容すればコストはここまで下がる」という対応関係を表にして示すこともできます。判断材料としてはこの表が最も実用的です。
もう1つの方法が、複数の指標に重みを掛けて足し合わせ、1つの目的関数にまとめるやり方です。コストを \(C\)、納期の遅れ日数の合計を \(D\) として、\(C + w D\) を最小化するという形になります。書き方としては単純ですが、実務では重み \(w\) の決め方が難点になります。コストは円、遅れは日という異なる単位ですので、\(w\) は「遅れ1日を何円と評価するか」という換算レートを意味します。この値に根拠のある数字を置けるのであれば有効な方法ですが、根拠なく決めた重みは、結果を見て気に入らなければ調整するという運用になりがちで、その調整が入った時点でモデルは意思決定の根拠ではなくなります。重み付けを採るのであれば、その重みが何を意味するのかを説明できることが条件です。
複数の目的を同時に扱う理論的な枠組みも存在しますが、業務の現場では、より単純な2つの方法で用が足りることがほとんどです。
1つ目が辞書式順序です。指標に優先順位を付け、第1優先の指標で最適化して最良値を求め、次にその最良値を制約として固定したうえで、第2優先の指標を最適化します。以下、順位の低い指標へ同じ手続きを繰り返します。「まず法令違反をゼロにする。それを満たす計画の中でコストを最小にする。同じコストの案が複数あるなら、勤務の偏りが小さいものを選ぶ」という進め方は、実務の判断順序をそのまま表現したものになります。優先順位さえ関係者間で合意できれば重みを決める必要がなく、各段階の答えも解釈しやすいという利点があります。第1優先の最良値をそのまま固定すると後段の自由度がなくなりすぎる場合は、「第1優先の指標は最良値から5%以内」といった許容幅を設けて次の段階に進みます。
2つ目が目標計画法です。各指標について「コストは月8,000万円以内、欠品率は2%以内」のように目標値を定め、そこからのずれの合計を小さくすることを目的にします。すべての目標を同時に達成できる計画があればずれはゼロになり、達成できない場合は、どの目標をどれだけ超過したかが数字で出てきます。「すべては満たせないが、この目標をこれだけ超過すれば残りは満たせる」という形で結果が出るため、どこを譲るかの議論に直接つながります。ずれの量を数式に載せる書き方は、第5章で扱う技法と同じものを使います。
いずれの方法を採る場合でも、複数の目的をどう扱ったかは、モデルの仕様として文書に残しておきます。運用に乗ってから「なぜこの案が選ばれたのか」を問われたときに、優先順位や目標値の設定が記録されていなければ答えられません。
書き出しの段階で起きる典型的な失敗を挙げます。いずれも、解いた後になって発覚すると手戻りが大きい種類のものです。
これらの失敗に共通するのは、書き出しの段階では気づけず、解いた後に現場の反応として現れるという点です。だからこそ、3点セットを日本語で書いた時点で業務側に読み合わせてもらう工程を、明示的に手順へ組み込んでおく価値があります。数式を読める人は限られますが、日本語で書かれた「何を決めるのか」「何を良しとするのか」「何を守るのか」の一覧であれば、業務の担当者が誤りを指摘できます。

次章では問題クラスの地図を扱います。
『しっかり学ぶ数理最適化 モデルからアルゴリズムまで』(梅谷俊治、講談社):本章で日本語のまま書き出した3点セットが、数式としてどのような形に落ちるのかを、線形計画から整数計画まで順を追って確認できます。モデリングの記述とアルゴリズムの解説が対になっているため、書き出した条件が解きやすさにどう影響するかまで追えます。
定式化を書き上げた直後に必ず問われるのが、「この問題は本当に解けるのか」「解けるとして、どれくらいの時間がかかるのか」という見通しです。これはプロジェクトの初期段階で答えを出さなければならない問いでもあります。データをどこまで細かい単位で持つのか、計画を毎日作り直すのか月に一度でよいのか、既存の表計算ソフトによる運用の何を置き換えるのか。こうした要件はすべて、書き上げた問題がどれくらいの時間で解けるかに左右されます。ここを見誤ると、要件定義を終えて開発に入ってから「この規模では計算が終わらない」と判明し、設計をやり直すことになります。
この見通しを立てるための道具が、問題クラスの分類です。第2章で書き出した3点セットを眺め、決定変数が連続量なのか整数なのか、目的関数と制約が一次式で書けているのかを確かめるだけで、その問題がどの型に属するかはおおよそ判別できます。型が決まれば、使えるソルバー、現実的に扱える規模、必要な計算時間の桁が同時に決まります。この章では代表的な5つの型と、型ごとに何が変わるのかを整理します。
定式化した問題がどのクラスに属するかによって、使えるソルバーも計算にかかる時間も大きく変わります。代表的な5つのクラスを整理します。
| クラス | 特徴 | 実務での目安 |
|---|---|---|
| 線形計画問題(LP) | 変数が連続で、目的関数と制約がすべて一次式 | 変数が数十万規模でも高速に解ける。まずここに落とせないかを検討する |
| 混合整数計画問題(MIP) | 変数の一部または全部が整数。とくに0か1を取る変数を含む | 「選ぶ/選ばない」「開く/開かない」を表現できるが、規模が大きくなると計算時間が急増する |
| ネットワーク型(輸送・割当・最短路) | LPの特殊形。問題の構造がグラフで表現できる | 専用アルゴリズムが使え、数万地点規模でも実用的な時間で解ける |
| 非線形計画問題 | 目的関数や制約に二次式などの非線形項を含む | 後述の凸性があるかどうかで難易度が大きく変わる |
| ヒューリスティクス(局所探索、遺伝的アルゴリズムなど) | 厳密な最適解を諦め、良い解を短時間で得る | 組合せが爆発する問題や、毎日回す必要がある業務で現実解になる |
この5つは、きれいに並んだ横並びの選択肢ではありません。LPが最も広く速く解ける土台にあり、その特殊な構造を持つものがネットワーク型、整数の条件を足して表現力を広げたものがMIP、一次式という縛りを外したものが非線形計画問題、という入れ子の関係になっています。ヒューリスティクスだけは性質が異なり、問題の型ではなく解き方の選択です。厳密な最適解を出すことを最初から諦め、限られた時間で十分に良い解を得る方針を指します。したがって表の最初の4つは「問題がどう書けているか」の分類、最後の1つは「どう解くと決めたか」の分類だと理解しておくと、混乱が減ります。
LPは、決定変数が連続的な数量で、目的関数も制約もすべて足し算と定数倍だけで書けている状態を指します。生産量、原料の配合比率、輸送量、資金の配分額のように、小数を許しても業務上の意味が失われない量を扱う問題が該当します。この型に落ちていれば、計算時間の心配はほとんどしなくてよいと考えて差し支えありません。逆に言えば、後述するとおり、定式化の工夫でLPに落とせるかどうかがプロジェクトの難易度を大きく左右します。
MIPは、決定変数の一部または全部に整数の条件が付いた型です。人数、台数、発注ロット数のように小数では意味をなさない量に加えて、「その候補地に出店するかしないか」「その施策を採用するかしないか」という判断そのものを数式で表すために使われます。判断を表す変数の書き方は第5章で扱いますが、この型に入った瞬間に計算の性質が変わることだけは、この段階で押さえておく価値があります。MIPは表現力が高く、実務課題の多くは最終的にこの型に落ち着きますが、その代償として計算時間が読みにくくなります。
ネットワーク型は、LPの中でも特別に恵まれた構造を持つ一群です。倉庫と店舗、作業者と作業、地点と地点というように、問題が「点と点をつなぐ線」の形で表現できる場合が該当します。輸送問題、割当問題、最短路問題、最小費用流問題などが含まれ、このうち割当は第7章、輸送と最小費用流は第9章で個別に扱います。この構造を持つ問題は専用のアルゴリズムが使えるうえ、整数の条件を明示的に書かなくても答えが自然に整数になるという性質を持つことがあります。その理由は第9章で扱います。
非線形計画問題は、目的関数や制約に二次式、平方根、割り算、対数などが現れる型です。規模の経済によって単価が数量とともに下がる、設備の稼働率が上がるほど不良率が跳ね上がる、といった現実の非線形な振る舞いをそのまま書くとこの型になります。表現の忠実さは上がりますが、後述するとおり、解の質の保証が効くかどうかが凸性という性質に左右されるため、扱いは慎重になります。
ヒューリスティクスは、局所探索、遺伝的アルゴリズム、焼きなまし法などの総称です。現在の解を少しずつ変えて改善を繰り返す、あるいは複数の解を組み合わせて新しい解を作る、といった手続きで良い解を探します。得られた解が最適である保証はありませんが、厳密解法では手が出ない規模の問題に対して、実用に耐える答えを短時間で返します。毎日決まった時刻までに配送計画を出さなければならない、といった業務ではこちらが現実解になります。
手元の定式化がどの型に属するかは、次の4つの問いに順に答えていけば判別できます。定式化のレビューの場で、この順に確認していく使い方も想定しています。
| 問い | 確認する対象 | 答えによって決まること |
|---|---|---|
| 決めたい量は連続的な数量か、それとも判断そのものか | 決定変数 | 整数の条件が要るかどうか。要るならMIP |
| 目的関数と制約はすべて一次式で書けているか | 目的関数と制約 | 書けていなければ非線形計画問題 |
| 問題の構造は点と線のつながりで表せるか | 制約の並び方 | 表せるならネットワーク型の専用手法が使える |
| 求めたいのは厳密な最適解か、時間内に得られる良い解か | 業務の要求 | 後者ならヒューリスティクスが選択肢に入る |
4つ目の問いだけは、数式を見ても答えが出ません。意思決定の頻度と重みから業務側が決めることです。年に一度の設備投資判断であれば、一晩かけて厳密な最適解を求める価値があります。毎朝6時までに当日の配送順を出す必要があるなら、計算時間の上限が先に決まっており、その中で得られる最良の解を採る以外にありません。この線引きを定式化の前に済ませておくと、後の手戻りがかなり減ります。

ここで出てきた凸性について補足します。目的関数の形が、谷が1つしかないお椀のような形であれば凸、谷や山が複数ある起伏の激しい地形であれば非凸です。制約が作る領域も凸で、そのうえで凸な目的関数を最小化する(あるいは凹な目的関数を最大化する)問題であれば、その周辺で最も良い解(局所最適解)が、問題全体で最も良い解(大域最適解)でもあることが保証されます。領域の凸性と、最小化か最大化かの向きの両方が条件になります。非凸の場合はその保証がなく、たまたま入り込んだ谷が全体では2番目、3番目の谷にすぎない可能性が残ります。非線形計画で「凸かどうかを確認する」と言われるのは、この保証の有無を確かめているということです。
この保証があるかないかは、業務の場面では次のような違いになって現れます。凸の問題では、適切な解法を使う限り、どこから探索を始めても大域最適解にたどり着きます。担当者が変わっても、実行する日が変わっても、同じデータを入れれば同じ目的関数の値が返ります。最適な解が複数ある場合、返ってくる解そのものは実行のたびに違うことがありますが、そのときも達成される値は同じです。非凸の問題では、探索の出発点を変えると別の答えが出ることがあり、しかもどちらがより良いかは、両方を計算して比べるまで分かりません。実際の運用では、出発点を何通りか変えて計算し、その中で最も良かった解を採る、という進め方が取られます。この場合、報告書に書けるのは「これが最適です」ではなく「この範囲で探した中では最も良い解です」という表現になります。
この違いは、成果の説明責任にも関わります。最適化の導入効果を役員会に説明する場面で、「計算した結果、これが理論上の最適解です」と言えるのか、「探索した範囲での最良解です」と言うしかないのかは、受け取られ方が異なります。凸性が成り立つかどうかを最初に確認しておくことは、単なる数学的な作法ではなく、後の説明の仕方を決める作業でもあるということです。
では、どのような場合に凸になるのでしょうか。まず、目的関数も制約もすべて一次式であるLPは、常に凸です。この意味でLPは、凸な問題の中でも最も扱いやすい特殊例と見なせます。非線形の項が入る場合も、二乗の項が正の係数で足されている形、たとえば需要と発注量のずれの二乗をペナルティとして最小化するような目的関数は凸になります。距離の二乗和を最小化する立地の決定や、投資配分におけるリスクの分散を最小化する問題も、この形に収まることが多い型です。
逆に非凸になりやすいのは、掛け算や割り算で変数どうしが絡み合う場合です。単価と数量を両方とも決定変数にして売上を最大化しようとすると、目的関数に掛け算が現れて非凸になります。数量が増えるほど単価が下がる数量割引をそのまま書いた場合も同様です。ただし、この種の非線形性は、区分ごとに直線でつなぐ近似によって一次式の組合せに置き換えられることがあります。その具体的な書き方は第5章で扱います。
もう一点、注意すべき落とし穴があります。整数の条件が入ったMIPは、目的関数と制約がすべて一次式であっても、上で述べた意味での凸性の恩恵をそのままは受けられません。整数という条件が、連続的につながっていた解の候補を飛び飛びの点に切り分けてしまうためです。この切り分けこそが、次に述べる計算時間の問題を生みます。
LPが速く解けるのは、解の候補が連続的につながっていて、良い方向へ進み続ければ最良の点にたどり着ける構造になっているからです。整数の条件が入ると、この連続性が失われます。連続的な世界での最良点が、たとえば「候補地を2.4か所開く」という答えだったとして、それを整数に直すために2に切り下げてよいのか3に切り上げるべきなのかは、その場では判断できません。切り下げると必要なカバー範囲を満たせず、切り上げると予算を超える、といったことが起こり得ます。小数の答えを丸めた結果が制約を破ってしまい、そもそも成り立たない計画になることすらあります。だからこそ、整数の条件は丸めではなく、探索そのものの中で扱わなければなりません。
実際のソルバーが取る方法が、緩和と分枝限定法の組合せです。緩和とは、整数の条件をいったん取り払って、連続的な問題として解くことを指します。取り払った分だけ制約が緩んでいるので、そこで得られる答えは、本来の整数の答えより必ず良い値になります。利益の最大化なら、緩和して得た利益は本来到達できる利益の上限を教えてくれます。費用の最小化であれば向きが逆になり、緩和して得た費用は本来かかる費用の下限にあたります。以下では最大化の場合で説明しますが、最小化のときは上限と下限、良い悪いの向きをすべて読み替えてください。この境界が、探索の効率を支える手がかりになります。
分枝限定法は、この手がかりを使って探索を枝分かれさせます。緩和して解いた結果、ある変数が小数になっていたとします。その変数を1つ選び、「その値を切り下げた整数以下にする」枝と、「切り上げた整数以上にする」枝の2つに問題を分けます。0か1を取る変数であれば、0に固定する枝と1に固定する枝になります。分けたそれぞれの枝で、また緩和を解いて上限を求めます。ここで、ある枝の上限が、すでに見つかっている整数の解の値を下回っていたら、その枝の先をこれ以上調べる意味はありません。どう頑張っても既存の解を超えられないことが確定しているからです。この枝ごと切り捨てる操作を限定と呼び、これが計算量を実用的な範囲に抑える中心的な仕掛けになっています。
しかし、この切り捨てがうまく効かない場合があります。緩和して得た上限が、本来の整数の答えから大きく離れているときです。上限がゆるすぎると、どの枝も「まだ望みがあるかもしれない」と判定されて切り捨てられず、枝分かれが際限なく増えていきます。判断を表す変数が \(n\) 個あれば、組合せは原理的に \(2^n\) 通りあり、変数が30個で約10億通り、50個になると約1,000兆通りになります。切り捨てが効かなければ、この数に近い探索を強いられるということです。同じ問題を表す定式化が複数あるとき、緩和したときの上限がより本来の答えに近い書き方を選ぶべきだ、と言われるのはこのためです。定式化の巧拙が計算時間に直結する理由が、ここにあります。
ここまでの話を、理論の側から裏づけておきます。この節の要点は2つです。LPについては規模が大きくても解ける見通しが理論的に立っていること、整数条件の入った問題には同じ保証がなく、解けるかどうかは実際に小さく試して確かめるほかないことです。
LPについては、変数と制約の数に対して多項式時間で解けるアルゴリズムが存在することが、1979年に楕円体法によって理論的に示されています。多項式時間というのは、問題の規模が大きくなっても計算量の増え方が緩やかにとどまる、という意味だと考えていただければ十分です。この楕円体法そのものは実用的な速度が出ないため、現在のソルバーには使われていませんが、「LPは原理的に手に負える問題である」という保証を与えた点で決定的な結果でした。実務で使われているのは、解の候補を順にたどって改善していく単体法と、領域の内側を通って最適点に近づく内点法の2系統です。単体法には、意地の悪い問題を与えると計算回数が変数の数に対して指数的に増える例が1972年に示されており、理論上の最悪計算量は良くありません。指数的に増えるというのは、変数が1つ増えるたびに計算量が倍に膨らんでいくような増え方を指します。それにもかかわらず実務では非常に速く動くことが知られており、理論の最悪値と実務の体感が食い違う代表例になっています。
一方、整数の条件が入った問題は、理論的な難しさの階段を一段上がります。1972年にリチャード・カープが発表した論文では、21の組合せ問題が互いに同じ難しさのクラスに属することが示されました。この21問題の中に、0か1を取る変数だけからなる整数計画問題と、ナップサック問題が含まれています。これらについて、規模が大きくなっても計算量が緩やかにしか増えないアルゴリズムが存在するかどうかは、現在も未解決です。クレイ数学研究所が2000年に設定した7つのミレニアム懸賞問題の1つであるP対NP問題がこの問いにあたり、解決には100万ドルの賞金がかけられています。
ただし、この理論的な難しさを「だから実務では使えない」と読むのは誤りです。最悪の場合に手に負えないことと、目の前の業務データで解けないことは別の話だからです。実際、この20年で解ける規模は劇的に広がりました。2001年時点のソルバーと2020年時点のソルバーを比較した研究では、計算機の性能向上による高速化がおよそ20倍、アルゴリズムの改良による高速化が線形計画でおよそ9倍、混合整数計画でおよそ50倍と見積もられています。両者を掛け合わせると、線形計画で約180倍、混合整数計画で約1,000倍の高速化にあたります。研究者自身が、この数字はばらつきが大きく、しかもアルゴリズムの進歩を過小評価していると述べています。かつては手も足も出なかった問題が、いまは数秒で解けるようになっている例が数多くあるためです。
自社の問題が解けるかどうかを事前に見積もる方法についても、型ごとに事情が異なります。LPとネットワーク型については、表に示したとおり、変数が数十万規模、地点が数万規模であっても実用的な時間で解けると考えて概ね差し支えありません。問題はMIPです。MIPの計算時間は、変数の数だけでは決まりません。同じ変数の数でも、緩和したときの上限が本来の答えに近い問題は数秒で終わり、遠い問題は何時間かけても終わらないことがあります。したがって、規模から所要時間を逆算するのではなく、実データの一部を使って小さな試作を作り、実際に解かせてみるのが唯一確実な見積もり方法です。
公開されたベンチマークも判断材料になります。混合整数計画問題については、ベルリンのツーゼ研究所が維持しているMIPLIBという問題集が業界標準として使われており、2017年版では現行のソルバーで解けることが確認された240問がベンチマーク集合として選定されています。自社の問題と規模や構造が近い問題がこの中にあるかを見ておくと、期待値の置き方を誤りにくくなります。
もう一点、実務で重要になるのが、計算を途中で打ち切るという選択です。分枝限定法は、探索の途中でも「いま手元にある最良の整数解」と「まだ切り捨てていない枝が示す上限」の両方を持っています。この2つの差を最適性ギャップと呼びます。ギャップが3%であれば、いま手元にある解は、理論上の最適解から見ても最大3%しか劣っていないことが保証されます。実務では、ギャップが一定値を下回った時点で計算を打ち切る運用が一般的です。最後の1%を詰めるために計算時間を10倍かけることに、業務上の価値がないことは多いためです。「最適解が出るまで待つ」のではなく「許容できるギャップと時間の上限を先に決める」という考え方は、計算量の性質から導かれる実務上の要点です。
ここまで見てきたとおり、型が1段変わるだけで、計算時間の桁も、答えの保証の強さも変わります。したがって定式化の実務では、次の順に「より扱いやすい型に落とせないか」を検討するのが定石になります。
この順で降りていく理由は明快です。上の段ほど、計算時間が読め、答えの保証が強く、使える道具が多いからです。とくに3つ目の「整数にする変数を最小限に絞れないか」は、実務で効果が大きい割に見落とされやすい観点です。たとえば生産量そのものは連続量として扱い、段取り替えを行うかどうかの判断だけを整数にすれば、整数の変数は大幅に減ります。10,000個作るか10,001個作るかの違いは業務上ほとんど意味がないのに、律儀に整数の条件を付けてしまい、計算時間を無用に悪化させている定式化は珍しくありません。整数にすべきなのは、小数では業務上の意味が失われる量と、判断そのものを表す変数だけです。
非線形に見える課題も、多くは一次式の組合せに落とせます。絶対値や最大値を含む目的関数、数量に応じて単価が段階的に変わる料金体系、条件によって有効になったり無効になったりする制約は、いずれも補助的な変数を導入することで一次式の範囲に収まります。この書き換えの具体的な手順は第5章で扱います。ここで押さえておきたいのは、「非線形に見えるから非線形計画問題として解く」という短絡が、多くの場合は不要な遠回りだということです。
それでも落とせない場合の手段が、問題の分割です。時間軸で分けて1週間ずつ順に解く、地域で分けて拠点ごとに解く、階層に分けて上位で大枠を決めてから下位で詳細を詰める、といった分け方があります。分割すると全体としての最適性は失われますが、各部分は扱いやすい型に収まり、計算が回るようになります。全体を1つの巨大なMIPとして書いて解けないまま止まるより、分割して毎日回るものを作るほうが、業務上の価値は高いという判断はしばしば正当です。
この章の内容は、数学的な分類の知識にとどまるものではありません。型が決まると、プロジェクトに必要なものがほぼ連動して決まるからです。LPで済むと分かれば、必要なのは係数を埋めるためのマスタデータの整備が中心になり、計算基盤への投資はほとんど要りません。MIPに入ると、計算時間の検証工程が必要になり、試作を早い段階で作って実データで解かせる計画を組む必要が出てきます。ヒューリスティクスを使う判断をしたなら、解の品質をどう評価し、どう関係者に説明するかを設計に含めなければなりません。型の見立ては、そのまま工数とリスクの見立てになります。
注意しておきたいのは、型は途中で変わることがある、という点です。要件のヒアリングを重ねる中で「最低発注ロットは50個単位です」「同じ担当者を2日連続で同じ工程に入れることはできません」といった条件が1つ出てくるだけで、それまでLPだった問題がMIPに変わります。制約が1本増えただけに見えても、計算時間の見通しは書き換わります。定式化の途中で新しい制約が出てきたときは、その制約が型を変えるものかどうかを必ず確認し、変えるものであれば計算時間の検証をやり直す。この習慣を持っておくと、開発の終盤で計算が終わらないことに気づく事故を避けられます。
逆に、型を意図的に変えないという判断もあり得ます。厳密に書けば整数の条件が必要な要件でも、丸めても制約を破らないことが確かめられる場合に限り、連続量のまま解いて最後に人が丸めるという運用にすることがあります。理論的な正しさよりも、毎日確実に計画が出ることのほうが重要な場面は実際にあります。どこまでを数式で厳密に表し、どこからを人の運用に委ねるかは、型の性質を理解したうえで下す設計判断です。
次章では、業務課題と定式化パターンの対応表を扱います。
『新版 数理計画入門』(福島雅夫、朝倉書店):線形計画から非線形計画、整数計画までを一冊で見通せる標準的な教科書です。この章で扱った凸性の意味や、緩和と分枝限定法がなぜ有効なのかを、定義と証明までさかのぼって確認したい場合の土台になります。
配送ルートの決定、勤務表の作成、出店先の選定、発注量の決定。最適化の相談として持ち込まれる業務課題は、担当する部門も扱う対象も大きく異なりますが、最適化問題として書き下したときの行き先には、それほど多くの種類がありません。実務で扱われる課題の大半は、すでに名前の付いた定番の型のどれかに収まります。自社の課題を数式に翻訳する作業は、白紙から発想する作業ではなく、整理済みの型のどれに最も近いかを見立てる作業だということです。
この見立てを先に済ませておくと、後の工程がかなり短くなります。型が決まれば、第2章の3点セットのうち決定変数の形はほぼ自動的に決まり、第3章の分類のどこに属するのかも同時に定まるからです。集めるべきデータも、想定すべき計算時間も、そこから逆算できます。この章では、よくある業務課題と対応する定式化パターンの対応表を示し、各行について決定変数が何になるのか、どの部門のどんな場面で現れるのかを解説します。各型の書き下し方と例題は第6章から第12章で個別に扱うため、この章は自社の課題から該当する章に辿り着くための引き当てに徹します。
実務で最適化の話が出てくる場面は、意外なほど型が決まっています。よくある業務課題と、対応する定式化パターンを整理しました。自社の課題を最適化の言葉に翻訳する際の出発点としてお使いいただけます。

| 業務課題 | 定式化パターン | 典型的な決定変数 | 詳しく扱う章 |
|---|---|---|---|
| 配送ルートの決定 | 巡回セールスマン問題、配車計画問題(VRP) | 地点iの次に地点jへ向かうかどうか(0か1) | 第12章 |
| シフト・勤務表の作成 | 割当問題+ソフト制約 | スタッフsをシフトtに割り当てるかどうか(0か1) | 第7章 |
| 生産計画・製造順序の決定 | ロットスケジューリング問題 | 各期の製品別生産量、段取り替えの有無 | 第6章 |
| 拠点・店舗の配置 | 集合被覆問題、p-メディアン問題 | 候補地iを開設するかどうか(0か1) | 第8章 |
| 倉庫から店舗への配分 | 輸送問題 | 倉庫iから店舗jへ送る数量 | 第9章 |
| 発注量・在庫水準の決定 | 経済発注量モデル、新聞売り子モデル | 1回あたりの発注量、目標在庫量 | 第10章 |
| 投資・施策の選定 | ナップサック問題 | 施策iを採択するかどうか(0か1) | 第11章 |
| 要員のスキル別配置 | 割当問題(二部グラフのマッチング) | 要員pを業務qに割り当てるかどうか(0か1) | 第7章 |
この表を眺めると、決定変数の多くが0か1を取る変数であることに気づきます。ビジネスの意思決定の大半は「やるか、やらないか」「割り当てるか、割り当てないか」という離散的な選択であり、それを素直に表現できるのがMIPである、という関係です。逆に、決定変数が連続的な数量になっているのは、生産量と輸送量と発注量の3つだけです。この違いは計算時間の見通しにそのまま効いてきます。第3章で扱ったとおり、連続量だけで書ける課題は規模の心配がほとんど要らず、判断そのものを変数にする課題は規模が増えたときの検証が要る、という差になります。
もう一点、表の8行はいずれも「何を決めるのか」で区別されていることに注意してください。同じ物流という領域の中に、拠点をどこに置くか、そこから何個送るか、どの順で回るかという3つの異なる意思決定が並んでいます。これらは扱う型も、必要なデータも、決め直す頻度も別物です。自社の課題を表に当てはめるときは、部門名や領域名ではなく、決めたい対象そのもので引くと迷いにくくなります。
決定変数は、地点iの直後に地点jへ向かうかどうかを表す0か1を取る変数です。車両が複数台になれば、そこに車両を表す添字が加わります。順序そのものを変数にするのではなく、地点と地点をつなぐ線を選ぶかどうかで順序を表現する点が、この型の特徴です。
現れる場面は物流に限りません。卸や小売の店舗配送、フィールドサービスの巡回、設備の定期点検、訪問介護、廃棄物の収集、営業担当の訪問計画まで、「複数の訪問先を1台または数台で回る」という構造を持つ業務はすべてこの型に入ります。多くの現場では、ベテラン担当者が地図と過去の実績を見ながら順序を決めており、その担当者が異動すると品質が落ちる、という悩みとセットで相談が来ます。
必要になるデータは、地点間の距離または所要時間です。直線距離ではなく道路上の実距離や実所要時間を使わないと、現場が受け入れられない計画が出てきます。加えて、車両の積載量、訪問先ごとの受け入れ可能時間、ドライバーの拘束時間が制約として入ります。これらが増えるほど、単純な巡回の型から配車計画の型へと移っていきます。
引き当ての目印は、「回る順番まで決めたいのか」という一点です。順番まで決めたいならこの型で、どこへ何個送るかまでで足りるなら次に述べる輸送問題の型になります。この2つは物流の課題としてはひとまとまりに語られがちですが、定式化としては別物です。訪問順序を含むこの型は組合せが急激に増えるため、規模によっては厳密な最適解を諦める判断が必要になります。その事情と具体的な書き下し方は第12章で扱います。
決定変数は、スタッフsをシフトtに割り当てるかどうかを表す0か1を取る変数です。個人を特定せずに「この時間帯に何人配置するか」という人数だけを決める書き方もあり、規模や目的に応じて使い分けます。前者は個々の希望や資格を反映できる代わりに変数が多くなり、後者は軽い代わりに個人の事情を扱えません。
店舗や飲食店のシフト、コールセンターの要員計画、病院や介護施設の勤務表、警備や運転業務の当直表、工場の交代勤務まで、時間帯ごとに必要な人数が決まっている業務はすべてこの型です。作成に毎月数日を要し、担当者の負担が特定の人に集中している、という形で課題が顕在化することが多い領域でもあります。
この型を特徴づけるのは、守るべき条件の性格が2種類に分かれる点です。法令や労使協定に由来する条件は破ることが許されず、個人の勤務希望や公平性は満たせるに越したことはないが必須ではありません。この2種類を同じように書いてしまうと、条件を同時に満たす解が存在しない状態に陥ります。ここでソフト制約が使われますが、その仕組みは第5章、シフトへの具体的な適用は第7章で扱います。
集めるデータは、時間帯別の必要人数、各スタッフの契約時間と勤務可能日、保有資格、提出された勤務希望、過去の勤務実績です。とくに必要人数は、来店客数や着信数の予測から導かれることが多く、予測の工程と最適化の工程が接続する典型的な場面になります。
決定変数は、各期の製品別生産量と、段取り替えを行うかどうかの判断です。前者は連続的な数量、後者は0か1を取る変数になります。この2種類が同じモデルに同居することが、この型の扱いにくさの原因であり、同時に表現力の源でもあります。
現れるのは製造業の月次・週次の生産計画、化学や食品における配合の決定、鉄鋼や紙のような素材産業での切り出し計画、複数工場を持つ企業での生産の振り分けです。需要予測を受け取ってから実際の製造指示に落とすまでの間に、必ずこの意思決定が挟まります。
引き当てで重要なのは、「何をどれだけ作るか」までなのか、「どの順で作るか」まで含むのかという線引きです。数量だけを決める課題であれば、決定変数はすべて連続量で済み、第3章の分類でいえばLPに収まります。ここに、製品を切り替えるたびに段取り時間と費用が発生する事情や、最低生産ロットの条件が入ると、判断を表す変数が必要になってMIPに移ります。この移行は制約が1本増えるだけのように見えて、計算時間の見通しを大きく変えます。
数量を決める側の書き下し方、複数期間にまたがる計画と在庫の繰り越し、設備能力の割り振りについては第6章で扱います。段取り替えのように判断を伴う条件の書き方は第5章の技法にあたります。実務では、まず数量だけを決めるモデルを作って全体の姿を確かめ、そこに順序や切り替えの条件を足していく進め方が確実です。
決定変数は、候補地iを開設するかどうかを表す0か1を取る変数です。既存拠点の閉鎖を検討する場合も、同じ変数で「維持するかどうか」を表せば同じ型に収まります。新設と統廃合は経営上はまったく別の判断に見えますが、定式化としては同じ構造です。
物流センターや配送拠点の配置、店舗の出店計画、保守・修理拠点の配置、営業所の統廃合、設備や機器の設置場所の選定などが該当します。判断の頻度は低い一方で、一度決めると数年から十数年にわたって費用構造を規定するため、1件あたりの金額的な重みが大きい領域です。
同じ拠点配置でも、何をもって良い配置とみなすかによって型が分かれます。すべての需要地を一定距離以内でカバーすることを条件にするなら集合被覆問題、平均的な距離を短くすることを目的にするならp-メディアン問題、各拠点が処理できる量に上限があるなら容量制約付き施設配置問題になります。この使い分けと、それぞれの書き下し方は第8章で扱います。
必要なデータは、候補地ごとの開設固定費と運営費、需要地の分布と需要量、候補地と需要地の間の距離または所要時間です。候補地の一覧そのものを最適化で作ることはできないため、不動産や事業開発の担当者が候補を挙げる工程が前段に必要になります。この型は、選択肢を用意する人間の作業と、その中から選ぶ計算の作業が明確に分かれている点で、他の型と性格が異なります。
決定変数は、倉庫iから店舗jへ送る数量です。連続的な量として扱えるため、判断を表す変数を含む型に比べて計算が軽く、規模が大きくても実用的な時間で解ける部類に入ります。
倉庫から店舗への在庫配分、工場から倉庫への補充、複数の調達先から複数の工場への原料の割り振り、複数工場への生産量の振り分けなどが該当します。「送り出す側に上限があり、受け取る側に必要量があり、間に単位あたりの費用がある」という構造を見つけたら、この型を疑ってよい場面です。
この型は第3章の分類でいうネットワーク型に属します。倉庫と店舗を点、輸送経路を線と見なすと問題全体がグラフの形で表現でき、そのおかげで専用の解法が使えます。加えて、整数の条件を明示的に書かなくても答えが自然に整数になるという性質を持つ場合があります。この性質が成り立つ理由と、最小費用流問題への一般化については第9章で扱います。
実務で追加されやすい条件は、供給量と需要量が一致しない場合の扱い、店舗ごとの最低配分量、輸送手段ごとの積載単位、複数段階を経由するネットワークです。なお、この型が答えるのは「どこからどこへ何個送るか」までであり、それを何台の車でどの順に運ぶかは答えません。後者は配送ルートの型の担当です。両者を1つのモデルに詰め込もうとして行き詰まる相談は少なくありません。
決定変数は、1回あたりの発注量、目標在庫量、発注のタイミングを決める在庫水準です。他の型と違って、決めた結果が1回限りの計画ではなく、当面のあいだ繰り返し使われる運用ルールになる点が特徴です。
資材や部品の調達、小売店舗の商品発注、通信販売の在庫計画、生鮮品や季節商品の仕入れが該当します。決定の頻度が高く、対象となる品目数が多いため、1品目あたりの改善幅が小さくても総額では大きな効果になりやすい領域です。
この領域は2つの型に分かれます。需要が比較的安定していて、発注のたびに固定的な費用がかかる状況では経済発注量モデルが使われます。売れ残りと品切れの損失が非対称で、仕入れをやり直せない状況では新聞売り子モデルが使われます。どちらに当てはまるかは、発注をやり直せるかどうかと、需要のばらつきの大きさで判断します。詳しくは第10章で扱います。
この型は、需要予測との接続が最も強い領域でもあります。他の型では予測値を所与の定数として受け取れば足りることが多いのに対して、ここでは需要の平均値だけでは決定に届かず、ばらつきの情報が必要になります。予測の担当者が平均値だけを渡している場合、最適化の側で使える情報が欠けている、という状態が起きます。この接続の詳細も第10章で扱います。
決定変数は、施策iを採択するかどうかを表す0か1を取る変数です。候補の一覧、各候補の費用、各候補の期待効果、そして使える予算という4つが揃えば、この型として書けます。
年次の予算配分、設備投資の選定、研究開発テーマの絞り込み、販促施策の組み合わせ、システム化案件の優先順位付けが該当します。経営企画や財務の部門が毎年繰り返している作業であり、最適化の対象として最も導入の敷居が低い領域の1つです。必要なデータが既存の稟議資料や投資計画書の中にほぼ揃っているためです。
この型の実務的な価値は、費用対効果の高い順に選ぶという直感が、予算の使い切りを考えると最良にならない場合がある点にあります。その仕組みと具体例は第11章で扱います。あわせて、「この施策を選ぶなら前提となるあの施策も必要」という依存関係や、「この2案は排他」という条件も表現できます。こうした条件の書き方は第5章の技法にあたります。
注意すべきは、計算の質が入力の質を超えないことです。各案の期待効果の見積もりが根拠の乏しい数字であれば、最適化は根拠の乏しい選択を精密に導くだけになります。この型を導入する価値は、選定作業の自動化よりも、各案の効果を同じ物差しで見積もる規律が組織に入ることにある、という見方もできます。
決定変数は、要員pを業務qに割り当てるかどうかを表す0か1を取る変数です。シフト作成と同じ割当問題の型ですが、割り当てる相手が時間帯ではなく業務や案件である点が異なります。
プロジェクトへの人員アサイン、保守要員の担当設備の割り振り、営業担当のエリア割り、教員の担当科目、審査員と案件の対応付けなどが該当します。人と業務の組み合わせごとに適合度や習熟度の差があり、その差を数値化できる場面で効果が出ます。
この型は、点を2つのグループに分けて、片方から片方へ線を引く構造として表現できます。二部グラフのマッチングと呼ばれる形で、ネットワーク型の一種です。人数と業務数が同じで一対一に対応させる場合は素直に解けますが、1人が複数の業務を持つ、1つの業務に複数人を充てる、担当のいない業務が出ることを許す、といった条件が入ると書き方が変わります。詳しくは第7章で扱います。
シフト作成との引き当ての違いは、満たしたい条件が「時間帯ごとの人数」なのか「人と業務の適合」なのかという点です。両方が同時に必要な業務もあり、その場合は2段階に分けて解く進め方が取られます。
ここまでは決めたい対象から引きましたが、自部門の日常業務から辿るほうが早い場合もあります。同じ表を部門の側から並べ替えたものが次の表です。
| 部門 | よくある意思決定 | 対応する定式化パターン | 詳しく扱う章 |
|---|---|---|---|
| 製造 | 生産量と製造順序の決定 | ロットスケジューリング問題 | 第6章 |
| 製造 | 設備投資の選定 | ナップサック問題 | 第11章 |
| 物流 | 配送ルートと配車の決定 | 巡回セールスマン問題、配車計画問題 | 第12章 |
| 物流 | 倉庫から店舗への配分 | 輸送問題 | 第9章 |
| 物流 | 物流拠点の配置と統廃合 | 集合被覆問題、p-メディアン問題 | 第8章 |
| 小売・EC | 商品ごとの発注量の決定 | 経済発注量モデル、新聞売り子モデル | 第10章 |
| 小売・EC | 店舗間の在庫移動 | 輸送問題 | 第9章 |
| 小売・EC | 出店先の選定 | 集合被覆問題、p-メディアン問題 | 第8章 |
| 人事・店舗運営 | 勤務表とシフトの作成 | 割当問題+ソフト制約 | 第7章 |
| 人事・店舗運営 | 要員のスキル別配置 | 割当問題 | 第7章 |
| 財務・経営企画 | 年次予算の配分と投資選定 | ナップサック問題 | 第11章 |
| 財務・経営企画 | 資金や資源の按分 | 線形計画問題 | 第6章 |
| 営業 | 訪問計画の作成 | 巡回セールスマン問題、配車計画問題 | 第12章 |
| 営業 | 担当エリアと顧客の割り振り | 割当問題 | 第7章 |
この表で目を引くのは、同じ型が複数の部門に現れることです。割当問題は人事にも営業にも製造にも登場し、ナップサック問題は設備投資でも予算配分でも同じ形になります。輸送問題は物流の課題として語られますが、資源を複数の受け手に配分する構造はどの部門にもあります。つまり、型を1つ身につけると、その知識は部門をまたいで使い回せるということです。最適化の社内展開が、業務ごとの個別開発ではなく型の横展開として設計できる根拠がここにあります。
逆に、同じ部門の中に性格の異なる型が並んでいることも読み取れます。物流部門は、年単位で決める拠点配置、週単位で決める配分、日単位で決めるルートという3つの型を同時に抱えています。この3つは決め直す頻度も、関わる部署も、必要なデータの粒度も違います。物流最適化という1つのプロジェクトとして立ち上げるより、どの意思決定を対象にするかを先に絞るほうが、成果までの距離は短くなります。

対応表を使ううえで実際につまずきやすいのは、似て見えて別の型になる組み合わせです。代表的なものを挙げます。
もう1つ、対応表のどの行にも当てはまらないと感じる場合があります。その多くは、次のいずれかに該当します。選択肢がもともと数個しかない場合は、全部を計算して比べれば済むため最適化の枠組みを持ち出す必要がありません。何を良いとするかが関係者の間で定まっていない場合は、型を探す前に第2章の3点セットを書き出す作業に戻る必要があります。決められる変数が自部門に1つもなく、すべてが他部門や取引先の決定である場合は、対象そのものを選び直したほうが早く成果が出ます。型が見つからないことは、必ずしも難しい問題であることを意味しません。
もう一つ、実務で判断を要するのは、複数のパターンが組み合わさる場合です。たとえば配送計画は、配車計画問題に積載量制約と時間枠制約が加わり、さらに車両の割当が入ります。この場合も、まずは単純な型で解ける形に落として全体像をつかみ、そこから制約を1つずつ足していく進め方が確実です。最初から完全な問題を書こうとすると、解が出ないときに原因の切り分けができなくなります。
この進め方を手順に落とすと、次の順になります。
4番目の工程が、実務では効いてきます。現場から挙がる条件をすべて書き込むと、モデルは重くなる一方で、答えは大して変わらないことがあります。制約を1本ずつ足しながら答えの変化を見る手順を踏んでおけば、どの条件が業務上の本質で、どの条件が念のための申し送りなのかが、数字の形で分かります。この記録は、後に運用を引き継ぐときの資料にもなります。
分割の切り口として最も扱いやすいのは、意思決定の時間軸です。拠点をどこに置くかは年単位、どの倉庫からどの店舗へ配分するかは週単位、どの順に回るかは日単位で決め直されます。決め直す頻度が違う判断を1つのモデルに詰め込むと、日次で回すには重すぎ、年次の判断には細かすぎる中途半端なものができます。頻度ごとに分けたうえで、上位の決定を所与の条件として下位のモデルに渡す構造にすると、それぞれが扱いやすい規模に収まります。この構造は、拠点配置の担当部署と日々の配車の担当部署が別であるという組織の実態とも整合します。
分割すると全体としての最適性は失われますが、そのことが業務上の損失に直結するとは限りません。年に一度の拠点配置と毎日の配車を同時に最適化して得られる上積みは、多くの場合、日々の配車が確実に回ることの価値を下回ります。どこまでを1つのモデルで扱い、どこからを分けるかは、数学の問題ではなく、運用に載るかどうかで決める設計判断です。
組み合わせの扱いでもう一点触れておくと、複数の型が並ぶ課題では、どの型を主軸に据えるかによって残りの型の扱いが決まります。配送計画であれば、ルートの決定を主軸に据えて積載量を制約として扱うのが一般的ですが、積み合わせの効率が支配的な業務では、どの荷物をどの車両に載せるかを主軸に据え、ルートを後段で決める構成もあり得ます。どちらを主軸にするかは、その業務でコストの大半がどこから発生しているかで決めます。この見極めができていないまま設計に入ると、精緻に作ったモデルが業務の主要因を扱っていない、という結果になりかねません。
次章では、頻出の表現テクニックを扱います。
『Excelで手を動かしながら学ぶ数理最適化 ベストな意思決定を導く技術』(三好大悟、インプレス):この章で引き当てた型を、実際に手を動かして確かめたい場合に向く一冊です。表計算ソフトのソルバー機能を使って各パターンを小さく試せる構成のため、自部門の課題がどの型に当てはまるかを、少ないデータで検証してから本格的な開発に進む判断がしやすくなります。
現場の条件を数式に載せる作業は、定式化のなかで最も手が止まりやすい工程です。「開設しない拠点には在庫を置かない」「この2つの施策は同時には実施できない」「勤務希望はできるだけ通したい」「100個を超えた分は単価が下がる」といった条件は、業務の言葉としては明確でも、そのままでは不等式の形になりません。決定変数と目的関数までは書けたのに制約の欄で止まってしまうという状態は、実務でよく起こります。
この壁は、新しい問題の型を探すのではなく、条件の書き換えの引き出しを増やすことで越えられます。上に挙げた条件はいずれも、補助的な変数を1つ足して不等式を数本組み合わせるだけで表現でき、第3章の分類でいえばMIPの枠内に収まります。裏を返せば、この引き出しがないうちは、線形の道具で書けるはずの課題まで「うちの業務は複雑すぎて数式にならない」と判断してしまいます。
定式化に慣れるうえで効果が大きいのは、「この条件はこう書く」という言い換えの引き出しを増やすことです。この章では、使用頻度の高い7つを、仕組みと最小限の数値例で順に見ていきます。いずれも第2章の3点セットのうち、制約と目的関数の書き方に関わるものです。
「店舗iを開くなら1、開かないなら0」と定めた変数を用意すれば、開設の有無という定性的な判断が数式に載ります。固定費は \(1000 \times x_i\) のように、変数に単価を掛けるだけで目的関数に組み込めます。
連続変数だけでは、この種の判断は表せません。生産量や輸送量のように「どれだけ」を決める変数は途中の値に意味がありますが、拠点の開設や施策の採否は途中の値に意味がなく、0.6だけ開設された店舗は現実に存在しません。0か1を取る変数は、この不連続な選択をそのまま変数の値域として書き下したものです。この1点だけで、線形計画の道具立てで扱える業務課題の範囲が大きく広がります。
使うときに効くのは、変数の意味を1文で言い切っておくことです。「候補地iの状態」といった曖昧な定義のままでは制約が書けません。「候補地iに拠点を開設するなら1、開設しないなら0」のように、1のときに何が起きるのかまで含めて書きます。添字の範囲も同時に決めます。拠点なら候補地の集合、施策なら候補施策の集合、シフトなら「スタッフと勤務日と時間帯の組」というように、何と何の組み合わせに対して変数を1つずつ置くのかを明示します。ここが曖昧なまま制約を書き始めると、後から数式の意味を追えなくなります。
0か1を取る変数の合計を取ると、そのまま個数の制約になります。候補地5か所から3か所までしか開設しないなら \(\sum_i x_i \leq 3\)、ちょうど2か所を選ぶなら \(\sum_i x_i = 2\)、少なくとも1か所は開設するなら \(\sum_i x_i \geq 1\) です。「いくつ選ぶか」という業務上の条件が、変数の足し算1本で書けます。
注意点は変数の個数です。添字を掛け合わせる設計にすると、個数は掛け算で増えます。スタッフ50人、日数30日、時間帯3区分で「誰がいつどの時間帯に入るか」を表すと、変数は50×30×3で4,500個になります。この規模はソルバーが十分扱える範囲ですが、ここに車両や工程といった添字がもう1つ加わると桁が変わります。整数条件が加わると計算時間が跳ね上がる理由は第3章で扱ったとおりで、添字の設計はそのまま計算時間の設計になります。時間帯を1時間刻みにするか2時間刻みにするかといった粒度の判断は、業務側と早い段階ですり合わせておく価値があります。
「開設しない店舗には在庫を置けない」という条件は、そのままでは数式になりません。ここで十分に大きな定数Mを用意し、在庫量 \(y_i\) について \(0 \leq y_i \leq M x_i\) と書きます。\(x_i\) は開設するかどうかを表す0か1を取る変数です。\(x_i = 0\) のときは \(y_i \leq 0\) と非負条件が挟み込んで \(y_i = 0\) に固定され、\(x_i = 1\) のときは実質的に制約がかからないという挙動になります。非負条件を書き落とすと、開設しない店舗に負の在庫を置く解が許されてしまいますので、量を表す変数には必ず下限を添えます。この書き方をbig-M法と呼びます。
ここで登場する定数Mは、単に「大きな数」ではなく、その変数が現実に取りうる上限を意味しています。上の例であれば、店舗1か所に置ける在庫の物理的な上限がMにあたります。倉庫の容量が500個であれば \(M = 500\) と置けば足ります。
Mを必要以上に大きく取ると、計算時間が悪化します。理由は、整数条件を外して解く緩和問題(第3章)の振る舞いにあります。\(M = 500\) であれば、在庫を500個置くには \(x_i\) を1まで上げる必要があり、固定費が在庫量に見合った形でかかります。ところがMを1,000,000と置くと、\(x_i = 0.0005\) という値でも \(y_i \leq 500\) が許されてしまい、固定費をほとんど払わずに在庫を置いた解が緩和問題の答えとして出てきます。この答えは現実の最適解から遠く、そこから整数解にたどり着くまでの探索が長くなります。「Mはできる限り小さく」という定石は、この現象を避けるためのものです。
実務では、Mをデータから計算して決めます。在庫なら倉庫容量、生産量なら設備能力、時間なら計画期間の長さ、金額なら予算上限というように、その変数の上限を与えている数値がどこかにあるはずです。すべての制約に同じMを使う必要もありません。制約ごとに \(M_i\) と添字を付け、それぞれに合った上限を入れるほうが計算の面では有利です。桁の極端に大きい係数は数値計算上の誤差も招くため、この点でも小さいMのほうが安全です。
big-M法の使いどころは、在庫と開設の関係にとどまりません。「生産するなら最低ロット以上」という条件は、生産量 \(y\) と実施の有無 \(x\) に対して \(L x \leq y \leq M x\) と書きます。\(x = 0\) なら \(y = 0\)、\(x = 1\) なら \(L\) 以上 \(M\) 以下という挙動になり、「作らないか、作るなら100個以上」という現場のルールがそのまま制約になります。段取り費用も同じ形で、「その製品を作るなら段取り費用がかかる」という関係を、制約 \(y \leq M x\) と目的関数の項 \(c x\) の組で表します。0か1を取る変数と量の変数を結び付ける接着剤がbig-M法である、と捉えると使いどころを見つけやすくなります。
「計画値と実績値のずれ \(|a – b|\) を最小化したい」という要望は頻出しますが、絶対値はそのままでは線形になりません。補助変数 \(z\) を導入して \(z \geq a – b\) と \(z \geq b – a\) の2本の制約を置き、\(z\) を最小化すれば、結果的に \(z\) は絶対値と一致します。最大値の最小化も同じ発想で線形化できます。
最大値のほうを具体的に書くと次のようになります。工程の完了時刻が \(f_1, f_2, \ldots, f_n\) と並んでいるとき、最も遅い完了時刻を小さくしたいなら、補助変数 \(z\) を置いて \(z \geq f_k\) という制約をすべての \(k\) について並べ、\(z\) を最小化します。\(z\) はすべての完了時刻以上でなければならず、かつできるだけ小さくしたいので、結果として最大の完了時刻に一致します。全工程が終わる時刻の短縮、最も負荷の重い担当者の作業量の抑制、最も遠い顧客までの距離の短縮といった課題は、いずれもこの形で書けます。合計を小さくする定式化と、いちばん悪いところを良くする定式化は別物であり、どちらが業務の要請かを確認してから書く必要があります。
ずれの表し方には、正負に分ける書き方もあります。計画値と実績値の差を \(a – b = p – n\) と置き、\(p \geq 0\)、\(n \geq 0\) としたうえで \(p + n\) を最小化する形です。\(p\) が超過、\(n\) が不足を表すため、「超過は保管費、不足は機会損失」というように、上振れと下振れに別々の重みを掛けられます。目標値からのずれを小さくするという考え方そのものは第2章で扱っています。
この線形化には成立条件があります。\(z \geq a – b\) と \(z \geq b – a\) が絶対値と一致するのは、\(z\) を小さくしたい力が働いているときだけです。\(z\) を大きくしたい問題や、\(z\) が制約の左辺にしか現れず下げる動機がない問題では、\(z\) は絶対値より大きい値のまま放置されます。ずれを大きくしたい、あるいは「ずれが一定以上あること」を要求したいという定式化は、この手では書けません。目的の向きと制約の向きが噛み合っているかを、線形化のたびに確認する必要があります。
制約を厳密に書きすぎると、条件を同時に満たす解が存在せず、ソルバーが「実行不可能(infeasible)」とだけ返してくる状態に陥ります。実務ではこれが最も困ります。そこで、破ってもよいが破るとペナルティがかかる制約として書く方法があります。違反量を表す補助変数を用意し、それに重みを掛けて目的関数に足し込む形です。これをソフト制約と呼びます。シフト作成における勤務希望の考慮は、その代表例です。労働基準は絶対に守るべき制約、個人の希望はソフト制約、と分けて設計します。
書き方そのものは単純です。もともと \(g(x) \leq b\) と書いていた制約に違反量の補助変数 \(s \geq 0\) を足して \(g(x) \leq b + s\) とし、目的関数にペナルティの項を加えます。費用の最小化であれば \(w s\) を足し、利益の最大化であれば \(w s\) を引きます(重み \(w\) は正の値)。違反したときに目的関数の値が悪くなる向きに入れる、ということです。\(s\) が0であれば元の制約が守られており、\(s\) が正の値を取れば、その分だけペナルティが目的関数に乗ります。守れるなら守り、どうしても守れないときだけ最小限の違反で済ませる、という挙動になります。
設計の要点は、重み \(w\) をどう決めるかです。金額に換算できるなら、金額をそのまま使うのが最も筋の通った決め方です。欠品1個あたりの機会損失が200円であれば、欠品量の補助変数に200を掛けて目的関数に足します。この場合、ペナルティは架空の罰点ではなく実際の損失額になり、目的関数全体が金額で統一されます。換算できない項目については、主目的の値と桁を合わせることを目安にします。総コストが数百万円の規模の問題で重みを1と置いても、その制約は事実上無視されます。逆に極端に大きな重みを置けば、それは絶対に守る制約と変わりません。重みは業務上の優先順位を数値に翻訳したものであり、後から説明を求められる箇所でもあるため、根拠を書き残しておくことが望ましいといえます。
違反の測り方にも選択肢があります。違反量に比例してペナルティがかかる扱いにするなら、連続の補助変数だけで足ります。「1回でも破ったら定額のペナルティ」という扱いにしたいなら、破ったかどうかを表す0か1を取る変数を置き、big-M法で違反量と結び付けます。前者は違反の量を小さく抑える方向に、後者は違反する箇所の数を減らす方向に解が寄ります。1人が大きく譲るのと、多くの人が少しずつ譲るのとで、どちらが受け入れられやすいかは業務によって異なります。
硬く書くものと柔らかく書くものの切り分けは、業務側との合意事項です。法令や物理的な制約は硬い制約として書きます。目標値、希望、望ましい水準といった項目はソフト制約の候補です。この切り分けは技術的な判断ではなく、「どこまでなら譲れるか」という業務判断であり、定式化の担当者が独断で決めるものではありません。
ソフト制約には、解が出ないときの診断としての価値もあります。すべての制約を硬く書いた問題が実行不可能になっても、どの条件が原因かは返ってきません。一方、疑わしい制約をソフトに切り替えて解き直せば、違反量の補助変数の値が「どの制約が、どれだけ足りなかったか」を数値で示します。これは制約の書き間違いやデータの誤りを見つける手がかりにもなります。ただし、何でもソフトにすると、すべての制約を少しずつ破った解が返ってきて、どれも守られていない計画ができあがります。柔らかくしてよいものだけを柔らかくする、という原則は崩さないことです。勤務希望をソフト制約として扱うシフト作成への本格的な適用は、第7章で扱います。
業務のルールの多くは「AならばB」「AとBは同時にできない」という論理の形をしています。0か1を取る変数を使うと、この種の条件は不等式1本で書けます。
「施策Aを実施するなら施策Bも実施しなければならない」という含意は \(x_A \leq x_B\) です。\(x_A = 1\) なら \(x_B\) は1以外を取れず、\(x_A = 0\) なら \(x_B\) は自由です。含意の向きがそのまま不等号の向きになります。基幹システムの刷新を行うならデータ基盤の整備も必要、といった前提条件がこの形にあたります。
排他は \(x_A + x_B \leq 1\) です。両方が1になると左辺が2になって制約を破るため、同時採択が禁じられます。「どちらか一方を必ず選ぶ」なら \(x_A + x_B = 1\)、「セットでしか実施できない」なら \(x_A = x_B\) です。個数の条件は前述のとおり合計の不等式で、「候補のうち少なくとも1つ」は \(\geq 1\)、「多くとも2つ」は \(\leq 2\)、「ちょうど1つ」は \(= 1\) と書き分けます。
「AとBの両方を実施したときだけ追加の効果が出る」という条件には、少し工夫が要ります。効果は \(x_A x_B\) という積の形で表れますが、変数どうしの掛け算は線形ではありません。ここで新しい0か1を取る変数 \(z\) を置き、\(z \leq x_A\)、\(z \leq x_B\)、\(z \geq x_A + x_B – 1\) の3本を課します。\(x_A\) と \(x_B\) がともに1のときだけ3本目が \(z \geq 1\) となって \(z\) は1に決まり、それ以外の組み合わせでは最初の2本のいずれかが \(z\) を0に押さえます。あとは \(z\) に追加効果の金額を掛けて目的関数に足せば済みます。積を線形の形に置き換えるこの書き方は、相乗効果や併用条件を扱うときに繰り返し使います。
「2つの制約のうち、どちらか一方が成り立てばよい」という条件も書けます。\(g_1(x) \leq b_1\) と \(g_2(x) \leq b_2\) のいずれかを満たせばよいとき、0か1を取る変数 \(u\) を置いて \(g_1(x) \leq b_1 + M(1 – u)\)、\(g_2(x) \leq b_2 + M u\) と書きます。\(u = 1\) なら1本目が有効で2本目は実質的に外れ、\(u = 0\) ならその逆になります。big-M法が、条件付きの制約だけでなく制約そのものの選択にも使えることが分かります。「自社便で運ぶか外部委託にするかで守るべき条件が変わる」といった、選択によって適用ルールが切り替わる場面がこれにあたります。
投資や施策の選定で、依存関係や排他選択をこの形で組み込む具体例は第11章で扱います。
数量に応じて単価が変わる料金体系は、そのままでは線形になりません。ここで使うのが、量を区間ごとに分けて別々の変数で持つ書き方です。
単価が上がっていく形から見ます。電力料金が最初の100kWhまで1kWhあたり30円、次の100kWhまで40円、それを超える分は50円という段階料金を考えます。使用量 \(y\) を \(y = y_1 + y_2 + y_3\) と3つに分け、\(0 \leq y_1 \leq 100\)、\(0 \leq y_2 \leq 100\)、\(y_3 \geq 0\) としたうえで、費用を \(30 y_1 + 40 y_2 + 50 y_3\) と書きます。費用を小さくしたい問題であれば、ソルバーは単価の安い \(y_1\) から順に埋めるため、区間の順番を強制する制約を書かなくても正しい費用になります。使用量150kWhなら \(y_1 = 100\)、\(y_2 = 50\) となり、費用は5,000円です。区間が進むほど単価が上がる形は第3章でいう凸な形にあたり、補助変数を並べるだけで済みます。
逆に、数量割引のように単価が下がっていく形では、この手が効きません。安い区間から先に埋めようとするソルバーは、まとめ買いをしていないのに割引後の単価を使った解を作ってしまいます。この場合は、どの区間にいるのかを表す0か1を取る変数を区間ごとに用意し、選ばれた区間の外側の量を0に押さえる制約をbig-M法で置きます。「割引を受けるには一定量以上を買う必要がある」という条件を、変数の側に明示することになります。単価が下がる料金体系のほうが定式化は重くなる、と覚えておくと工数の見積もりを誤りません。
同じ考え方は、曲線を折れ線で近似する場面にも使えます。生産量に対して効率が変化する関係や、在庫量に対して費用が非線形に増える関係は、いくつかの点で区切って直線でつなげば線形の問題として扱えます。分割数を増やすほど近似は正確になり、そのぶん変数と制約は増えます。どこまで細かく刻むかは、必要な精度と許容できる計算時間から決める判断になります。実務では、まず粗く3区間ほどで解いて答えの傾向をつかみ、精度が足りなければ刻みを細かくする進め方が確実です。
工程や作業の順序に関する条件は、開始時刻を変数に取ると素直に書けます。工程 \(i\) の開始時刻を \(s_i\)、所要時間を \(p_i\) とすると、「工程 \(j\) は工程 \(i\) が終わってから始める」という先行制約は \(s_j \geq s_i + p_i\) です。この形は変数の1次式だけでできており、補助変数も0か1を取る変数も要りません。前工程の完了を待つ、承認が下りてから着手する、乾燥時間を置いてから次の作業に移る、といった条件はすべてこの1本で表せます。
難しくなるのは、同じ設備や同じ担当者に複数の作業が集中し、作業どうしを重ねられない場合です。工程 \(i\) と工程 \(j\) については「\(i\) が先か、\(j\) が先か」のどちらかが成り立てばよく、これは前節で見た選択の形になります。順序を表す0か1を取る変数 \(u_{i,j}\) を置き、\(s_j \geq s_i + p_i – M(1 – u_{i,j})\) と \(s_i \geq s_j + p_j – M u_{i,j}\) の2本を課します。\(u_{i,j} = 1\) なら \(i\) が先、0なら \(j\) が先という意味になり、どちらの順序を選んでも重なりが起きません。ここでのMは計画期間の全長を取れば十分で、これも小さく取るほど計算が軽くなります。
製品を切り替えるたびに段取り替えが必要な場合は、切り替え時間 \(t_{i,j}\) を足して \(s_j \geq s_i + p_i + t_{i,j} – M(1 – u_{i,j})\) と \(s_i \geq s_j + p_j + t_{j,i} – M u_{i,j}\) の2本にします。順序によって必要な段取り時間が変わるため、上の非重複の2本と同じく、こちらも両方向を書く必要があります。納期は \(s_i + p_i \leq d_i\) と書けますが、これを硬い制約にすると、少しでも間に合わない案件が1件あるだけで実行不可能になります。遅れ量の補助変数を置いて \(\ell_i \geq s_i + p_i – d_i\)、\(\ell_i \geq 0\) とし、目的関数にペナルティを掛ければ、遅れを最小限に抑えた計画が得られます。最も遅れた案件の遅れを小さくしたいなら、最大値の線形化を重ねて使います。この章のテクニックは、単独で使うより組み合わせて使う場面のほうが多いということです。
訪問順序そのものを決める問題、つまり配送ルートの決定では、順序の表し方が別の形になり、部分巡回、つまり訪問先の一部だけで小さな閉じた輪ができてしまう状態を禁じる制約が必要になります。これは第12章で扱います。
ここまでの7つを、業務の条件からの引き方でまとめます。定式化の途中で手が止まったときは、書きたい条件がこの表のどの行に近いかを探すところから始めると進みます。
| 表現したい業務の条件 | 書き方 | 補足 |
|---|---|---|
| やるかやらないかを決める | 0か1を取る変数 \(x\) | 1のときに何が起きるかまで定義に書く |
| いくつまで選ぶ、ちょうどいくつ選ぶ | \(\sum_i x_i \leq 3\) のような合計の不等式 | 不等号の向きで上限・下限・ちょうどを書き分ける |
| 選ばないなら量はゼロ | \(y \leq M x\) | Mはその変数の現実的な上限 |
| やるなら最低量以上 | \(L x \leq y \leq M x\) | 最小ロット、最低発注量 |
| 計画と実績のずれを小さくする | \(z \geq a – b\)、\(z \geq b – a\) を置いて \(z\) を最小化 | 小さくしたい向きでのみ成立する |
| いちばん悪いところを良くする | すべての \(k\) に \(z \geq f_k\) を置いて \(z\) を最小化 | 最大完了時刻、最大負荷、最遠距離 |
| 破ってもよいが破りたくない | 違反量 \(s\) を足して目的関数に \(w s\) を加える | 重みは金額換算が基本 |
| AならばB | \(x_A \leq x_B\) | 依存関係、前提条件 |
| AとBは同時にできない | \(x_A + x_B \leq 1\) | 二者択一なら等号にする |
| 両方そろったときだけ効果が出る | \(z \leq x_A\)、\(z \leq x_B\)、\(z \geq x_A + x_B – 1\) | 変数の積の線形化 |
| 段階的に単価が変わる | 区間ごとの変数に分ける | 単価が下がる形は0か1を取る変数が要る |
| この工程の後にあの工程 | \(s_j \geq s_i + p_i\) | 補助変数は不要 |
| 同じ設備で作業を重ねない | 順序変数 \(u_{i,j}\) とbig-M法の2本 | Mは計画期間の全長 |
使ううえでの見極めもあります。補助変数と0か1を取る変数は、増やせば増やすほど計算が重くなります。第3章で扱ったとおり整数条件は計算時間に直接効くため、「この条件は本当に必要か」「今回の意思決定に影響するか」を確かめずに全部を書き込むと、解けない問題ができあがります。実務では、まず条件を絞った素直なモデルを解いて答えの形を確かめ、そこに現場から出てきた条件を1つずつ足していく進め方が確実です。足した制約によって答えがどう変わったかを見れば、その条件が業務にどれだけ効いているかも同時に分かります。
もう1つ、これらのテクニックは条件を数式に載せる手段であって、何を制約にするかを決めてくれるものではありません。「開設しない拠点に在庫は置けない」という条件を書き忘れれば、どれだけ丁寧に線形化しても、現実には実行できない計画が出てきます。書き方の引き出しが増えたぶん、書くべき条件を漏らさず拾う作業の重みはむしろ増します。現場が当然のこととして口にしない前提こそ、制約として書き落とされやすい部分です。

次章では、生産計画と資源配分を線形計画で解く方法を扱います。
『最適化手法入門』(寒野善博、講談社):この章で扱った線形化や0か1を取る変数の使い方を、最適化の手法体系のなかに位置づけて確認できる一冊です。線形計画・非線形計画・凸計画・ネットワーク計画・整数計画を順に扱う構成のため、条件の書き換えがなぜ解きやすさに直結するのかを、解法側の理屈からたどりたい方に向いています。
生産計画の立案は、限られた設備時間と原料を、どの製品にどれだけ振り向けるかを決める意思決定です。製品ごとに1個あたりの利益が違い、1個作るために使う機械時間も原料の量も違うため、「利益の大きい製品から順に作る」という素直な方針が最善にならないことがあります。利益は大きいが機械時間を多く使う製品を優先した結果、機械の能力を先に使い切ってしまい、原料が余ったまま月末を迎える、といったことが起こるためです。表計算ソフトの上で製品ごとの数量を少しずつ動かしながら辻褄を合わせる作業は、製品が数品目のうちは成立しますが、資源の種類と製品の数が増えると、どこを動かせば全体が良くなるのかが見えなくなります。
この課題は、第3章の分類でいえばLPにあたります。生産量は連続量として扱ってよい場面が多く、利益も資源の消費量も生産量に比例するため、目的関数も制約もすべて一次式に収まるからです。そしてLPに落ちた問題からは、最適な生産量そのものに加えて、「この設備をあと1時間増やしたら利益はいくら増えるのか」「原料の仕入価格がいくらまでなら買い増す価値があるのか」という、投資判断や調達交渉に直結する情報が同じ計算から取り出せます。この取り出し方まで含めて使えることが、生産計画をLPで書く値打ちです。
例題:2種類の製品の生産量
製品Xの利益は1個あたり300円、製品Yは200円。機械時間はXが2時間、Yが1時間かかり、月の上限は400時間。原料はXもYも1個あたり1kgで、月の上限は300kgです。
2つの制約が交わる点は \(x = 100\)、\(y = 200\) で、このときの利益は \(300 \times 100 + 200 \times 200 = 70000\) 円となり、これが最適解です。
ここで確かめておきたいのは、利益の大きい製品Xだけを作る計画が最善ではないという点です。製品Xだけを作ると、機械時間400時間を使い切って200個が作れ、利益は60,000円になります。このとき原料の消費は200kgですから、100kgが手つかずで残ります。逆に製品Yだけを作ると、原料300kgを使い切って300個が作れ、利益はやはり60,000円です。このとき機械時間の消費は300時間で、100時間が空きます。どちらか一方に寄せた計画は、必ずもう一方の資源を余らせます。2つの資源を同時に使い切る組合せに踏み込んで初めて、利益は70,000円に届きます。
資源が1種類しかなければ、単位資源あたりの利益が大きい製品に寄せるという直感で正解にたどり着けます。この例題で機械時間だけを考えるなら、1時間あたりの利益は製品Xが150円、製品Yが200円ですから、製品Yに寄せるのが正しい。ところが原料という2本目の制約が入った瞬間に、その判断は成り立たなくなります。制約が2本以上あるとき、資源ごとの効率を別々に見て判断すると答えを外す。これが、生産計画を数式に載せて解く理由そのものです。
有限の最適解を持つLPでは、制約が作る領域の角にあたる点(端点)の中に、必ず最適解が1つは含まれます。制約を1本追加するたびに角の位置が動く、という感覚を2変数の図で一度つかんでおくと、定式化の勘所が理解しやすくなります。
例題で確かめます。非負条件と2本の制約が囲む領域は、次の4つの角を持つ多角形になります。
| 端点 | 製品Xの生産量 | 製品Yの生産量 | 利益 | 資源の使われ方 |
|---|---|---|---|---|
| 原点 | 0個 | 0個 | 0円 | どちらも未使用 |
| 機械時間の上限に沿った端 | 200個 | 0個 | 60,000円 | 機械時間を使い切り、原料が100kg余る |
| 原料の上限に沿った端 | 0個 | 300個 | 60,000円 | 原料を使い切り、機械時間が100時間余る |
| 2本の制約の交点 | 100個 | 200個 | 70,000円 | 機械時間も原料も使い切る |
最適解が角に現れる理由は、目的関数が一次式であることに由来します。利益が同じになる点を結んだ線は直線であり、この直線を利益が大きくなる向きへ平行移動していくと、領域からはみ出す直前で必ず角か辺に接します。辺に接する場合でも、その辺の両端にある2つの角は同じ利益になりますから、角だけを調べれば最適解を取りこぼしません。無数にある候補の中から角にあたる有限個の点だけを調べればよいというこの性質が、LPが大規模でも高速に解ける理由の1つになっています。ソルバーが端点をたどりながら改善していく仕組みについては第3章で触れたとおりです。
角が動く感覚も、この例題で確かめられます。「製品Yは販売可能量の関係で月150個までしか作れない」という制約 \(y \leq 150\) を1本足すとします。これまでの最適解であった \(x = 100\)、\(y = 200\) は、この時点で実行できない計画になります。新しい最適解は、機械時間の制約と販売上限が交わる点、すなわち \(x = 125\)、\(y = 150\) に移り、利益は67,500円になります。原料の消費は275kgですから25kg余り、ボトルネックは機械時間と販売上限の2つに入れ替わります。制約を1本足したことで、角の位置も、余る資源も、利益も同時に動いたわけです。
制約を足せば利益は下がるか、良くても横ばいです。下がった幅が、その条件を守ることの値段になります。今回であれば、製品Yの販売上限という条件は月2,500円の利益を消している、という言い方ができます。現場から後出しで出てくる条件の妥当性を議論するとき、この金額が判断材料になります。

例題の最適解では、機械時間400時間と原料300kgの両方を使い切っています。では、機械時間の上限が401時間だったら、利益はいくらになるでしょうか。2本の制約の交点を計算し直すと \(x = 101\)、\(y = 199\) となり、利益は70,100円です。1時間増えたことで、利益はちょうど100円増えました。同じように原料の上限を301kgにすると、交点は \(x = 99\)、\(y = 202\) に移り、利益はやはり70,100円になります。原料1kgあたりでも100円です。
この「制約の右辺を1単位ゆるめたときに、目的関数の値がいくら改善するか」を表す値を双対価格と呼びます。実務のソルバーは、最適解を求める過程でこの値も同時に計算しており、追加の計算をせずに取り出せます。今回の例題であれば、機械時間の双対価格は1時間あたり100円、原料の双対価格は1kgあたり100円です。
この数字は、そのまま意思決定の言葉に翻訳できます。機械時間を1時間増やすために残業や休日稼働を行うとして、その追加コストが100円を下回るなら実行する価値があり、上回るなら実行しないほうがよい、という判断になります。原料についても同様で、通常の仕入価格に上乗せしてでも1kgを追加調達したいとき、上乗せしてよい金額の上限が100円だと分かります。「増産したいので設備を増やしたい」という現場の要望に対して、増やす価値がある水準を金額で答えられるということです。
双対価格のもう1つの使い方が、ボトルネックの特定です。使い切っていない資源の双対価格は0になります。余っている資源をさらに増やしても、利益は1円も増えないからです。設備投資や増員の要望が複数の部署から同時に上がってきたとき、どれが本当に利益を押さえている制約なのかを、感覚ではなく金額の大小で並べられます。今回の例題は機械時間と原料の双対価格がどちらも100円で並んでおり、2つの資源が同時にボトルネックになっている状態です。この場合は、1単位増やすためのコストが安いほうから手当てするのが合理的な順序になります。
目的関数を利益ではなくコストで書いた問題でも、考え方は変わりません。コスト最小化の問題であれば、双対価格は「その制約を1単位ゆるめるとコストがいくら下がるか」を表します。納期の余裕を1日増やしたときに生産コストがいくら下がるか、といった問いに金額で答えられるということです。制約とは守るべき条件であると同時に、値段の付いた交渉材料でもある。双対価格は、その値段を計算する仕組みだと捉えると使いどころを見つけやすくなります。
ここで注意が必要なのは、双対価格が「1単位あたり」の値であって、いくら増やしても同じ率で利益が増え続けるわけではないという点です。機械時間を増やしていくと、いつかは原料のほうが先に尽きて、機械時間はボトルネックでなくなります。その時点で双対価格は0に落ちます。
例題で確かめます。機械時間の上限を \(b\) 時間としたとき、2本の制約の交点は \(x = b – 300\)、\(y = 600 – b\) になります。製品Yの生産量が0になるのは \(b = 600\) のときで、このときの生産量は製品Xが300個、利益は90,000円です。600時間を超えて機械時間を用意しても、原料300kgという上限が先に効くため、利益はそれ以上増えません。逆に機械時間が300時間を下回ると、今度は原料が余り始めて別の局面に入ります。つまり100円という双対価格が通用するのは、機械時間が300時間から600時間の範囲にある間だけです。
原料についても同じ確認ができます。原料の上限を \(b\) kgとすると交点は \(x = 400 – b\)、\(y = 2b – 400\) となり、製品Xの生産量が0になるのは \(b = 400\) のときで、利益は80,000円です。原料の双対価格100円が通用するのは、200kgから400kgの範囲となります。
この範囲を確認しないまま双対価格を掛け算すると、判断を誤ります。「1時間あたり100円だから、200時間増やせば20,000円の増益になる」という計算は600時間までしか成り立たず、実際には300時間の増設に見合う増益は20,000円で頭打ちになります。設備増設のように大きく動かす判断では、双対価格を目安として使いつつ、実際に増やした後の条件でモデルを解き直して確かめるのが確実です。双対価格が答えてくれるのは「いま、この計画の周辺で」という限定付きの問いだ、と押さえておく必要があります。
もう1つ、実務で出くわす注意点があります。3本以上の制約が1つの点で交わるような状態では、双対価格が一意に定まらないことがあります。この場合、ソルバーが返す値は複数ある候補の1つにすぎず、別のソルバーで解くと違う値が返ることもあります。金額の大きい意思決定にそのまま使う場面では、右辺を実際に動かして解き直し、利益の差を直接確かめる手順を挟むほうが安全です。
制約の右辺と並んでもう1つ、動きうるのが目的関数の係数です。1個あたりの利益は、売価の改定、原料費の変動、為替の動きによって変わります。しかも計画を立てる時点では、その値はあくまで見積もりです。ここで知りたくなるのが、「見積もりがどこまでずれたら、計画そのものを組み替える必要が出るのか」という問いです。この問いに答える作業が感度分析です。
例題で製品Xの利益を動かしてみます。300円という値を下げていくと、200円を下回ったところで最適解が \(x = 0\)、\(y = 300\) に移ります。逆に上げていくと、400円を超えたところで \(x = 200\)、\(y = 0\) に移ります。言い換えれば、製品Xの利益が200円から400円の範囲にある限り、最適な生産量は100個と200個のままで変わりません。同じことを製品Yについて行うと、利益が150円から300円の範囲にある間は生産量が変わらない、という結果になります。
この結果には実務上の意味があります。製品Xの利益を300円と見積もったものの、実際には280円かもしれないし320円かもしれない、という状況を考えます。この幅は200円から400円の範囲に十分収まっていますから、見積もりが多少ずれても、100個と200個という計画は動きません。動くのは利益の金額であって、作るべき数量ではないということです。逆に、範囲の端に近い係数を持つ製品があれば、そこは見積もりの精度を上げる価値が高い箇所です。どの数値を丁寧に調べ、どの数値は概算で済ませてよいかを、感度分析は教えてくれます。
感度分析は、いま作っていない製品の採否にも使えます。新製品Zの導入を検討していて、1個あたり機械時間を1.5時間、原料を1kg使うとします。この資源の使い方を双対価格で金額に換算すると、機械時間の分が \(1.5 \times 100 = 150\) 円、原料の分が \(1 \times 100 = 100\) 円で、合わせて250円です。これは、製品Zを1個作るために既存の製品XとYの生産を削ることで失う利益にあたります。したがって製品Zは、1個あたり250円を超える利益を生まなければ、導入する価値がありません。仮に製品Zの利益が230円であれば、モデルに加えて解き直しても生産量は0のままです。
受注の可否判断も同じ形です。その受注が消費する資源を双対価格で金額に換算し、受注価格がそれを上回るかどうかを見ます。表面上の粗利だけを見て受けた受注が、実は既存の高収益品の生産を押しのけていた、という事態を避けられます。
2製品2資源の例題は、そのまま実務規模に一般化できます。製品jの生産量を \(x_j\)、1個あたり利益を \(c_j\)、資源iを1個あたりどれだけ使うかを \(a_{i,j}\)、資源iの上限を \(b_i\) と置くと、目的関数は \(\sum_j c_j x_j\) の最大化、制約はすべての資源iについて \(\sum_j a_{i,j} x_j \leq b_i\)、そして \(x_j \geq 0\) となります。例題では製品が2つ、資源が2つだったものが、製品200品目、資源80種類に増えても、書き方は変わりません。変数が200個、制約が280本程度の問題は、LPであれば一瞬で解けます。規模が壁になることはほとんどない、というのは第3章で扱ったとおりです。
この基本形に、実務では2種類の制約を足します。1つは販売可能量の上限 \(x_j \leq u_j\) です。これを書き忘れると、モデルは「利益が出るなら作れるだけ作る」という解を返し、売れない在庫を積み上げる計画ができあがります。実際に起こりやすい書き忘れの典型例です。もう1つは契約上の最低生産量 \(x_j \geq l_j\) で、取引先との約束や、生産を止められない品目を表します。
実務でむしろ手間がかかるのは、数式そのものではなく係数 \(a_{i,j}\) を埋める作業です。この値は品目マスタと工程マスタから作りますが、標準時間が何年も更新されていない、設備の改造で所要時間が変わったのに反映されていない、といった状態はよくあります。モデルの答えは入力した係数の忠実な帰結ですから、係数がずれていれば答えも同じだけずれます。最初のプロジェクトで時間を取られるのは、たいていこの部分です。
係数 \(c_j\) の定義も、決めておくべき論点です。短期の資源配分を決める問題では、生産量に応じて増減しない固定費を配賦する前の利益、つまり売価から変動費だけを差し引いた限界利益を係数に置くのが基本になります。固定費を製品に配賦した後の利益を最大化すると、配賦の基準を変えただけで最適な生産計画が変わってしまい、答えの根拠を説明できなくなります。何を最大化するのかは業務判断であるという第2章の論点が、ここでも効いてきます。
ラインが複数ある場合は、添字を1つ増やします。製品jをラインkで作る量を \(x_{j,k}\) と置き、ラインごとに能力上限を書き、ラインごとに異なる単位あたり所要時間を係数に入れます。同じ製品でも新鋭機と旧型機で所要時間が違うといった実態が、これで表現できます。「その製品をそのラインで作る段取りをするかどうか」という判断まで入れると0か1を取る変数が必要になりますが、その書き方は第5章で扱ったとおりです。まず段取りを考えない形で解いて全体像をつかみ、必要になった分だけ整数の条件を足していく進め方が確実です。
決定変数の意味を「製品の生産量」から「原料の投入量」に置き換えると、同じ骨格が配合の決定に使えます。飼料、燃料、合金、飲料、塗料、セメントのように、複数の原料を混ぜて規格を満たす製品を作る業種では、原料価格が動くたびに配合を見直す必要があり、この型が繰り返し使われます。
決定変数は原料jの投入量 \(x_j\)、目的関数は原料費 \(\sum_j c_j x_j\) の最小化です。制約が生産計画と違うのは、資源の上限ではなく成分の要件が中心になる点です。ここで扱いに注意が要るのが比率の条件です。「たんぱく質が全体の20%以上」という要件は、原料jのたんぱく質含有率を \(a_j\) とすると、そのままでは \(\sum_j a_j x_j / \sum_j x_j \geq 0.2\) という割り算の形になり、一次式ではありません。しかし両辺に総量を掛けて移項すれば \(\sum_j a_j x_j \geq 0.2 \sum_j x_j\) となり、一次式に収まります。比率の条件は割り算を残さずに書ける、というのがブレンド問題の書き方の要点です。総量があらかじめ決まっている場合はさらに単純で、比率をそのまま数量に読み替えられます。
成分の要件には上限と下限の両方が現れます。栄養素は一定以上、不純物は一定以下、特定の原料は全体の何%を超えない、といった形です。原料の在庫や調達可能量の上限も制約として入ります。これらを並べれば、配合の問題はそのままLPとして解けます。
ここでも双対価格が効きます。成分要件に付く双対価格は、「その規格を1単位だけ緩めたら原料費がいくら下がるか」を表します。品質規格が過剰に厳しく設定されていて、そのために原料費が押し上げられている場合、その金額が数字で出てきます。規格の見直しを品質部門と議論するとき、あるいは新しい代替原料を採用すべきかを検討するときに、この金額が出発点になります。配合の最適化で得られる効果は、多くの場合、配合そのものの改善よりも「どの規格が高くついているか」が可視化されることのほうが大きいと言えます。
運用面では、原料価格の更新が命綱になります。配合は価格が動けば最適解も動く性質の問題で、日次あるいは週次で解き直す運用になりやすいものです。価格マスタの更新が止まると、モデルは古い価格に基づいた配合を出し続けます。誰がいつ価格を更新するのかを、導入時に決めておく必要があります。
ここまでは1か月といった単一の期間を扱ってきました。実務の生産計画は、複数の期間にまたがります。需要が期ごとに変動する場合、期を1つずつ独立に解くと、需要の山の月には能力が足りず、谷の月には設備が遊ぶという計画になります。前の期に多めに作って在庫として持ち越すという選択肢を、モデルに入れる必要があります。
期をつなぐのは、在庫バランスの制約1本です。期tの生産量を \(p_t\)、需要を \(d_t\)、期末在庫を \(I_t\) とすると、\(I_t = I_{t-1} + p_t – d_t\) と書けます。前期末の在庫に今期の生産を足し、今期の需要を引いたものが今期末の在庫になる、という当たり前の関係を式にしただけですが、この1本があることで、期と期が初めてつながります。あとは各期の生産能力の上限 \(p_t \leq\) 能力、倉庫容量の上限 \(I_t \leq\) 容量、欠品を許さないなら \(I_t \geq 0\) を並べ、目的関数は利益から在庫保管費 \(\sum_t h I_t\) を差し引いた形にします。
この形にすると、平準化の度合いをモデルが金額で決めてくれます。需要の山に合わせて残業や臨時要員で乗り切るコストと、前の期に作って持ち越す保管費のどちらが安いかを比較し、前倒し生産の量を決める。従来は生産管理の担当者が勘と経験で決めていた前倒しの量が、金額の比較として説明できる形になるということです。
実装上、いくつか押さえておくべき点があります。初期在庫 \(I_0\) には実績値を入れます。そして最終期の期末在庫を0に固定してはいけません。固定すると、計画期間の終わりに向けて生産を絞る不自然な計画が出てきます。翌期の立ち上がりに必要な水準を下限として置くのが実務的な扱いです。期の粒度は、月次12か月とするか週次12週とするかで変数の数が変わります。期数と製品数の掛け算で変数が増えるため、粒度は業務上必要な細かさと計算時間の両面から決めます。
運用の形としては、ローリングホライズンが一般的です。12か月分を通して解き、実行に移すのは直近の1か月分だけ。翌月になったら最新の実績と更新された需要予測を入れて、また12か月分を解き直します。先の期の需要予測は精度が落ちますが、それでも計画期間に入れておく意味はあります。先の需要を無視して直近だけを見ると、能力に余裕のあるうちに作り置いておくべきだという判断が出てこないためです。
欠品を絶対に許さない設計にすると、需要の山が能力を超えた瞬間に解が出なくなります。不足量を表す変数を置いてペナルティを掛ける書き方に切り替えれば、「どうしても足りない分はどこで発生するか」を計画の段階で把握できます。この切り替え方は第5章のソフト制約で扱ったとおりです。また、「その期にその製品を作るなら段取り費用がかかる」「作るなら最低ロット以上」といった条件を入れると、0か1を取る変数が必要になってMIPに変わります。この場合も、まずLPで解いて全体像と金額の規模をつかんでから、必要な条件だけを足していく順序が確実です。
次章では、人員配置とシフト作成を扱います。
『問題解決のためのオペレーションズ・リサーチ入門 Excelの活用と実務的例題』(高井英造、真鍋龍太郎 編著、日本評論社):生産計画、配合、輸送といった実務的な題材を、表計算ソフト上で実際に解きながら学ぶ構成の一冊です。この章で扱った双対価格と感度分析は、表計算ソフトのソルバー機能でも感度レポートとして出力できるため、手を動かして数字の意味を確かめたい場合の入口になります。
勤務表の作成は、時間帯ごとに必要な人数を満たしながら、誰をいつ働かせるかを決める意思決定です。小売、飲食、コールセンター、医療、警備、製造の交替勤務など、時間帯によって必要な要員数が変わる職場に共通して発生します。多くの場合は特定の担当者が表計算ソフトの上で数日かけて組み上げており、その担当者が異動すると品質が落ちる、という形で属人性が表面化します。条件の一つひとつは「日曜は3人必要」「夜勤の翌朝は入れない」といった単純なものですが、数が多く、しかも相互に影響し合うために、人の手では全体を見渡しきれなくなる種類の業務です。
この課題は、第3章の分類でいえばネットワーク型に含まれる割当問題を基本形とし、条件が増えるにつれてMIPの側に寄っていきます。人の集合と勤務枠の集合があり、その間の対応づけを決めるという構造がそのまま割当問題の形だからです。第1章で触れた大阪ガスの当直シフト編成も、この型に属する取り組みです。
この章では、まず人数だけを決める小さな例題で骨格を確認し、そこからスタッフ個人を割り当てる形へ広げ、実務で必ず加わる法令・スキル・連勤・希望・公平性の条件を順に制約として書いていきます。
最小の形から始めます。個人を区別せず、どの勤務パターンに何人入れるかだけを決める問題です。
例題:カフェのスタッフシフト
設定は次のとおりです。時間帯は朝・昼・夕・夜の4区分で、必要人数は朝2人、昼4人、夕3人、夜2人。スタッフは連続する2区分のシフト(朝昼、昼夕、夕夜)のいずれかで勤務します。
この条件のもとでは、たとえば \(x_1 = 2\)、\(x_2 = 2\)、\(x_3 = 2\) の計6人が最適です。このときの実際の配置は朝2人、昼4人、夕4人、夜2人となり、夕方だけ必要人数を1人上回りますが、これ以上減らすと夜間の人数を確保できません。なお、総人数6人という値は動かせませんが、その6人をどのシフトに割り振るかは1通りではありません。\(x_1 = 3\)、\(x_2 = 1\)、\(x_3 = 2\) も同じく計6人ですべての条件を満たします。同点の解が複数あるのは実務でも普通に起こることで、そのどれを選ぶかは、この定式化では決まらない部分です。
6人が最適であることは、制約を組み合わせるだけで確認できます。昼の制約 \(x_1 + x_2 \geq 4\) と夜の制約 \(x_3 \geq 2\) を足すと \(x_1 + x_2 + x_3 \geq 6\) が導かれます。つまり、どんな組み方をしても総人数は6人を下回れません。そして上の解は実際に6人でありすべての制約を満たしていますので、下界に到達している以上、これ以上良い解は存在しないと言い切れます。制約から下界を作り、それに一致する解を1つ示すという確認の仕方は、小さな例題で定式化の正しさを検証する際に使えます。
この定式化の要点は、決定変数を「人」ではなく「勤務パターンに入る人数」に取ったところにあります。スタッフを個人として区別しないため、変数は3つで済み、必要人数の条件は不等式4本で書き切れます。誰が入っても構わない、全員が同じ仕事をこなせる、という前提が成り立つ場面では、この粒度が最も軽く扱えます。1日の必要人数の見積もり、採用計画の検討、店舗ごとの必要人員の試算といった、個人名まで踏み込まない段階の意思決定であれば、この形で十分に答えが出ます。
ここで表れているもう1つの性質が、「夕方だけ1人多い」という余りです。勤務が時間帯をまたぐ以上、必要人数の山と谷にぴったり合わせた配置は作れず、上回る形でしか満たせないことがあります。この余剰は無駄ではなく、シフトの区切り方が需要の形に合っていないことを示す信号として読めます。夕方の余剰が常態化しているなら、勤務パターンの長さや開始時刻を見直す余地があるということです。
実務では、個人を区別しない前提はすぐに崩れます。出勤できる曜日が人によって違う、資格を持つ人が限られる、勤務希望がある、といった条件が入った時点で「誰が入るか」を決めなければならなくなるためです。ここで決定変数を、スタッフと勤務枠の組に対して1つずつ置く形に取り直します。
スタッフを \(s\)、日を \(d\)、時間帯を \(t\) として、\(x_{s,d,t}\) を「スタッフ \(s\) が日 \(d\) の時間帯 \(t\) に勤務するなら1、しないなら0」と定義します。第5章の0か1を取る変数をそのまま当てはめた形です。この1つの定義で、以降の条件のほとんどが不等式として書けるようになります。
骨格になるのは次の2種類です。1つは必要人数を満たす条件で、日 \(d\) の時間帯 \(t\) に必要な人数を \(r_{d,t}\) とすると \(\sum_s x_{s,d,t} \geq r_{d,t}\) と書きます。もう1つは1人の勤務が重複しない条件で、1日に入れる時間帯を1つまでとするなら \(\sum_t x_{s,d,t} \leq 1\) です。前者は勤務枠の側から見た条件、後者はスタッフの側から見た条件であり、この2方向から書くという発想は、第2章で挙げた需要側と供給側の洗い出しと同じものです。
この2種類だけを書いた状態が、割当問題の原型になります。スタッフという集合と勤務枠という集合があり、その間に線を引く。引ける線には制限があり、引いた線には価値やコストが伴う。この構造がネットワーク型の一員として扱われる理由です。整数の条件を明示しなくても答えが自然に整数になる場合があるという性質については、その根拠を第9章で扱います。
粒度の設計はここで決まります。時間帯を1日3区分とするか1時間刻みとするかで、変数の数も出力される勤務表の細かさも変わります。スタッフ20人、30日、3区分であれば変数は1,800個、必要人数の制約は30日×3区分で90本という規模感になり、この程度であれば計算時間は問題になりません。ただし添字が1つ増えるたびに変数は掛け算で増えますので、業務が本当に必要としている粒度を先に確認しておくことです。
シフト作成の定式化で最初に固めるべきなのは、破ってはいけない条件と、破る余地のある条件の切り分けです。ここを曖昧にしたまま重みの調整で処理しようとすると、ペナルティを払えば法令違反の勤務表が出てくるモデルができあがります。法令にもとづく条件は目的関数に載せず、必ず制約として書きます。
労働基準法では、労働時間は原則として1日8時間、1週間40時間が上限とされ、休日は少なくとも毎週1日、または4週間を通じて4日以上を与えることが求められています。休憩については、労働時間が6時間を超える場合は45分以上、8時間を超える場合は1時間以上と定められています。これらは勤務表の形を直接決める条件です。
法定労働時間を超えて働かせる場合には、いわゆる36協定を締結して届け出る必要があり、その時間外労働にも上限が定められています。原則は月45時間・年360時間で、臨時的な特別の事情がある場合の特別条項を結んだときでも、年720時間以内、2か月から6か月までのいずれの平均でも休日労働を含めて80時間以内、単月では休日労働を含めて100時間未満、月45時間を超えられるのは年6か月までという上限を超えることはできません。この上限規制は、大企業では2019年4月、中小企業では2020年4月から適用されています。なお、一部の業種には別の定めが置かれていますので、自社に適用される規定を確認したうえで制約に落とす必要があります。
これらをモデルに載せるときは、いずれも合計を取る形の不等式になります。スタッフ \(s\) の日 \(d\) の勤務時間を \(h_{s,d}\) とすれば、月の合計 \(\sum_d h_{s,d}\) に上限を置く、週単位で区切った合計に上限を置く、休日の日数に下限を置く、という書き方です。時間外労働の月ごとの上限と年間の上限のように、期間の長さが異なる条件が重なる場合は、それぞれ別の制約として並べます。上限が複数あるときに厳しいほうだけを書くと、月をまたいだ集計で違反が生じる余地が残ります。
もう1つ、法令の周辺には性質の異なる条件があります。終業から次の始業までに一定の休息時間を設ける勤務間インターバル制度は、労働時間等の設定の改善に関する特別措置法第2条第1項にもとづく事業主の努力義務として位置づけられており、2019年4月1日から施行されています。義務ではなく努力義務であるものを、モデルの上で絶対に守る制約として書くのか、破ったときにペナルティがかかる形で書くのかは、自社の方針として決める事柄です。ここを分析側の判断で決めてしまうと、後から「なぜこの条件は守られないのか」という問いに答えられなくなります。
社内規程にもとづく条件は、法令とは分けて記録しておく価値があります。「夜勤の翌日は必ず休みにする」「連続勤務は5日までとする」といったルールは、法令に由来するものと、過去の運用の積み重ねから生まれたものが混ざっていることが多いためです。前者は動かせませんが、後者はその条件を外すとどれだけ人員に余裕が生まれるかを試算して見せることで、ルールそのものの見直しにつながる場合があります。
誰でも同じ仕事をこなせるという前提が外れると、スキルと資格の条件が加わります。書き方は必要人数の制約と同じ形で、対象を絞った合計に下限を置くだけです。
有資格者の配置義務であれば、資格を持つスタッフの集合を \(Q\) として \(\sum_{s \in Q} x_{s,d,t} \geq 1\) と書きます。「各時間帯に責任者を1人以上置く」「レジ操作ができる人を2人以上入れる」「危険物取扱者を常時1人配置する」といった条件は、すべてこの形に収まります。逆に、まだ研修が終わっていないスタッフをその時間帯に入れないなら、該当する変数を0に固定します。出勤できない曜日や時間帯も同じ扱いで、変数を置かない、あるいは0に固定することで表現できます。
実務で効いてくるのは、この条件を書くためのデータが揃っているかどうかです。誰がどの業務をこなせるかという情報は、多くの職場で担当者の頭の中にあり、一覧の形では存在しません。スキルマトリクスを作る作業そのものが、シフト最適化の前段でいちばん時間のかかる工程になることは珍しくありません。逆に言えば、この一覧ができた時点で、どのスキルが不足していて誰に習得させるべきかが判断できるようになり、最適化を導入しなくても要員計画の議論の質は上がります。
スキルには段階があるという点も、書き方に影響します。「できる」と「できない」の2値ではなく、単独で担当できる、指導つきなら担当できる、という区分がある場合には、区分ごとに別の集合を用意します。単独で担当できる人を1人以上入れるという制約と、指導つきの人だけで時間帯を埋めないという制約を並べる形です。新人を熟練者と組ませる育成の要請も、「経験年数1年未満の人を入れるなら、同じ時間帯に3年以上の人を1人以上入れる」という条件として書けます。これは第5章の論理条件の当てはめにあたります。
連続勤務の上限は、期間を区切った合計で表します。スタッフ \(s\) が日 \(d\) に勤務するかどうかを \(y_{s,d}\) とすると、6日連続の勤務を禁じたい場合は、任意の連続7日の窓について \(\sum_{d’=d}^{d+6} y_{s,d’} \leq 6\) と書きます。この不等式を、計画期間内のすべての開始日について並べます。窓をずらしながら同じ形の制約を並べるという書き方は、連勤に限らず「一定期間内に何回まで」という条件全般に使えます。月あたりの夜勤回数の上限も、期間を1か月に取った同じ形です。
勤務の間隔に関する条件は、組合せを禁じる形になります。時間帯を朝・昼・夕・夜に番号1から4を振ったとき、夜勤の翌朝に入れないという条件は \(x_{s,d,4} + x_{s,d+1,1} \leq 1\) です。両方が1になると左辺が2になって制約を破るため、この2つが同時に選ばれることはありません。禁じたい組合せが複数あるなら、その分だけ不等式を並べます。終業から次の始業まで一定時間を空けるという条件も、空けられない組合せを列挙して同じ形で書きます。
ここで注意が要るのは、計画期間の端の扱いです。月単位で勤務表を作ると、前月末の勤務が今月の初日に影響します。前月の最終日に夜勤だった人を、今月1日の朝に入れてはいけません。同様に、前月末に4日連続で勤務していた人は、今月の初日からの連勤日数がゼロから始まるわけではありません。これらは制約の外側にあるデータとして与える必要があり、書き落とすと、月替わりのたびに現場が手で直す事態になります。月をまたぐ条件をどう引き継ぐかは、シフト最適化を運用に乗せる際に必ず出てくる論点です。
もう1点、これらの制約は互いに干渉します。連勤上限を厳しくし、勤務間隔を広く取り、資格者の配置を義務づけ、そのうえで必要人数を満たそうとすると、条件を同時に満たす勤務表が存在しなくなることがあります。制約を1本ずつ足しながら、どこで解が出なくなるかを確かめる進め方を取ると、原因の切り分けができます。
勤務希望は、破ってはいけない条件ではありません。全員の希望を同時に満たす勤務表は、必要人数の条件と両立しないことがほとんどです。したがって希望は、第5章のソフト制約として書きます。労働基準にもとづく条件は絶対に守る制約、個人の希望はソフト制約という切り分けが、この章の設計の柱になります。
適用にあたって決めるべきなのは、どの希望をどの強さで扱うかです。休みの希望と時間帯の希望では重みが違いますし、冠婚葬祭や通院のように事前に確定している予定は、そもそも希望ではなく出勤不可として扱うべきものです。実務では、希望を「必ず通す」「できるだけ通す」「参考程度」の3段階に分け、1段階目は変数を固定し、2段階目と3段階目は重みを変えたソフト制約として書く、という整理がよく使われます。この段階分けは業務側が決めることであり、決めた内容は勤務表を受け取る側にも公開しておくほうが納得を得やすくなります。
重みの相対関係を決めたら、その結果として希望がどれくらい通るのかを事前に確認します。希望の通過率は、勤務表を作る前に「何%を目指すか」を決めておく種類の指標です。通過率が低すぎれば現場の不満につながり、高すぎれば必要人数を満たすために人を増やす必要が出てきます。何通りかの重みで解いてみて、通過率と必要人員数の対応関係を表にすると、どこで折り合いをつけるかの議論ができます。この表は、要員数そのものを見直す材料としても使えます。
期間をまたいだ調整も論点になります。ある月に希望がほとんど通らなかった人がいたとき、翌月にその分を優先する仕組みがなければ、不公平は累積していきます。過去の希望通過率を重みに反映させ、通っていない人の希望を重く扱うという設計にすれば、単月ではなく通期での納得感を作れます。1か月ごとに独立して最適化すると、この累積の視点が抜け落ちます。
勤務の偏りをなくしてほしい、という要望はシフト作成で最も頻繁に出てくるものの1つですが、そのままでは数式になりません。何をもって公平とみなすかを先に決める必要があります。
実務で使われる定義はいくつかあります。総勤務回数を揃える、夜勤や休日勤務のような負担の重い枠の回数を揃える、希望の通過率を揃える、勤務時間の合計を揃える、といったものです。どれを選ぶかで出てくる勤務表は変わります。総勤務回数だけを揃えると、夜勤ばかり入る人と日勤ばかりの人ができてしまう可能性が残りますし、逆に夜勤回数だけを揃えると総勤務時間に差が出ます。関係者が「公平でない」と感じているのが具体的に何の偏りなのかを聞き取るところから始めるのが確実です。
定義が決まれば、書き方は難しくありません。各スタッフの該当回数の最大値と最小値の差を小さくするという形が最も直接的で、これは第5章の最大値の線形化をそのまま当てはめれば書けます。もう1つの書き方が、目標値を決めてそこからのずれを小さくする形です。夜勤は1人あたり月4回を目安とする、と決めたうえで、4回からの上下のずれに重みを掛けて目的関数に足します。前者は最も割を食っている人を救う方向に、後者は全体を目標値の周りに寄せる方向に働きます。
公平性を評価する期間の取り方も、設計の一部です。短い期間で厳密に揃えようとすると、必要人数の条件と衝突して解が出にくくなります。四半期のような長い期間で見るなら、過去の実績を初期値として持ち込む仕組みが要ります。累積の記録を持つ設計にしておくかどうかで、運用開始後の説明のしやすさが変わります。
加えて、公平性を目的関数に載せるとコストや人数と競合し、完全に揃えようとすれば人を増やすしかないという関係になる場面もあります。競合する指標の扱い方は第2章で扱ったとおりで、公平性を制約に回して「回数の差は2回以内」と書き、目的関数は別の指標に絞る進め方も選べます。どちらを採るにせよ、公平性の定義とどこまで求めるかは、勤務表を受け取る人たちに説明できる形にしておく必要があります。
シフト作成と並んで、割当問題がそのまま当てはまるのが、要員を業務に対応づける配置の問題です。担当者と案件、作業者と工程、審査担当と申請、面談者と応募者というように、2つの集合の要素を1対1で結びつける場面が該当します。
構造は、点を2つのグループに分け、グループをまたぐ線だけを引ける形になります。これが二部グラフと呼ばれるもので、左側に要員、右側に業務を並べ、その要員がその業務を担当できる場合にだけ線が引けるという図で表せます。この線のうち、どの要員もどの業務も1本ずつしか使わないように選ぶことをマッチングと呼びます。定式化は素直で、要員 \(p\) を業務 \(q\) に割り当てるなら1を取る変数 \(z_{p,q}\) を置き、各要員について \(\sum_q z_{p,q} \leq 1\)、各業務について \(\sum_p z_{p,q} = 1\) と書きます。
目的関数には、要員と業務の相性を表す値を置きます。習熟度から見積もった処理時間、過去の実績にもとづく品質の指標、移動距離、担当希望の強さなど、業務によってさまざまです。処理時間であれば合計を最小化し、適性の点数であれば合計を最大化します。ここで悩ましいのは、合計を最良にすると特定の人に負荷が寄る場合があることです。全体の合計時間は短いが1人だけ極端に忙しい、という解が出てきたら、最も重い負荷を小さくする書き方に切り替えます。合計を良くするのと、いちばん悪いところを良くするのは別の定式化であるという点は、第5章で扱ったとおりです。
この型が実務で扱いやすいのは、規模が大きくなっても解けることです。要員と業務がそれぞれ数千の規模になっても実用的な時間で答えが出るため、毎朝実行する必要がある作業割当でも計算時間が問題になることはまずありません。シフト作成に本格的に取り組む前段として、まず1日単位の要員配置から始める進め方は、成果を早く出す意味でも有効です。
シフト最適化は、解が出れば終わりという種類の仕組みではありません。出力された勤務表を現場が受け入れ、翌月も使い続けてはじめて成果になります。ここで効いてくるのが、運用側の設計です。
まず、手修正の余地を残すことです。当日の欠勤、急な受注、家庭の事情による変更は必ず発生します。出力を確定版として扱うのではなく、担当者が編集できる下書きとして渡す形にしておくと、現場は安心して使えます。修正したときに制約違反が起きていないかを判定する機能を添えれば、担当者は自分の判断で直しながら、法令や社内規程の違反だけは避けられます。
固定シフトの扱いも決めておきます。管理職の勤務、契約で曜日が決まっているスタッフ、研修や会議の予定は、最適化の対象ではなく所与の条件です。これらを変数として扱わず固定してしまえば、問題は小さくなり、計算も軽くなります。何を決めるのかを絞り込むという第2章の考え方は、ここでも同じように効きます。
説明できることも重要です。「なぜ自分がこの日に夜勤なのか」という問いに答えられなければ、出力された勤務表は信用されません。希望の通過率、夜勤の回数、連勤の状況を人ごとに一覧で示せるようにしておくと、この問いに数字で答えられます。誰か1人だけが割を食っていないことを示せる形にしておくことが、最適化に対する納得の土台になります。
導入の順序としては、いきなり全条件を組み込んだ勤務表の自動生成を目指さないほうが確実です。まず必要人数の充足と法令にもとづく条件だけで解き、現行の勤務表と比べて違いを確認する。次にスキルと連勤の条件を足す。最後に希望と公平性を載せる。この順で進めれば、どの条件がどれだけ勤務表の形を変えるのかが段階的に見えます。現場から「これは実行できない」という指摘が出たときも、直前に足した条件に原因を絞り込めます。

次章では、拠点・設備の配置を扱います。
『Pythonではじめる数理最適化(第2版) ケーススタディでモデリングのスキルを身につけよう』(岩永二郎、石原響太、西村直樹、田中一樹、オーム社):この章で書き下したスタッフと勤務枠の割当を、実際に手を動かして解く段階に進むための一冊です。ビジネス寄りのケーススタディを題材に、条件を1つずつ足しながらモデルを育てていく進め方が示されているため、本章の制約をそのまま自社のデータに当てはめてみたい場合の手引きになります。
拠点や設備をどこに置くかという意思決定は、一度決めると数年から十数年にわたって費用とサービス水準の両方を縛ります。物流センター、営業所、保守拠点、店舗、充電設備、監視カメラのいずれについても、候補地はあらかじめ限られた数に絞られており、実際の作業はその候補のうちどこを選ぶかを決めるところに集約されます。判断材料は、開設にともなって発生する固定費と、開設した結果として得られるカバー範囲やサービス水準の2つです。この2つはたがいに逆を向いており、拠点を増やせばサービス水準は上がりますが固定費も上がります。地図を広げて候補地に印を付け、担当者の土地勘で絞り込む進め方は今も広く行われていますが、候補が10か所を超えたあたりから、組み合わせの数が人手で比較できる範囲を出ます。
この課題は、第3章の分類でいえばMIPにあたり、候補地ごとに開設するかどうかを表す変数を並べる施設配置問題として定式化できます。決めるのは数量ではなく組み合わせであるため、変数には第5章の0か1を取る変数を使います。ここで型が分かれるのは、サービス水準を目的関数の側に置くか制約の側に置くかという一点です。まずは制約の側に置く型から見ていきます。
例題:5つの候補地からどの店舗を開くか
候補地は5か所で、開設固定費はいずれも年間1,000万円。すべてのエリアを、距離10km以内にある店舗でカバーしたいという条件です。3点セットで書き下すと次のようになります。
これは集合被覆問題と呼ばれる、0か1を取る変数による整数計画の代表型です。「最低1つでカバーする」という制約の形が、消防署の配置、保守拠点の配置、監視カメラの設置計画など幅広い場面に現れます。開設数をあらかじめ固定して総距離を最小化するp-メディアン問題も、出店戦略の検討でよく使われる型です。
制約の書き方をもう少し丁寧に見ます。エリアkを候補地iが10km以内でカバーできるなら1、できないなら0という定数を \(a_{k,i}\) と置くと、制約は \(\sum_i a_{k,i} x_i \geq 1\) の形になります。この不等式は、エリアの数だけ並びます。左辺に現れるのは、そのエリアを担当できる候補地だけの合計であり、遠すぎてカバーできない候補地は \(a_{k,i}\) が0なので左辺に効きません。つまり1本の制約が「このエリアの面倒を見られる候補地のうち、少なくとも1つは開いていること」という業務上の要請をそのまま表しています。
目的関数の側は単純です。固定費がどの候補地も同額であれば、費用の最小化は開設数の最小化と同じ意味になります。候補地ごとに賃料や造作費が異なるなら、係数を候補地別の金額に置き換えるだけで、費用の安い組み合わせを探す問題になります。この差し替えでモデルの構造は変わりません。用地費が高いが多くのエリアを見られる候補地と、安いが守備範囲の狭い候補地を、同じ土俵で比較できるようになります。
この例題では距離データを具体的に与えていないため、どの候補地の組み合わせが選ばれるかはここでは決まりません。確認しておきたいのは答えの数字ではなく、「すべてのエリアを取りこぼさない」という一見すると数式になりにくい要請が、エリアごとの不等式1本ずつという形に落ちるという点です。距離行列さえ用意できれば、あとはソルバーが最小の組み合わせを返します。
規模の感覚もつかんでおきます。この型では、変数の数は候補地の数と一致し、制約の本数はエリアの数と一致します。候補地が50か所、エリアを800区画に切ったとしても、変数50個と制約800本にしかなりません。0か1を取る変数を含む問題としては小さい部類で、実務で扱う多くの配置検討は現実的な時間で解けます。計算が重くなるのはむしろ、後述する割当変数を持つ型に移ったときです。
施設配置の型は1つではありません。同じ「拠点をどこに置くか」という問いでも、何を最小化したいのか、何が先に決まっているのかによって、書くべき式が変わります。代表的な4つを並べます。
| 型 | 何を最小化・最大化するか | 主な制約 | 使う場面 |
|---|---|---|---|
| 集合被覆問題 | 開設費用の合計を最小化 | 各エリアを1か所以上がカバー | 到達時間や距離に守るべき基準がある |
| 最大被覆問題 | カバーできる需要量を最大化 | 開設数または予算に上限 | 投資枠が先に決まっている |
| p-メディアン問題 | 需要で重み付けした総距離を最小化 | 開設数をpに固定、各エリアを1拠点に割当 | 平均的な近さを重視する |
| 容量制約付き施設配置問題 | 固定費と割当費用の合計を最小化 | 拠点ごとの処理能力の上限 | 拠点の能力が有限である |
集合被覆問題は、サービス水準を制約の側に置く型です。「10km以内」「30分以内」という基準線を先に引き、それを全域で満たす最小費用の組み合わせを探します。基準を満たすかどうかだけを見るので、9kmでも1kmでも制約の上では同じ扱いになります。基準線が契約や規程で決まっている場合には素直に使えますが、基準の置き方そのものが結果を大きく動かすため、その数値の根拠を業務側と共有しておく必要があります。
最大被覆問題は、目的と制約を入れ替えた型です。開設できる数や予算が先に決まっていて、その枠内でできるだけ多くの需要を拾いたい場合に使います。エリアkがカバーされたかどうかを表す0か1を取る変数 \(z_k\) を追加し、\(z_k \leq \sum_i a_{k,i} x_i\) という制約を置いたうえで、需要量 \(w_k\) を重みにした \(\sum_k w_k z_k\) を最大化します。開設数の上限は \(\sum_i x_i \leq p\) と書きます。全域を必ずカバーするという条件を外す代わりに、どこを取りこぼすかを費用対効果で選ぶ形になります。全域カバーが予算的に成り立たないことが分かった段階で、この型に切り替える進め方がよく取られます。
p-メディアン問題は、距離そのものを目的関数に載せる型です。エリアkを拠点iに割り当てるかどうかの変数 \(y_{k,i}\) を置き、各エリアがちょうど1つの拠点に割り当てられるという制約 \(\sum_i y_{k,i} = 1\)、開いていない拠点には割り当てられないという制約 \(y_{k,i} \leq x_i\)、開設数を固定する制約 \(\sum_i x_i = p\) を課したうえで、\(\sum_k \sum_i w_k d_{k,i} y_{k,i}\) を最小化します。被覆型が「基準内かどうか」という2値でしか距離を見ないのに対し、こちらは距離の大小をそのまま評価します。平均的な近さを良くしたいときはp-メディアン、いちばん遠いエリアを見捨てたくないときは被覆型、という向き不向きがあります。なお、変数の数が候補地とエリアの掛け算になるため、モデルの規模は被覆型より一段大きくなります。
容量制約付き施設配置問題は、拠点に処理能力の上限があるときの型です。1拠点で担当できる出荷量や来店客数に限りがある場合、被覆やp-メディアンのように「最も近い拠点に任せる」という前提が崩れます。割当を0か1ではなく量で持ち、拠点ごとに \(\sum_k q_{k,i} \leq C_i x_i\) のような能力制約を置きます。開設しない拠点には量を割り当てないという条件の書き方は、第5章のbig-M法で扱っています。ここから先、拠点が決まったあとに実際の物量をどう配分するかは第9章の主題になります。
どの型を選ぶかは、次の3つの問いでおおむね決まります。1つ目は、サービス水準に明確な基準線があるかどうかです。契約や規程で「何分以内」が決まっているなら被覆型が自然です。2つ目は、開設数や予算が先に決まっているかどうかです。決まっているなら最大被覆型やp-メディアンのように、開設数を制約側に置く型になります。3つ目は、拠点の能力が有限かどうかです。1拠点に集中させると回らないのであれば、容量制約付きの型を選ばざるを得ません。実務では最初から複雑な型を組まず、被覆型で解いて必要拠点数の当たりを付けてから、容量や割当の条件を足していく順序が扱いやすいといえます。
消防署や救急拠点の配置は、被覆型が最も素直に当てはまる例です。到着までの目標時間が定められている場合、その時間内に到達できる範囲を候補地ごとに算出すれば、それがそのままカバー集合になります。時間を距離に読み替えるか、道路網から到達時間を直接計算するかで結果は変わるため、どちらを使うかは先に決めておきます。
設備の保守サービスやフィールドサービスの拠点も同じ形です。契約上「連絡から何時間以内に駆けつける」という水準を約束しているなら、その水準を満たす配置のうち最も安いものを探す問題になります。既存顧客の所在地がデータとして手元にあるため、エリアの重みを顧客数や契約金額で置きやすいのもこの領域の特徴です。契約水準を満たせない顧客が出てしまう場合には、最大被覆型に切り替えて、どの顧客層を優先するかを金額で判断する形になります。
監視カメラやセンサーの設置計画では、「見えているかどうか」がもともと2値の情報であるため、被覆の考え方がそのまま使えます。設置候補の位置と向きの組み合わせを1つの候補として扱い、それぞれがどの区画を視野に収めるかを列挙すれば、カバー集合ができます。死角を作らないという要請は、全区画をカバーする制約そのものです。重要度の高い区画については、2か所以上から見えていることを求める書き方も使われます。
充電設備の設置計画では、全域をカバーするより、限られた台数で拾える需要を最大化する形が現実的な場合が多くなります。需要の重みは、走行実績や滞在時間、周辺施設の集客力などから作ります。設備1基あたりの同時利用台数に上限がある点を考えると、容量制約付きの型に近づいていきます。
物流センターや工場の立地検討は、固定費と輸送費のどちらも大きく、拠点の処理能力にも上限があるため、容量制約付き施設配置問題として組むのが基本になります。この場合の目的関数は、開設固定費と配送費用の合計です。拠点を増やせば固定費は増えますが配送距離は縮み、減らせばその逆になるという関係を、1つの目的関数の上で比較できるところに定式化の利点があります。なお、これらの適用例はいずれも型の当てはめ方を示したものであり、特定の企業の実施例を指すものではありません。
新規出店だけでなく、すでにある拠点をどう畳むかという判断にも同じ型が使えます。書き方の違いは変数ではなく費用の置き方にあります。新規の候補地では \(x_i = 1\) が開設を意味し、開設固定費が発生します。既存拠点では \(x_i = 1\) が存続を意味し、\(x_i = 0\) にすると維持費が消える代わりに閉鎖にともなう一時費用が発生します。目的関数は「これから発生する費用」に統一し、すでに支出済みの投資額は判断材料に含めない扱いにするのが原則です。この点は会計上の処理と混同されやすいため、モデルに入れる費用の範囲を業務側と文書で合意してから計算に入ることをおすすめします。
統廃合の検討で有効なのは、現状の拠点構成を制約として固定した場合の費用と、最適化した場合の費用を並べて出すことです。現状構成は既存拠点の \(x_i\) をすべて1に固定して解けば計算でき、その差額が統廃合によって見込める効果額になります。効果額が用地の処分損や移転費用を上回るかどうかが、案件を進めるかどうかの分かれ目になります。差額が小さければ、統廃合は見送るという結論も同じモデルから出てきます。
段階的な移行を検討する場合は、期をまたいだ変数に拡張します。年度ごとに \(x_{i,t}\) を置き、一度閉じた拠点は再び開かないという条件や、同時に閉じるのは年に2か所までという条件を加えます。個数の条件は変数の合計に対する不等式で書け、順序の条件も1次式の範囲で表せます。ただし期の数だけ変数が増えるため、まず単年で最終形を求め、そこへ至る道筋を別途検討するという二段構えのほうが、意思決定の材料としては扱いやすい場合が多くあります。
移転を扱うときは、閉鎖と開設を同じモデルの中に置きます。既存拠点の \(x_i\) と新規候補地の \(x_i\) を1つの変数の並びとして持ち、被覆や能力の制約は両者を区別せずに書きます。区別が必要になるのは費用の項だけです。この形にしておくと、「既存の2拠点を閉じて新規の1拠点に集約する」という案と、「既存を残して1拠点だけ増やす」という案が、同じ目的関数の上で自動的に比較されます。移転案を人手で作って持ち寄る進め方では、候補の作り方そのものに担当者の想定が入りますが、変数として並べておけば、想定の外にある組み合わせも検討対象に入ります。
拠点の統廃合には、数式に載らない要素も多く含まれます。従業員の勤務地変更、地域との関係、賃貸借契約の残存期間などがそれにあたります。契約期間のように金額と期日が明確なものは費用として組み込めますが、そうでないものは無理に数値化せず、最適化で候補を数案に絞ってから人が比較する対象として残すほうが健全です。モデルの役割は結論を出すことではなく、比較すべき候補を意味のある数まで減らすことにあります。
この型の実務作業は、定式化そのものよりも、カバー集合 \(a_{k,i}\) を作るところに時間がかかります。ここで置いた前提が、そのまま答えの前提になります。
候補地の並べ方には2つのやり方があります。1つは、実際に取得や賃借の見込みがある物件を候補として列挙するやり方で、答えがそのまま実行案になる利点があります。もう1つは、エリアの代表点や一定間隔の格子点をすべて候補として置くやり方で、この場合の答えは実行案ではなく、「このあたりに拠点があるとよい」という探索範囲の提示になります。物件情報が集まる前の初期検討では後者から入り、範囲を絞ってから物件を当たり、あらためて前者で解き直すという順序が現実的です。どちらのやり方を取っているかを結果と一緒に伝えないと、地図上の点を実在の候補地だと受け取られることがあります。
次に距離の測り方です。直線距離、道路網に沿った距離、実際の所要時間の3つがあり、結果は一致しません。10kmという基準は、多くの場合「そのくらいの時間で到達できる」という意味の代理指標として使われています。市街地と郊外では同じ10kmでも所要時間が数倍異なるため、時間で管理している業務であれば、距離ではなく到達時間でカバー集合を作るほうが実態に合います。時間帯によって所要時間が変わる場合は、最も厳しい時間帯を基準にするか、平均で見るかを先に決めます。
次にエリアの粒度です。町丁目、一定サイズのメッシュ、郵便番号区域などが使われます。細かく切るほど制約の本数は増えますが、被覆型であれば制約が増えても計算はさほど重くなりません。むしろ問題になるのは、粗く切った場合にエリアの代表点が実態からずれることです。面積の広い区画を1点で代表させると、その点は基準内でも区画の端は基準外という状況が起こります。人口や需要が偏在している地域ほど、代表点の取り方に注意が要ります。
エリアの重みも決めておきます。人口、世帯数、出荷実績、契約件数のいずれを使うかで、最大被覆型やp-メディアンの答えは変わります。過去の実績を重みにすると、現状で拠点が近い地域の需要が大きく見え、結果として現状を追認する配置が出やすくなる点には注意が必要です。将来の計画値を使うのか実績値を使うのかは、業務側の判断事項として明示的に扱います。
基準値そのものの感度を確認しておくことも有効です。10kmを12kmに緩めれば必要な拠点数は減り、8kmに締めれば増えます。基準値をいくつか変えて解き、基準と必要拠点数と費用の関係を1枚の表にまとめると、「どこまでのサービス水準を、いくらで買うのか」という形の議論ができます。経営会議で使えるのは、1つの最適解そのものよりも、この対応関係であることが少なくありません。定式化の価値は、単一の答えを出すことよりも、条件を振ったときの反応を短時間で示せるところにあります。
被覆型には、同じ値を取る最適解が複数存在しやすいという性質があります。固定費が候補地によらず同額であれば、同じ拠点数で全域をカバーできる組み合わせはすべて同点であり、ソルバーはそのうちの1つを返します。返ってきた1案が唯一の答えだと受け取ると、現場から出た別案を検討の外に置いてしまいます。対処としては、総距離のように二次的な指標を小さな重みで目的関数に足して順位を付ける方法や、最適値と同じ費用になる解を複数列挙して並べる方法があります。同点の案を並べて見せたほうが、用地の取りやすさや人員の確保しやすさといった数式外の条件で選びやすくなります。
冗長性を要求する書き方も覚えておくと使えます。制約の右辺を1から2に変えるだけで、「2か所以上からカバーされていること」を求められます。1か所が停止しても業務が続くことを重視する場合や、繁忙時に応援を出せる体制を求める場合に使います。全域に対して2以上を求めると必要拠点数は大きく増えるため、重要度の高いエリアだけ右辺を2にするという書き分けが現実的です。エリアごとに右辺の値を変えられるところが、この型の使い勝手の良いところです。
結果を現場に示すときは、どのエリアがどの拠点にカバーされているかを地図の上で見せることが有効です。数式の上では制約が満たされていても、地図に落とすと「この区画をここから担当するのは無理がある」という指摘が出てきます。その指摘は、カバー集合の作り方が実態と合っていないという情報であり、モデルを直すための材料になります。定式化は一度で完成させるものではなく、こうした指摘を制約やデータに反映させながら精度を上げていく作業です。
最後に、この型が扱っているのは候補地の選択であって、候補地そのものの発掘ではないという点を確認しておきます。候補地リストに入っていない場所は、どれだけ良い立地であっても答えに現れません。用地の取得可能性、賃料水準、周辺の道路事情といった条件は、候補地リストを作る段階で確認しておく必要があります。モデルの出力の質は、入力である候補地リストの質を超えません。

次章では、輸送と配分をネットワーク型問題で解く方法を扱います。
『あたらしい数理最適化 Python言語とGurobiで解く』(久保幹雄、ジョア・ペドロ・ペドロソ、村松正和、アブドル・レイス、近代科学社):この章で並べた施設配置の型を、実際に解けるモデルとして書き下すところまで確認できる一冊です。被覆型と割当型の定式化が具体的なコードとともに示されているため、候補地とエリアのデータをどう持たせるか、制約をどの単位で生成するかといった実装上の判断を、手を動かしながらつかみたい方に向いています。
倉庫から店舗への商品の配分は、どこにいくつ在庫があり、どこでいくつ必要とされているかが分かっていても、それだけでは決まりません。供給元が複数あり、届け先も複数あり、その組み合わせごとに輸送費が違うためです。「各店舗は最も近い倉庫から取る」という決め方は一見合理的ですが、同じ倉庫が複数の店舗から同時に当てにされると成り立ちません。誰がどこから受け取るかを店舗ごとに個別に決めるのではなく、全体の組み合わせとして同時に決める必要があるのは、この重なりがあるからです。日々の出荷指示、災害時の物資配分、電力や水の融通、工場から販売拠点への製品の振り分けは、いずれも同じ形をした意思決定です。
この課題は、第3章の分類でいえばネットワーク型にあたり、輸送問題として定式化できます。供給する地点と受け取る地点を点、その間の輸送を線と見なすと、問題全体が点と線のつながりとして描けます。この形に収まっている問題は、LPのなかでも特別に恵まれた性質を持ちます。輸送量を整数に限る条件をどこにも書かないのに、答えが整数で返ってくるという性質です。その根拠にあたるのが、この章で扱う完全単模性です。
倉庫Aの在庫は100個、倉庫Bの在庫は80個。店舗1、2、3の需要はそれぞれ60個、70個、50個です。1個あたりの輸送コストは、倉庫Aから順に10円、20円、30円、倉庫Bから順に25円、15円、10円とします。
| 1個あたり輸送コスト | 店舗1 | 店舗2 | 店舗3 | 在庫 |
|---|---|---|---|---|
| 倉庫A | 10円 | 20円 | 30円 | 100個 |
| 倉庫B | 25円 | 15円 | 10円 | 80個 |
| 需要 | 60個 | 70個 | 50個 |
3点セットで書き下すと次のようになります。
制約の書き分けに、業務の意味が入っています。供給側は「在庫以下」という上限であり、在庫を余らせても構いません。需要側は「需要と等しい」という等式であり、多く送っても少なく送っても駄目です。この例題では在庫の合計が180個、需要の合計も180個で一致しているため、結果として倉庫の在庫は使い切られます。合計が一致しない場合の扱いは後述します。
まず、素直に見えるやり方を試します。各店舗が自分にとって最も安い倉庫から取ると、店舗1は倉庫Aから60個、店舗2は倉庫Bから70個、店舗3は倉庫Bから50個となります。ところが倉庫Bに求められる量は合計120個で、在庫の80個を40個超えています。個別最適を並べただけでは成り立たないという状態が、ここで表面化します。倉庫Bは40個ぶんを誰かに譲ってもらわなければなりません。
そこで、譲ったときにいくら余計にかかるかを店舗ごとに比べます。店舗2が倉庫Bをあきらめて倉庫Aから受け取ると、1個あたりのコストは15円から20円へ5円上がります。店舗3が同じことをすると、10円から30円へ20円上がります。40個を譲るなら、単価差の小さい店舗2に譲ってもらうほうが安く済みます。実際、店舗2に譲らせた場合の総コストは2,350円、店舗3に譲らせた場合は2,950円となり、600円の差が出ます。総額そのものではなく、動かしたときの差額で比べるという見方が、この型の問題では効きます。
最適解は、倉庫Aから店舗1へ60個、店舗2へ40個、倉庫Bから店舗2へ30個、店舗3へ50個という配分で、総コストは \(10 \times 60 + 20 \times 40 + 15 \times 30 + 10 \times 50 = 2350\) 円です。倉庫Aから店舗3への輸送と、倉庫Bから店舗1への輸送は、どちらも使われません。単価が最も高い経路が使われないのは当然に見えますが、注目すべきは、単価が2番目に安い倉庫Bから店舗2への経路が、在庫の制限によって30個までしか使えていない点です。安い経路から順に埋めるという手順では、この配分にはたどり着けません。
例題は倉庫2か所と店舗3店ですので変数は6個ですが、規模が大きくなっても構造は変わりません。倉庫20か所から店舗500店への配分であれば変数は10,000個で、この規模のLPは計算時間を心配する範囲に入りません。増え方に注意が要るのは、添字を足したときです。品目を100種類に分けて品目ごとに配分を決めるなら、変数は100万個になります。それでも解けない規模ではありませんが、品目ごとに独立して解けるのであれば、100個の小さな問題に分けたほうが速く、結果も読みやすくなります。分けられるかどうかは、品目どうしをつなぐ条件があるかどうかで決まります。
いま解いた例題では、輸送量を整数に限る条件をどこにも置いていません。それでも答えは60個、40個、30個、50個という整数で返ってきます。これは数値の巡り合わせではなく、輸送問題の構造から保証されている性質です。実務上の意味を先に述べると、この型に収まっている限り、輸送量を整数に限る条件をわざわざ書き加える必要はなく、軽いLPのまま解いてよい、ということです。整数条件を書けばMIPになり、探索の工程がまるごと必要になりますが、同じ答えがLPで得られるならその工程は要りません。
この保証を支えているのが、制約の係数行列が持つ完全単模性という性質です。需要と供給が整数であれば、整数条件を課さなくても、整数の値を取る最適解が必ず存在することが保証されます。ソルバーが端点を返す解法を使っていれば、実際に返ってくる答えも整数になります。完全単模性とは、行列から取り出したどの正方部分行列を見ても、その行列式が0、1、マイナス1のいずれかにしかならないという性質のことで、これが整数解を保証する根拠になっています。
行列式という言葉が唐突に見えるかもしれませんので、どこでこの性質が効いているかを補っておきます。LPの最適解は、制約が作る領域の角にあたる端点に現れます(第6章)。端点の座標は、選んだ制約を等式として連立させて求めますが、その解を書き下すと、分子に在庫や需要といった右辺の数値が並び、分母に係数行列から取り出した正方部分行列の行列式が来ます。分母が1かマイナス1にしかならず、分子側が整数であれば、割り算の結果は必ず整数になります。完全単模性が整数解を保証するというのは、この分母の話をしているということです。
この性質は、実務では2つの形で効いてきます。1つは、モデルが軽くなることです。輸送量を整数に限る条件を書き加えれば、その問題は第3章の分類でいうMIPになり、緩和と分枝限定法による探索が必要になります。同じ答えがLPのまま得られるのであれば、その探索工程はまるごと不要です。もう1つは、計算時間が読めることです。MIPの計算時間は変数の数だけでは決まらず、実際に解かせてみるまで見当がつきませんが、LPであれば規模から所要時間の桁を見積もれます。毎晩決まった時刻までに翌日の配分表を出す、といった運用に乗せる場合、この違いはシステムの設計そのものを左右します。「整数条件を書かなくてよい」は数学的な小技ではなく、開発の見積もりを1段軽くする話です。
ただし、整数で返ってくるのは在庫と需要が整数の場合に限られます。需要を小数で与えれば、答えも小数になります。重量やリットルのように連続量を配分する問題では、そもそも整数である必要がないため気になりませんが、ケース単位やパレット単位で配分しているのに答えが小数で出てきたという場合は、モデルを疑う前に入力データの単位と丸めを確認するのが先です。
もう一点、この性質はネットワークの形が保たれている間だけ有効です。たとえば、倉庫を開設するかどうかの判断を同じモデルに組み込み、第5章のbig-M法で開設の有無と輸送量を結び付けると、係数行列にネットワークの形をしていない行が加わり、完全単模性は失われます。積載量に応じて必要な便数を数える条件や、複数の経路にまたがる合計に上限を置く条件も同じです。逆に、経路ごとの上限や下限であればネットワークの形は保たれます。目安としては、1本の経路だけに関わる条件なら安全、複数の経路をまたぐ条件を1本足した時点で保証は外れる、と考えておくとよいでしょう。定式化の途中で新しい条件が出てきたときに、それがネットワークの形を壊すものかどうかを確認する習慣を持っておくと、計算時間の見通しを立て直す判断が早くなります。
なお、整数の答えが返ってきたという事実そのものは、完全単模性が保たれていることの証明にはなりません。たまたま整数になっただけという場合もあり得ます。実務上の手軽な確認としては役に立ちますが、根拠として持ち出すなら、係数行列がネットワークの形をしているかどうかを構造の側から見るのが正しい順序です。確かめ方も単純です。整数条件を書かずにLPとして解き、答えがすべて整数で返ってくるかを見ます。整数で返ってくるうちは構造が保たれており、小数が混じり始めたら、直前に足した条件がネットワークの形を壊したという合図です。どの条件を足した時点で小数が出たかを記録しておけば、その条件を別の書き方に置き換えられないか、あるいは整数条件を明示したうえで計算時間を見積もり直すかを、根拠を持って判断できます。
この構造を持つのは輸送問題だけではありません。人と業務を対応づける割当問題(第7章)や、地点間の最短経路を求める最短路問題も同じ形をしており、同じ理由で整数の答えが得られます。割当問題を第5章の0か1を取る変数で書いた場合でも、整数条件を外してLPとして解けば、答えは自然に0と1に落ちます。第3章の早見表でネットワーク型が独立した1行を与えられているのは、こうした共通の性質を持つ一群だからです。自社の課題が点と線のつながりで表せると気づくことには、問題が見やすくなるという以上の実利があります。

倉庫と店舗という2階層に限らなければ、この型はもっと広く使えます。一般形が最小費用流問題です。書き方は、点と、点をつなぐ矢印を並べるだけです。各点には、供給量、需要量、あるいはどちらでもないという区分を与えます。各矢印には、1単位を流したときのコストと、流せる量の上限を与えます。決定変数は矢印ごとの流量です。制約は、各点で「入ってくる量と出ていく量の差が、その点の供給量または需要量に一致する」という1本だけです。この条件は保存則と呼ばれ、途中の点で荷物が消えたり湧いたりしないことを意味します。
この書き方に慣れると、表現できる範囲が一気に広がります。中継拠点は、供給でも需要でもない点として置けば、経由するかどうかがそのまま流量として決まります。トラック便と鉄道便のように、同じ区間に複数の輸送手段がある場合は、同じ2点を結ぶ矢印を2本並べ、それぞれに単価と容量を与えます。特定の区間の輸送能力に上限があるなら、その矢印の容量として書きます。「どの経路を使うか」という選択を、選択肢を表す変数ではなく矢印の本数で表現できるところが、この形の使いやすさです。
そして、これまでに出てきた型の多くが最小費用流の特殊な場合として位置づきます。輸送問題は供給点と需要点だけからなる形、割当問題は供給量と需要量がすべて1の形、最短路問題は1つの点から1単位を流す形です。共通の枠組みに収まるということは、専用に開発されたアルゴリズムがそのまま使えるということでもあります。第3章の早見表にあるとおり、ネットワーク型が大きな規模でも実用的な時間で解けるのは、この構造を前提にした解法が使えるためです。
| 型 | 点が表すもの | 矢印が表すもの | 本コラムでの扱い |
|---|---|---|---|
| 輸送問題 | 供給地点と需要地点 | 供給地点から需要地点への輸送 | 本章 |
| 割当問題 | 割り当てる側と割り当てられる側 | 1対1の対応づけ | 第7章 |
| 最短路問題 | 経路上の地点 | 地点間の移動 | 型の名前のみ |
| 最小費用流問題 | 供給点、需要点、中継点 | 容量と単価を持つ流れ | 本章 |
例題では在庫の合計と需要の合計がどちらも180個で一致していましたが、実務ではまず一致しません。在庫のほうが多い月もあれば、需要のほうが多い月もあります。この不一致をそのまま等式で書くと、制約を同時に満たす配分が存在せず、ソルバーは実行不可能とだけ返してきます。原因はデータではなく定式化の側にあるため、まずここを疑う価値があります。
扱い方は単純で、差を吸収するための架空の点を1つ足します。在庫が需要を上回っている場合は、余った分の行き先としてダミーの店舗を置きます。この店舗への輸送コストを0にすれば「倉庫に置いたまま」という意味になり、保管費を入れれば「翌期に持ち越す費用」という意味になります。どの倉庫に在庫を残すかも、このコストの置き方で誘導できます。逆に需要が在庫を上回っている場合は、供給元としてダミーの倉庫を置きます。ダミー倉庫から送られた量は、実際には届かなかった量、つまり欠品を表します。
ここで重要なのは、ダミーからの輸送コストに何を入れるかが、そのまま業務判断だという点です。欠品1個あたりの機会損失を金額で置けば、「欠品させてでも輸送費を抑えるべき場面」と「輸送費をかけてでも欠品を避けるべき場面」を、モデルが金額の比較として自動的に切り分けます。この金額を置けないまま「欠品は絶対に避ける」と等式で書いてしまうと、在庫が足りない月には毎回解が出ないシステムができあがります。ダミー拠点は数式上の帳尻合わせではなく、避けられない不足をどう配るかという判断を明示的に書く場所です。
不足が避けられないと分かったとき、次に決めるのは、どこにどれだけ我慢してもらうかです。ダミー倉庫から各店舗への単価を店舗ごとに変えれば、この優先順位はそのまま数値になります。旗艦店や大口の法人向け拠点には高い欠品コストを設定し、在庫を回しやすい近接店舗には低めに設定する、といった具合です。この単価は、欠品したときに失う粗利や、契約上のペナルティから見積もるのが筋の通った決め方になります。
金額に換算しにくい場合は、条件の側で書く方法もあります。「どの店舗も需要の8割以上は満たす」という下限を経路ごとの制約として置き、その範囲でコストを最小化する形です。特定の店舗にだけ不足が集中する事態は、これで避けられます。1店舗あたりの最大の欠品量を小さくしたい場合は、第5章の最大値の線形化を使います。合計の欠品量を減らす定式化と、いちばん不足の大きい店舗を救う定式化は別物で、前者は効率、後者は公平性に寄った答えを返します。どちらを採るかは業務判断であり、両方を計算して並べて見せると議論が早く進みます。
いずれの書き方を採る場合も、優先順位を数値として残しておくことに意味があります。従来、不足時の配分は担当者が電話で調整して決めていることが多く、その判断根拠は記録に残りません。欠品コストや充足率の下限として明文化すれば、なぜその店舗が減らされたのかを後から説明できます。配分の妥当性を問われる場面で、根拠を提示できるかどうかは運用の安定度に直結します。
店舗間の横持ちも、同じモデルに載せられます。店舗どうしを結ぶ矢印を足し、その単価に横持ちの輸送費を入れるだけです。倉庫からの補充が間に合わない状況で、在庫に余裕のある近隣店舗から融通するという運用は現場でよく行われますが、どこからどこへ回すのが全体として安いかは、店舗数が増えると勘では追えなくなります。矢印を足しても点と線のつながりであることは変わらないため、答えが整数で返る性質もそのまま保たれます。
実際の物流は、工場から物流センターを経て店舗に届く多段階の構造をしていることがほとんどです。この場合も書き方は変わりません。工場を供給点、店舗を需要点、物流センターを供給でも需要でもない中継点として置き、保存則を課すだけです。工場から店舗へ直送する経路と、物流センターを経由する経路の両方を矢印として並べておけば、どちらを使うかの判断もモデルの中で決まります。直送は輸送単価が高くても積み替えの手間がかからず、経由は単価が下がる代わりにセンターの処理能力を消費します。この兼ね合いを勘で決めていた部分が、単価と容量の比較として明示されます。
期間をまたぐ計画も、同じ枠組みに載せられます。「第1週の物流センター」と「第2週の物流センター」を別々の点として並べ、その間を結ぶ矢印に保管費を与えると、その矢印を流れる量が翌週への在庫の繰越を表します。時間軸を点の側に展開してしまうという発想で、これによって多期間の配分計画が1つのネットワークとして書けます。同じ考え方を生産計画に適用した多期間の定式化は第6章で扱っています。
先ほど触れた、品目ごとに分けて解けるかどうかの分かれ目も、ここで整理できます。品目Aの配分と品目Bの配分がそれぞれ独立に決まるなら、問題は品目の数だけの小さな輸送問題に分解できます。ところが「同じ便に積むため、全品目の合計重量が車両の上限を超えない」という条件が1本入ると、品目をまたいで変数が結び付き、分解できなくなります。この種の条件は複数の経路にまたがるため、前述のとおりネットワークの形も壊します。共通の制約が1本増えるだけで、軽いLPの集まりだった問題が1つの重い問題に変わるということです。実務では、その共通制約が本当に効いているのかを実データで確かめ、余裕をもって満たされているなら外して分解する、という判断が有効です。
境界も引いておきます。この章で決めているのは、拠点の場所と需要が与えられたときに「どこからどこへいくつ送るか」だけです。物流センターをどこに置くか、いくつ置くかという判断は第8章、各拠点にどれだけの在庫を持つかという判断は第10章で扱います。実務のプロジェクトでは、これらを一度に決めようとして問題が重くなり、解が出ないまま止まることがあります。配分だけを先に解けるようにしておくと、拠点の候補を何通りか変えて配分コストを計算し、その結果を拠点配置の判断材料にするという進め方が取れます。重い問題を1つ解くより、軽い問題を何度も解くほうが結論に早く届く場面は少なくありません。
配分のモデルを実際の業務に載せる際、最初に確認したいのが輸送コストの定義です。例題では1個あたりの単価としましたが、実際の請求は1台あたりの車建てであることが多く、その場合コストは輸送量に比例しません。9個でも11個でも1台分の料金がかかり、11個になると2台分になる、という階段状の形になります。この形をそのまま書くと線形ではなくなりますので、第5章の区分線形近似で扱うか、比例するとみなせる規模かどうかを先に確かめておく必要があります。ここを詰めずに単価だけでモデルを組むと、計算上は最適でも請求額が下がらないという結果になりかねません。
もう一つは、出力の粒度です。配分表がそのまま出荷指示として使える形になっていなければ、担当者が手作業で品目別に割り戻すことになり、自動化した意味が薄れます。品目をまとめて総量で解いた結果を、後から品目別に分ける運用にするのか、最初から品目を添字に加えて解くのかは、変数の数と現場の使い勝手を見比べて決める判断になります。
次章では、発注量と在庫水準の決め方を扱います。
『Pythonによる数理最適化入門』(並木誠 著、久保幹雄 監修、朝倉書店):この章で扱った輸送問題と最小費用流問題を、実際に動くコードとして書き下す手順を確認できる一冊です。ネットワーク型の問題をどのようなデータ構造で持ち、どう解かせるかまで具体的に追えるため、配分のモデルを試作する段階の手引きになります。
発注量と在庫水準の決定は、いつ、いくつ手配するかを繰り返し決める意思決定です。多く持てば欠品は減りますが、保管費と廃棄の損が増えます。少なく持てば在庫は軽くなりますが、売り逃しと緊急手配が増えます。どちらに振っても損失が出る構造になっており、そのわりに担当者の経験で「だいたいこのくらい」と決められたまま、根拠が書き残されていない領域でもあります。
この課題が本コラムのほかの課題と異なるのは、決めるべき数量が需要という不確かな量に対して決まる点です。設備の稼働可能時間や倉庫の保管容量は計画を立てる時点で分かっていますが、来月いくつ売れるかは分かりません。したがって発注量の決定は、需要予測の出力をそのまま入力として受け取る位置に立っています。予測と最適化がそれぞれ何を担うかは第1章で触れたとおりですが、両者が実際に噛み合う接点がこの章の主題です。
この課題には、性質の異なる2つの型があります。1つは、需要が安定していて補充を繰り返す品目に対して、1回あたりの発注量を決める型です。もう1つは、売れ残ると価値を失う品目に対して、1回限りの仕入量を決める型です。前者は第3章の分類でいえば決定変数が1つの非線形計画問題にあたり、後者は需要の確率分布を目的関数に取り込む点でその枠の外に出ますが、いずれも閉じた式で答えが出るため、ソルバーを持ち出す前に手元で計算できます。
例題:部品の1回あたり発注量
年間需要は10,000個で一定ペース、1回の発注固定費は4,000円、在庫保管費は1個あたり年間200円とします。発注量を増やせば発注回数は減りますが在庫が増え、減らせば在庫は減りますが発注回数が増えるというトレードオフです。
3点セットで書き下すと次のようになります。
目的関数の第1項は、年間の発注回数 \(D/x\) に1回あたりの固定費Kを掛けたものです。第2項は、在庫が0とxの間を直線的に上下することから平均在庫が \(x/2\) になり、そこに単位あたりの保管費hを掛けたものです。前者はxが増えるほど小さくなり、後者はxが増えるほど大きくなります。
このトレードオフは閉じた式で解けることが知られており、経済発注量(EOQ)と呼ばれます。年間需要をD、発注固定費をK、単位あたり保管費をhとすると、最適発注量は \(\sqrt{2DK/h}\) で与えられます。今回の数値では \(\sqrt{2 \times 10000 \times 4000 / 200} = \sqrt{400000} \fallingdotseq 632\) となり、1回あたり約630個、年間およそ16回の発注が最適という結論になります。
この式が閉じた形で書けるのは、目的関数が谷を1つだけ持つ形をしているためです。第3章でいう凸な形にあたり、傾きがゼロになる点を求めれば最小値が確定します。実際に計算すると、最適点では第1項と第2項が等しくなります。つまり、年間の発注費と年間の保管費がちょうど釣り合う量が最適な発注量だということです。今回の数値でも、発注費が \(10000 \times 4000 / 632\)、保管費が \(200 \times 632 / 2\) で、いずれもおよそ63,000円と一致します。この釣り合いの形は、EOQの答えが妥当かどうかを検算するときにも使えます。
実務で効いてくるのは、この谷が平らだという性質です。発注量が最適値の2倍になっても、逆に半分になっても、年間の総費用の増加は25%にとどまります。今回の設定では、最適な発注量での年間総費用が約126,000円であるのに対し、2倍または半分の発注量でも約158,000円です。さらに、最適発注量は年間需要の平方根に比例するため、需要の見積もりが2割ずれても発注量のずれは1割程度にしかならず、総費用への影響はそれよりさらに小さくなります。EOQの入力を精密に測ることに時間をかけるより、桁を外さないことのほうが重要だということです。この式が1913年に発表されて以来、道具として使われ続けている理由の一端もここにあります。
実務では数量割引、リードタイム、需要変動が加わるためこの式のままでは使えませんが、発注方針を議論する際の出発点としての価値は大きいものがあります。前提が崩れたときにどう扱うかは、この章の後半で順に見ます。
例題:廃棄と機会損失があるときの仕入量
仕入原価100円、売価300円、売れ残りの価値はゼロとします。1個多く仕入れて売れ残れば原価100円の損失、1個少なく仕入れて品切れになれば利益200円の機会損失です。
3点セットで書き下すと次のようになります。
この構造は新聞売り子モデルと呼ばれ、臨界比率という指標で最適な仕入量が決まります。品切れによる損をCu、売れ残りによる損をCoとすると、臨界比率は \(C_u / (C_u + C_o)\) です。今回は \(200 / (200 + 100) \fallingdotseq 0.67\) となり、需要がその数量以下に収まる確率が67%になる点まで仕入れるのが最適という結論になります。
この比率が出てくる理屈は、1個だけ余分に仕入れるかどうかを考えると見えます。すでにx個仕入れると決めているところに、もう1個追加したとします。その1個が売れるのは需要がxを上回ったときで、そのとき利得はCuです。売れ残るのは需要がx以下のときで、そのとき損失はCoです。需要がx以下に収まる確率を \(F(x)\) と書けば、追加1個の期待損得は \(C_u (1 – F(x)) – C_o F(x)\) になります。これが正である限り仕入れを増やす価値があり、ゼロになる点で止めるのが最適です。式を解くと \(F(x) = C_u / (C_u + C_o)\) となり、これが臨界比率にあたります。
ここで注目したいのは、答えが数量そのものではなく確率で与えられている点です。0.67という値は「需要分布の67%点まで仕入れる」という指示であって、それが何個にあたるかは需要の分布が決まらなければ出てきません。EOQが年間需要という1つの数字から発注量という数字を返したのとは、入力の性質が違います。
臨界比率がどちらに寄るかは、2つの損失の大小で決まります。品切れの損が大きい品目ほど比率は1に近づき、分布の上側まで仕入れる、つまり多めに持つのが最適になります。逆に廃棄の損が大きい品目ほど比率は0に近づき、少なめに持つのが最適です。今回の設定では売価300円に対して原価が100円で、売り逃しの痛みのほうが廃棄の痛みより大きいため、平均的な需要より多めに持つ答えになります。粗利率の高い商品ほど多めに、原価率の高い商品ほど少なめに、という現場の感覚と方向は一致します。この型が与えるのは、その感覚を品目ごとに数量として決められる根拠です。
ここで重要なのは、この計算に需要の平均値ではなく分布が必要だという点です。需要予測モデルが平均だけでなくばらつきまで出力できれば、臨界比率と接続して発注量を直接決められます。需要予測と在庫最適化をセットで設計すべき理由は、ここにあります。
多くの需要予測は、来月の販売数は1,200個です、という1つの数字を返します。これを点予測と呼びます。点予測しか手元にないと、臨界比率が0.67と分かっていても発注量に変換できません。67%点がどこにあるかは、需要が1,200個の周りにどれくらいばらついているかを知らなければ決まらないからです。ばらつきの小さい品目では平均をわずかに上回る程度の数量になり、ばらつきの大きい品目では平均を大きく上回る数量になります。同じ平均でも、発注量は分布の形で変わるということです。
したがって、在庫の意思決定に接続する需要予測に求められるのは、平均を当てる精度だけではありません。分布、あるいは必要な分位点を出せることです。実務では次のいずれかの形で用意します。
需要が間欠的な品目、つまり多くの日は0個で、たまにまとまった数が出る品目では、正規分布の仮定は特に外れやすくなります。この場合は実績の度数分布をそのまま使う、あるいは間欠需要を前提とした手法に切り替えるという判断になります。分布を用意する工程を省いて平均だけで発注量を決めると、この種の品目では欠品と過剰在庫が同時に発生します。
在庫の話をすると、需要予測が当たらないのだから発注量を最適化しても意味がない、という指摘が出ることがあります。これは半分だけ正しいといえます。
正しくないほうから述べます。ここまでの2つの型は、いずれも需要が当たることを前提にしていません。EOQは需要の見積もりが多少ずれても総費用がほとんど変わらない構造を持っていました。新聞売り子モデルにいたっては、需要が外れることを前提に、その外れ方の分布を入力として受け取る形になっています。品切れと廃棄のそれぞれに何円の損が出るかを与えれば、外れることを織り込んだうえで損失の期待値が最も小さい数量が決まります。予測が完全でないことは、最適化を諦める理由ではなく、平均ではなく分布を使う理由にあたります。
正しいほうは、予測の質が意思決定の質に効く場面があるという点です。ただしその効き方は、点予測の精度そのものとは違うところに現れます。臨界比率が0.5から離れるほど、必要になるのは分布の裾の情報です。品切れの損が廃棄の損の9倍あれば臨界比率は0.9となり、需要分布の90%点を当てにいくことになります。平均の予測がどれだけ正確でも、裾の形を読み違えれば発注量は外れます。予測モデルへの投資を検討する際に見るべきなのは、平均の誤差を何%縮められるかではなく、意思決定に使う分位点をどれだけ正しく出せるかです。
この見方は、予測モデルの評価の仕方にも影響します。平均の誤差だけでモデルを選ぶと、平均は当たるが裾が合わないモデルが選ばれることがあります。在庫の意思決定に使うのであれば、そのモデルの出力から発注量を決めたときに、過去の実績に対していくらの損失が出たかで評価するのが筋の通った測り方です。予測を担う部門と在庫を担う部門が分かれていると、この評価が誰の仕事でもなくなりやすく、予測の精度指標は改善しているのに欠品も過剰在庫も減らない、という状態が続きます。評価をどちらの部門の指標に載せるかは、モデルの精度以前に決めておく事項です。
もう1点、予測の改善と運用の改善は互いに代替します。リードタイムが2週間の品目では、2週間先の需要を読む必要があります。リードタイムを3日に縮められれば、読む必要のある期間が短くなり、同じ予測精度のままでも必要な在庫は減ります。発注の頻度を上げることにも同じ効果があります。予測を良くするか、読む期間を短くするか、どちらが安く効くかは品目と取引条件によって異なります。在庫の課題を予測の課題としてだけ扱うと、この選択肢が最初から視野に入りません。
ここまでの2つの型は、発注のタイミングを扱っていません。EOQは1回あたりいくつ発注するかを決めますが、いつ発注するかは決めていないためです。実務では発注してから届くまでにリードタイムがあり、在庫が尽きる前に発注する必要があります。この「いつ」を決めるのが発注点です。
発注点は、リードタイムの間に見込まれる需要と、そのばらつきを吸収するための上乗せの合計として決めます。上乗せの部分が安全在庫です。リードタイム中の平均需要と同じだけの在庫を残して発注すると、需要がその平均を上回った時点で欠品します。需要の分布が左右対称であれば、欠品する確率はおよそ半分になるという関係です。安全在庫は、この確率を業務が許容できる水準まで下げるために積む在庫だといえます。
安全在庫の大きさは、リードタイム中の需要のばらつきに、目標とする欠品の許容水準に応じた係数を掛けて求めます。需要が正規分布に従うと仮定した場合、欠品を5%まで許容するなら係数は約1.65、1%までなら約2.33です。許容水準を上げるほど係数の伸び方は急になり、99%から99.9%へ引き上げると係数は約3.09に達します。サービス水準の最後の数%が在庫費用を大きく押し上げるという実感は、この伸び方に対応しています。
ここで、目標とする欠品の許容水準をどう決めるかという問題が残ります。慣行で全品目一律に95%と置かれていることの多い項目ですが、この水準こそ臨界比率で決められる部分です。欠品1個あたりの損と、在庫1個を1期間持ち越す損が分かれば、両者の比から適切な水準が計算できます。品目ごとに粗利も保管費も違う以上、すべてに同じ水準を当てるのは本来は根拠のない運用です。粗利の高い品目の水準を上げ、低い品目の水準を下げるだけで、在庫総額を増やさずに欠品を減らせることがあります。臨界比率は1回限りの仕入れだけの道具ではなく、繰り返し補充する品目のサービス水準を決める場面にも同じ形で効いてくるということです。
リードタイムそのものがばらつく場合は、需要のばらつきに加えて入荷時期のばらつきも安全在庫に効きます。海外調達で入荷が1週間前後する品目では、需要が読めていても在庫を厚く持たざるを得ません。安全在庫を減らす議論をするときに、需要予測の精度だけを見て調達側のばらつきを見ないのは片手落ちになります。入荷日の実績を記録していない現場は珍しくなく、その場合はばらつきを測るための記録を始めるところからになります。
発注のルールは、大きく2つの形に整理されています。どちらもここまでの発注量と発注点を部品として使いますが、運用の前提が違います。
定量発注方式は、在庫が発注点を下回った時点で、あらかじめ決めた一定量を発注する形です。発注量にはEOQを使い、発注点は前節の形で決めます。在庫を常時把握できることが前提になりますが、発注量が一定なので運用は単純です。需要が伸びれば発注点に到達するまでの期間が自然に短くなり、発注の間隔が伸び縮みして需要の変化に追随します。
定期発注方式は、毎週月曜のように決まったタイミングで在庫を確認し、目標とする在庫水準まで足りない分を発注する形です。発注量は毎回変わります。この方式で読む必要がある期間は、リードタイムだけでなく、次の発注機会までの間隔を足した長さになります。今日発注しなかった分は次の発注日まで補充されないためです。したがって、同じ欠品の許容水準を保つには、定量発注方式より安全在庫が厚くなります。
使い分けの軸は3つあります。1つは在庫を常時把握できるかどうかで、把握できないなら定期発注しか選べません。2つ目は発注の手間で、品目数が多く1件ずつ発注点を管理することが現実的でない場合は、定期発注のほうがまとまります。3つ目は輸送や取引のまとまりで、同じ仕入先から多品目を1便で受け取る場合は、発注日を揃える定期発注のほうが輸送費と事務費を抑えられます。
実務では全品目に同じ方式を当てるのではなく、金額の大きさと動きの読みやすさで区分して方式を変えます。金額が大きく動きの読みにくい品目は定期発注で細かく見直し、金額が小さく安定して出る品目は定量発注に任せて手を離す、という切り分けです。管理の手間も有限な資源であり、どこに手間をかけるかを決めることは在庫の意思決定に含まれます。
EOQが置いている前提は、需要が一定ペースで発生すること、単価が数量によらないこと、リードタイムが一定であること、欠品を起こさないことの4つです。実務ではこのいずれかが崩れます。崩れ方ごとに扱いが決まっています。
単価が数量で変わる数量割引の場合は、式をそのまま当てはめられません。実務的な手順は、単価が一定である区間ごとにEOQを計算し、その値がその区間に収まっているかを確かめ、収まっていなければ区間の境界にあたる数量を候補に加えて、候補の中で年間総費用が最小のものを選ぶという形になります。候補は数個にしかならないため手計算でも足ります。段階的に変わる単価をモデルの中で表現する書き方は第5章で扱っています。
リードタイムは、発注量ではなく発注のタイミングに効きます。EOQの計算そのものは変わらず、発注点の側で吸収します。量とタイミングを分けて扱えることが、この2つを別々の式で決められる理由です。
需要が一定ペースでない場合は、前提そのものから外れます。ただし総費用の谷が平らであることを踏まえれば、年間需要として平均を使い、変動は安全在庫の側で吸収するという使い方は実務で成り立ちます。季節性が大きく、時期によって需要が数倍変わる品目では、この近似は苦しくなります。その場合は期ごとに需要量が異なる前提で計画を立てることになり、多期間の計画問題として書き直します。多期間の計画の定式化は第6章で扱っています。
欠品を許す前提に変えると、欠品による損失を目的関数に足した別の式になります。ここで必要になるのが欠品1個あたりの損失額であり、この数字を持っている企業は多くありません。売り逃した分の粗利で置くのか、代替品に流れた分を差し引くのか、顧客が離れる影響まで見るのかで金額は変わります。決め方を関係者で合意し、根拠とともに記録しておくことが、後で結果を説明するために要ります。
保管しているだけで価値が下がる品目では、そもそもEOQの型が合いません。生鮮品、季節商品、型落ちのある製品は、まとめ買いによる発注費の節約が廃棄の損で相殺されるため、新聞売り子モデルの側で考えるのが自然です。同じ在庫の課題でも、品目の性質によって使う型が変わります。
もう1つ、EOQは品目ごとに独立に計算します。実務では倉庫の保管容量、発注担当者の処理能力、仕入に充てられる資金といった共通の制約があり、品目ごとに最適な発注量を足し合わせると制約を超えることがあります。この場合は個別の計算では足りず、全品目の発注量を同時に決める問題として書き直します。決定変数は品目ごとの発注量、目的関数は総費用の合計、制約は共通資源の上限という形で、3点セットに落ちます。個別最適の積み上げが全体で成り立たなくなったときに、最適化の問題として書く必要が出てくるということです。

この章で扱った式は、いずれも一度計算して終わりのものではありません。入力となる保管費率、発注固定費、欠品による損失、リードタイム、需要の分布は、時間とともに変わります。運用に載せるうえでは、少なくとも次の3点を決めておくことになります。
発注量と在庫水準の決定は、数式そのものより、入力となる数字を誰がどう決めるかで結果が変わる領域です。欠品1個の損をいくらと置くか、廃棄1個の損をいくらと置くかは業務判断であり、その判断を明文化して残すことが、この章の型を使ううえでの実質的な作業になります。臨界比率も安全在庫の係数も、そこで置いた数字を機械的に数量へ翻訳しているにすぎません。
次章では、投資と施策の選定を扱います。
『サプライ・チェイン最適化ハンドブック』(久保幹雄、朝倉書店):この章で扱った発注量と在庫水準の決定を、調達から配送までを含むサプライチェーン全体の設計のなかに位置づけて確認できます。在庫モデルだけでなくロットサイズの決定や輸送計画までを同じ枠組みで扱うため、品目単位の発注ルールが全体の費用にどう効くのかをたどりたい場合の土台になります。
限られた予算をどの施策に配るかという意思決定は、多くの企業で年に一度は必ず発生します。設備投資の案件、研究開発のテーマ、DXの個別プロジェクト、広告の出稿先、人材の採用枠。いずれも候補の一覧が並び、それぞれに費用と期待できる効果の見積もりが付いていて、合計額が予算に収まる範囲でどれを実施するかを決める、という同じ形をしています。実務で広く使われているのは、費用対効果の高い順に候補を並べた表を作り、予算が尽きるところで線を引くという手順です。作業が簡単で、順位の根拠も説明しやすい方法ですが、この線引きが最も効果の大きい組合せを選んでいる保証はありません。
この課題は、第3章の分類でいえばMIPにあたり、ナップサック問題として定式化できます。決められた容量の袋に、価値の異なる品物をどう詰めれば価値の合計が最大になるか、という古典的な問題と同じ構造を持つためこの名前が付いています。ここでの袋の容量が予算、品物が施策候補、品物の重さが費用、品物の価値が期待効果にあたります。決定変数は候補ごとに1つずつ置いた第5章の0か1を取る変数、目的関数は効果の合計、制約は費用の合計が予算以下という1本だけです。定式化としては本コラムで扱う型のなかで最も短く書けますが、手作業の選定との差が出やすい型でもあります。
例題:限られた予算でどの施策に投資するか
施策候補は5件。費用は順に400、300、250、200、150万円、期待効果は順に500、420、300、290、180万円で、予算上限は700万円です。表にすると次のようになります。効率の列は、期待効果を費用で割った値です。
| 施策 | 費用(万円) | 期待効果(万円) | 効率(効果÷費用) |
|---|---|---|---|
| 施策1 | 400 | 500 | 1.25 |
| 施策2 | 300 | 420 | 1.40 |
| 施策3 | 250 | 300 | 1.20 |
| 施策4 | 200 | 290 | 1.45 |
| 施策5 | 150 | 180 | 1.20 |
3点セットで書き下すと次のとおりです。
係数を記号で置くなら、施策iの費用を \(c_i\)、期待効果を \(e_i\)、予算上限を \(B\) として、\(\sum_i e_i x_i\) を最大化し、\(\sum_i c_i x_i \leq B\) を満たす、という2行で書き切れます。業務側から集めるデータも、候補の一覧と費用と効果の3列だけです。
ここで注目していただきたいのは、「費用あたりの効果が高いものから順に選ぶ」という直感が最適解を外すことです。効率の高い順に選ぶと施策4、施策2、施策5が採択され、費用650万円で効果890万円になります。しかし施策1と施策2を選べば、費用は上限ちょうどの700万円で効果は920万円に達します。差は効果で30万円、しかも予算は50万円多く使われずに残っています。予算を残したまま効果を取り逃がしている状態です。
予算をちょうど使い切る組合せは他にもあります。施策2と施策3と施策5の組は、費用が700万円で効果が900万円になります。使い切ってさえいれば良いわけではなく、どの組合せで使い切るかによって20万円の差が生じるということです。
候補が5件であれば、採択するかしないかの組合せは32通りしかなく、すべて書き出して比べることもできます。ただし手作業で全部を書き出す場面は現実にはほとんどなく、多くの場合は順位表の上から線を引いて終わりになります。候補が数十件に増えれば書き出す方法は取れなくなりますが、その規模の増え方が計算にどう効くかは第3章で扱ったとおりで、この程度の件数であれば整数計画ソルバーが厳密解を瞬時に返します。表計算ソフト上での手作業の選定を置き換える価値は大きいと言えます。この例題を実際にコードで解く手順は第13章で扱います。
順位を付けて上から採る方式を貪欲法と呼びます。この例で効率順の貪欲法が外した理由は、枠の埋まり方をたどると見えてきます。効率が最も高い施策4を先に入れると残りは500万円、次に効率の高い施策2を入れると残りは200万円になります。効果が最も大きい施策1は費用が400万円ですので、この時点でもう入る余地がありません。施策4を入れずにいれば、施策1と施策2の両方が予算にちょうど収まっていました。効率の高い小さな候補を1つ先に入れたことが、後から効果の大きい候補を締め出しているわけです。個々の候補の良し悪しではなく、費用の組合せが予算枠にどう収まるかという「詰まり方」が結果を左右します。
効率順という規則そのものが誤っているわけではありません。施策を途中まで実施でき、費用の半分だけ払えば効果も半分だけ得られると仮定してよいのであれば、効率の高い順に予算を使い切る選び方が最適になることが知られています。実務の施策はそこで切れず、半分だけ実施した基幹システムの刷新には効果がありません。分割できないという条件が入った瞬間に、効率順の保証は失われます。整数の条件が入ると計算の性質が変わる理由は第3章で扱ったとおりで、この例題はその現れ方を最も小さな形で見せているものだと言えます。
では効果の大きい順ならよいかというと、こちらにも保証はありません。この例題では、効果の大きい順に選ぶと施策1と施策2が採択され、結果として厳密解と一致しますが、これは費用の並びがたまたまそうなっていたためであり、規則が正しいことを意味しません。効果が最大の候補が予算の大部分を1件で占有し、残った枠に何も入らないという状況は容易に起こります。順位を付けて上から線を引く方式は、費用の側の組合せを一切考慮していないため、どの指標で順位を付けても外れる可能性が残ります。
この性質は、予算会議の進め方にそのまま関わります。案件をROIの高い順に並べた資料を配り、上から順に予算が尽きるまで承認していく進め方は、まさに効率順の貪欲法です。候補が数件なら差は小さく収まりますが、候補が数十件に増え、費用の桁がばらつくほど、取り逃がす効果の額は大きくなります。順位表を作る作業自体は必要ですが、順位表は議論の材料であって決定の手続きではない、と切り分けておく必要があります。
差が出やすい条件も、ある程度は見当が付きます。候補の費用が同じくらいの金額でそろっていて、予算がその金額の整数倍に近い場合は、どの順位規則で選んでもほぼ同じ答えになります。差が開くのは、大口の案件と小口の案件が混在していて、予算の残りが中途半端に余る場合です。数千万円規模の設備投資と数十万円規模の改善施策を同じ表に並べて順位を付けている、という状況は珍しくありません。自社の候補一覧が後者の形をしているなら、この章の型を使う価値は高いと考えられます。
ナップサック型に落ちるかどうかの見分け方は単純です。決めたいことが「やるかやらないか」であり、資源の上限が総量として与えられていて、それぞれの候補が資源をどれだけ使い、どれだけの価値を生むかが数字で置ける。この3つがそろえばこの型です。予算配分のほかに、設備投資案件の選定、研究開発テーマの絞り込み、DX案件のポートフォリオ、広告出稿先の組合せ、営業担当の訪問先の選定、限られた棚の割り当て、車両1台への積み合わせなど、対象は広く分布しています。共通しているのは、上限のある入れ物に何を入れるかという構造です。
近い型との区別も付けておきます。第8章で扱った拠点配置は、同じく0か1を取る変数で書きますが、目的が固定費の最小化であり、制約として全エリアを漏れなくカバーすることを課す形になります。カバーすべき対象が先に決まっていて、それを満たす最小の投資額を求めるのがそちらで、投資額の上限が先に決まっていて、その中での価値の最大化を求めるのがこの章の型です。予算が制約なのか、達成すべき水準が制約なのかで、どちらに書くかが決まります。第6章で扱った生産計画は、決めたいことが数量であり、量を連続的に動かせる点が異なります。「どれだけ作るか」ではなく「どれを実施するか」を決めたいのであれば、この章の型が出発点になります。
現実の施策選定では、候補が互いに独立していることのほうが少なくなります。基幹システムの刷新を行うならデータ基盤の整備も必要、同じ工場に2種類の設備を同時に入れることはできない、3つの案は同じ目的に対する代替案でどれか1つだけを採る、といった関係が必ず出てきます。これらはいずれも第5章で扱った論理条件の書き方をそのまま当てはめれば制約になります。
両方を実施したときにだけ追加の効果が出る、という相乗効果も、補助変数を1つ置く第5章の書き方で目的関数に載せられます。逆に、同じ顧客層を狙う2つの施策を両方実施しても効果が単純な足し算にならない、という重複の関係も同じ形で表せます。ここで重要なのは、こうした関係が制約として書かれていなければ、ソルバーは実行できない組合せを平然と最適解として返すという点です。施策の一覧を集める段階で、費用と効果の欄に加えて「前提となる施策」「同時に実施できない施策」の欄を設けておくかどうかが、モデルの実用性を分けます。
依存関係を洗い出す作業は、施策の一覧を眺めているだけでは進みません。有効なのは、候補を出した担当者に「この施策は単独で実施できるか」「実施済みでなければならない前提はあるか」の2問を必ず答えさせることです。この2問だけで、前提となる施策と一体で扱うべき案件の大半は拾えます。同時に実施できない組合せのほうは、同じ設備や同じ部署の同じ人員を取り合う候補を並べて確認する形になります。どちらも技術的な作業ではなく、申請の様式と確認の手順で解決する種類の課題です。
制約が増えるほど、順位表を上から採る方式との差はさらに開きます。前提関係が付いた施策は、単独では効率が低くても前提側とセットで見れば十分に高い、という逆転が起こるためです。人手で順位表を組み替えながらこの逆転を追うのは現実的ではなく、制約を書いてソルバーに解かせる価値が最も出るのがこの領域になります。
制約が予算1本というのは、説明のための単純化です。実際の施策選定では、金額のほかに、情報システム部門が確保できる工数、現場が新しい業務を受け入れられる件数、外部委託先の稼働といった資源が同時に効いてきます。これらは制約の本数を増やすだけで表せます。施策iが必要とする資源rの量を \(a_{r,i}\)、資源rの上限を \(B_r\) として、\(\sum_i a_{r,i} x_i \leq B_r\) という制約を資源の数だけ並べます。決定変数も目的関数も変わりません。予算だけを見て選んだ組合せが情報システム部門の工数を大幅に超えていた、という事態は、この1行を書いておけば起こらなくなります。
年度をまたぐ配分も同じ発想で書けます。施策iを年度tに着手するなら1を取る変数 \(x_{i,t}\) を置き、各施策は高々1回しか着手しないという条件を \(\sum_t x_{i,t} \leq 1\)、各年度の支出が当該年度の予算に収まるという条件を年度ごとに1本ずつ書きます。着手が遅れるほど効果の立ち上がりも遅れますので、目的関数の係数は年度によって変えます。3年目に着手した施策の効果を計画期間内の実現分だけで評価する、といった扱いです。使い残した予算を次年度に繰り越せる制度であれば、繰越額を表す変数を年度ごとに置いて、前年度の残額を翌年度の上限に足し込みます。
資源の制約を書くときに気を付けたいのは、上限として置く数値の根拠です。予算は稟議で決まった金額をそのまま入れれば済みますが、情報システム部門の工数や現場の受け入れ余力は、明示的な数字として管理されていないことが多くあります。ここに実態より大きい数字を置くと、モデルは資源の制約がないものとして選び、実行段階で立ち行かなくなります。逆に安全側に小さく置きすぎれば、実施できたはずの施策が落ちます。上限の置き方は、担当部門との合意事項として記録に残しておく必要があります。
複数年度で考えると、単年度では選ばれない施策が浮上することがあります。初年度に費用が集中して単年度予算に収まらない施策でも、着手年度をずらせば全体としては大きな効果を生む、という組合せが見えるようになるためです。単年度ごとの積み上げで決めている限り、この種の判断は構造的に見落とされます。
この型で最も弱い部分は、費用ではなく期待効果の数字です。費用は見積書や過去実績からある程度の精度で置けますが、効果は将来の予測であり、算出の前提も担当部署によってばらつきます。目的関数は効果の合計を最大化しますので、見積もりが楽観的な施策ほど選ばれやすくなります。精度の低い大きな数字が選定を支配するという構造が、この定式化には内在しています。
実務的な対処の第一は、シナリオを分けて解き直すことです。効果の見積もりを楽観・標準・悲観の3通り用意し、それぞれで最適な組合せを求めます。どのシナリオでも選ばれる施策と、シナリオによって出入りする施策に分かれますので、前者は議論の余地なく実施し、後者を検討の対象に絞れます。会議の時間を配分する先が数字で決まるという点で、この分け方は実用的です。
もう一段踏み込む考え方がロバスト最適化です。効果が見積もりからどれだけ下振れしうるかの幅を施策ごとに与え、その幅の中で最も悪い場合を想定しても最良になる組合せを選びます。悲観的に評価する分だけ選ばれる組合せは保守的になり、見積もりの根拠が固い施策に寄ります。効果の期待値が同程度なら、ばらつきの小さいほうが選ばれるという挙動です。新規性の高い施策が不利になる面はありますので、探索的な投資枠を別に確保して、その枠の中では別の基準で選ぶといった運用と組み合わせることになります。
効果の見積もりを一律に何割か割り引いてから最適化する、という運用も見かけますが、これは注意が必要です。すべての候補を同じ率で割り引いても順位も組合せも変わらず、単に効果の合計額が小さく見えるだけで終わります。割り引くのであれば、見積もりの確からしさに応じて率を変えなければ意味がありません。過去の実績と見積もりの差が施策の種類によって違うのであれば、その差を種類ごとの補正として入れるのが筋の通ったやり方になります。
ただし、いずれの手法を使っても、見積もりそのものの質を超える答えは出ません。効果の算出手順を部署間で揃える、前提となる数値の出所を書かせる、過去に承認された施策の見積もりと実績の差を記録する。こうした地味な整備のほうが、モデルを高度化するより結果に効くことが多いといえます。定式化を導入する過程で、効果の見積もりが同じ土俵に乗っていないことが明らかになるという副次的な効果もあります。数字を並べて最適化しようとした途端に、その数字が比較可能な形で作られていないことが露呈するという意味では、モデルを作る作業そのものが現状の点検になります。
この型を運用に乗せる作業は、モデルを作ることよりも、申請の様式を変えることが中心になります。モデルが必要とするのは、候補ごとの費用、期待効果、必要な資源量、前提となる施策、排他の相手という項目です。これらを施策の申請フォーマットの欄として最初から用意しておけば、集計の段階でデータがそろいます。逆に、様式を変えないまま個別に問い合わせて回る運用にすると、年に一度の作業のたびに担当者の手間が発生し、続きません。
会議での使い方にも工夫の余地があります。最適な組合せを1案だけ示して終わりにすると、選から漏れた施策の担当者は納得しにくくなります。有効なのは、特定の施策を必ず採択すると固定したうえで解き直し、全体の効果がいくら下がるかを示す方法です。その差額が、政策的にその施策を通すことの価格になります。「この施策を通すと全体の効果が40万円下がりますが、それでも通す価値があるか」という形の議論は、順位表を眺めながらの議論より結論が出やすくなります。落選した施策についても、効果が低いから落ちたのではなく予算枠と組合せの都合で落ちたのだ、という説明が数字を伴ってできます。
期中の変化にも対応できます。予算の追加が認められた、想定していた施策が外部要因で実施できなくなった、といった場面では、条件を書き換えて解き直すだけで残りの枠の使い方が更新されます。年度当初に一度決めたら期末まで動かさない運用から、条件が変わるたびに配分を組み直す運用へ移せることが、この型を導入する実質的な利点です。
運用にあたって決めておきたいのは、モデルが出した組合せをそのまま決定にするのか、案の1つとして扱うのかという位置づけです。予算配分には数字に表れない戦略上の意図が入るのが当然ですので、モデルの答えを決定そのものにする必要はありません。有効なのは、モデルの答えを基準線として置き、そこから外れる判断をするときに、外れることで失う効果の額を明示するという使い方です。基準線があることで、議論の対象が「どの施策が良いか」から「どの施策のために、いくらの効果を譲る判断をするか」に移ります。
導入後は、見積もった効果と実績の差を施策の種類ごとに記録しておきます。設備投資は見積もりに近く、販促施策は上振れも下振れも大きい、といった傾向が数年分たまれば、次年度の見積もりに掛ける補正の根拠になります。定式化そのものは変わらず、係数の質だけが年ごとに上がっていくという形です。年に一度しか回らない業務ではデータの蓄積に時間がかかりますので、四半期ごとの投資判断や、部門単位の小さな予算配分から先に適用して、記録を早く貯めるという進め方も現実的です。

次章では、配送ルートと配車計画を扱います。
『意思決定分析と予測の活用 基礎理論からPython実装まで』(馬場真哉、講談社):この章で扱った、効果が不確実な候補のなかから何を選ぶかという判断を、意思決定の理論の側から整理できる一冊です。期待値をどう扱うか、情報を追加で集めることにどれだけの価値があるかといった論点を押さえておくと、シナリオの分け方や見積もりの精度に投じる労力の配分を決めやすくなります。
配送ルートの決定は、その日に回るべき訪問先が決まったあとで、どの車両がどの順に回るかを決める意思決定です。訪問先の集合と車両の台数が同じでも、回る順番が違えば総走行距離は変わり、燃料費も、ドライバーの拘束時間も、最後の荷物が届く時刻も変わります。多くの現場では、この順番を配車担当者が地図と経験をもとに毎朝決めています。前日の受注が確定してから出発までの時間は短く、担当者は限られた時間のなかで実行可能な計画を1つ作ることに集中せざるを得ません。走行距離を最小にする順番が別にあるとしても、それを探す余裕はないというのが実情です。
この課題は、第3章の分類でいえば整数条件を含むMIPにあたり、訪問先を1回ずつ回って出発地に戻る最短の順序を求める型として定式化できます。ただし、この型は他の章で扱った型とは性質が大きく異なります。決定変数の置き方も目的関数も素直に書けるにもかかわらず、制約のほうに、書き下すと本数が爆発するという厄介な性質があります。この章では、まず基本形を書き下し、その制約の性質と実務での扱い方を見ていきます。
例題:配送トラックはどの順に回るべきか
出発地を含めて20地点、1台のトラックで全件を回って出発地に戻ります。目的は総走行距離の最小化です。
これが巡回セールスマン問題(TSP)です。最後の「部分巡回の禁止」がこの問題の難しさの中心にあります。各地点に1回ずつ出入りするという制約だけでは、全体が1つの輪にならず、小さな輪がいくつも独立してできてしまう解を許してしまうためです。これを排除する制約を加える必要があり、その本数は地点数に対して指数的に増えるため、実装では必要になった分だけ順次追加する方法が取られます。
20地点の巡回順は約6×10の16乗通りあり、総当たりでの探索は現実的ではありません。実務の配送計画は、これに時間枠、積載量、複数台の車両が加わった配車計画問題になることがほとんどで、専用のルーティングソルバーを使うのが第一候補になります。
決定変数 \(x_{i,j}\) は第5章の0か1を取る変数そのもので、地点iの次に地点jへ向かうかどうかという判断を1つずつ変数に対応させたものです。地点が20か所であれば、行き先の組み合わせは自分自身への移動を除いて380通りあり、その一つひとつに変数が立ちます。目的関数は、選ばれた移動の距離を足し合わせるだけですから、\(\sum d_{i,j} x_{i,j}\) と書けます。ここまでは第2章の3点セットの手順どおりに進みます。
制約の前半も素直です。各地点からちょうど1本の移動が出ていくという条件は、地点iについて \(\sum_j x_{i,j} = 1\)、各地点にちょうど1本の移動が入ってくるという条件は、地点jについて \(\sum_i x_{i,j} = 1\) と書けます。地点が20か所なら、この2組で合計40本の等式です。「すべての配送先を1回ずつ訪問する」という業務上の要請を、そのまま等式に写しただけの形になっています。
問題は、この40本を満たしていても、1つながりの経路になるとは限らないところにあります。たとえば地点1から5までの5か所が1、2、3、4、5、1という輪をつくり、残りの15か所が別の輪をつくったとします。どちらの輪の中でも、各地点から出る移動は1本、入る移動も1本ですから、40本の等式はすべて満たされています。しかし現実には、トラックは2つの輪を同時に走ることができません。この「複数の独立した輪に分裂した解」を部分巡回と呼びます。距離を最小化しようとすると、近い地点どうしで小さな輪をつくったほうが総距離は短くなりやすいため、部分巡回はたまたま起こる例外ではなく、むしろ積極的に選ばれてしまう解です。
この点は、業務側に説明するときに誤解されやすい箇所でもあります。「すべての配送先を1回ずつ回る」という日本語の条件は、担当者の頭のなかでは当然に1本の経路を意味しています。ところが数式に写すと、その「1本のつながり」という部分だけが抜け落ちます。訪問回数は地点ごとの局所的な条件として書けますが、経路がつながっているかどうかは経路全体を見なければ判定できない、大域的な条件だからです。日本語では1文で済む条件が、数式では別枠の制約群を必要とする、という典型例といえます。
部分巡回を排除する書き方は、地点の集合の一部を取り出して考えます。全地点のうち一部を集めた集合 \(S\) について、\(S\) の内側だけで閉じた移動が \(|S|\) 本あると、\(S\) だけで輪ができてしまいます。そこで、\(S\) の内側で使える移動の本数を \(|S| – 1\) 本以下に抑える制約を置きます。
式で書くと \(\sum_{i \in S} \sum_{j \in S} x_{i,j} \leq |S| – 1\) です。この制約は、\(S\) に含まれる地点だけで輪を閉じることを禁じ、必ず \(S\) の外へ出る移動が1本以上あることを強制します。同じ条件を、\(S\) の内側から外側へ出る移動が1本以上あるという形で \(\sum_{i \in S} \sum_{j \notin S} x_{i,j} \geq 1\) と書くこともでき、どちらも意味は同じです。
ここからが、この型の性質を決める部分です。この制約は、ある特定の \(S\) について1本書けば済むものではありません。分裂の仕方はいくらでもあり得るため、地点の部分集合すべてについて1本ずつ必要になります。20地点の部分集合は2の20乗通り、およそ105万通りあります。そのうち意味を持たないもの、つまり空集合、1点だけの集合、全体集合を除いても、必要な制約はおよそ105万本です。地点が30か所になると2の30乗でおよそ10億本、40か所なら2の40乗でおよそ1兆本になります。地点が10か所増えるたびに、制約の本数がおよそ1,000倍になる計算です。
この増え方は、第3章で扱った計算量の話とは少し別の種類の困りごとを生みます。計算に時間がかかるという以前に、制約をすべて書き出すこと自体ができません。105万本の制約をメモリ上に展開したモデルは、20地点という小さな規模にもかかわらず、ソルバーに渡す前の段階で扱いにくい大きさになります。定式化の教科書に載っている数式を素直にコードへ写すと、この時点で手が止まります。数式として正しく書けることと、そのまま計算機に渡せることは別だ、という事実がはっきり出るのがこの型です。
ここで使われるのが、制約を最初から全部書かず、必要になった分だけ後から足していく進め方です。手順そのものは単純で、次の繰り返しになります。
この方法を遅延制約生成と呼びます。制約を遅らせて生成する、という意味です。最初に解いた答えには、たいてい複数の小さな輪が現れます。そこで、実際に現れた輪だけを名指しで禁じ、また解きます。禁じられた輪は次からは出てこないので、別の形の分裂が起きるか、1つの輪にまとまるかのどちらかになります。これを繰り返すと、いずれ輪は1つになります。
この進め方が成り立つのは、105万本の制約のうち、実際に効いているのはごく一部だからです。最適解を求める過程で邪魔になる分裂の仕方は限られており、残りの制約は「書いても書かなくても答えが変わらない」ものです。20地点であれば、追加される制約は数本から数十本の範囲に収まるのが通常で、105万本を用意する必要はありません。制約を後から足していく手法は一般に行生成と呼ばれ、部分巡回の禁止はその代表的な適用例です。実務で使う配送計画のモデルが、教科書の数式の見た目ほど巨大にならないのは、この仕組みが働いているためです。
別の書き方もあります。地点ごとに「何番目に訪問するか」を表す連続変数 \(u_i\) を用意し、地点iの次に地点jへ向かうなら \(u_j\) が \(u_i\) より大きくなるように制約を置く方法です。訪問順位が単調に増えていくなら、途中で別の輪に飛ぶことができなくなるため、部分巡回が自動的に排除されます。この形は考案者3名の頭文字を取ってMTZ定式化と呼ばれ、必要な制約の本数は地点数の2乗におさまります。数式を一度書き切ってしまえばそれで済むという利点があり、実装は明らかに楽です。
ただし、この書き方には計算上の弱点があります。整数条件を外した緩和問題(第3章)の答えが、最適解から遠いところに出やすいのです。順位を表す \(u_i\) が小数値を取れてしまうと、部分巡回を禁じる力がほとんど働かなくなるためで、結果として探索が長引きます。制約の本数は少ないのに解くのは遅い、という状態になります。制約が少ないモデルほど速く解けるとは限らないという点は、定式化の設計で覚えておく価値があります。小さな規模で試すならMTZ定式化、規模が大きくなるなら遅延制約生成、という使い分けが実務的な落としどころです。
ここまでは1台のトラックが全件を回る前提でした。実務の配送計画では、車両が複数あり、車両ごとに積める量の上限があり、届け先ごとに受け取れる時間帯が決まっています。この形に拡張したものが配車計画問題(VRP)です。TSPは、車両が1台で積載量の上限も時間の制約もない場合という、VRPの最も単純な場合にあたります。
拡張のしかたは、制約を1種類ずつ足していく形になります。まず複数台への拡張です。決定変数に車両の添字を足して \(x_{i,j,k}\) とし、車両kが地点iの次に地点jへ向かうかどうかを表します。各配送先はいずれか1台の車両がちょうど1回訪問するという条件と、各車両は出発地から出て出発地へ戻るという条件を置きます。車両が3台あれば、出発地から出る移動が3本、戻る移動が3本になります。変数の個数は車両数に比例して増えるため、地点数と車両数の積が、そのままモデルの大きさの目安になります。
次に積載量です。車両kの最大積載量を \(Q_k\)、地点jの荷物量を \(q_j\) として、車両kが訪問する地点の荷物量の合計が \(Q_k\) を超えないという制約を置きます。この制約が入ると、問題の性質が変わります。1台では回りきれない量になるため、「どの配送先をどの車両に割り振るか」という分担の決定と、「その車両がどの順に回るか」という順序の決定が同時に発生します。分担だけなら第7章の割当問題に近く、順序だけならTSPですが、両方が絡むところにこの型の難しさがあります。積み込みの都合で車両ごとに積める品目が違う場合は、その組み合わせを禁じる制約をさらに足します。
時間枠は、到着時刻を変数に取ることで扱えます。地点iへの到着時刻を \(t_i\)、地点iでの荷降ろしにかかる時間を \(s_i\)、地点iから地点jまでの移動時間を \(\tau_{i,j}\) とすると、地点iの次に地点jへ向かう場合には \(t_j \geq t_i + s_i + \tau_{i,j}\) が成り立つ必要があります。この条件は、その移動が選ばれたときだけ有効にしたいので、第5章のbig-M法を使って \(t_j \geq t_i + s_i + \tau_{i,j} – M(1 – x_{i,j})\) と書きます。あとは、受け取り可能な時間帯が午前9時から正午までであれば \(9 \leq t_j \leq 12\) と挟むだけです。ここで使うMは計画対象の1日の長さを取れば足ります。
時間枠を入れた定式化には、副次的な効果があります。到着時刻が移動のたびに増えていくため、途中で別の輪に飛ぶことができなくなり、部分巡回が自動的に排除されるのです。前節のMTZ定式化と同じ理屈が、業務上の意味を持つ変数によって実現されている形になります。時間枠付きの配送計画では、部分巡回を禁じる制約を別途書かなくてよい場合がある、というのは実装上知っておくと役に立ちます。
これらを足していくと、変数の個数も制約の本数も急速に増えます。配送先100か所、車両10台という、業務としてはごく普通の規模でも、移動を表す変数だけで10万個近くになります。この規模を汎用の整数計画ソルバーで厳密に解こうとするのは現実的ではなく、配送計画に特化した解法を備えたツールを使うのが通例です。OR-Toolsのように配車計画向けの機能を持つものがあり、ツールの選び方は第13章で扱います。
配送計画が近年あらためて注目されている背景には、労働時間の規制があります。自動車運転の業務については時間外労働の上限規制の適用が猶予されていましたが、2024年4月から適用が始まり、特別条項付きの36協定を結ぶ場合でも年間の時間外労働の上限は年960時間とされています。一般の労働者に適用される「時間外労働と休日労働の合計を月100時間未満、2か月から6か月の平均で80時間以内とする」規制や、「時間外労働が月45時間を超えられるのは年6か月まで」とする規制は、自動車運転の業務には適用されません。
あわせて、自動車運転者の労働時間等の改善のための基準、いわゆる改善基準告示も2024年4月1日から改正後の内容が適用されています。トラック運転者について定められている主な数値は次のとおりです。1日の拘束時間は始業時刻から起算して24時間について13時間を超えないことを原則とし、延長する場合の限度は15時間とされています。連続運転時間は4時間を超えないものとされ、1年の拘束時間は原則として3,300時間以内、1か月では原則として284時間以内とされています。勤務終了後は継続11時間以上の休息期間を与えるよう努めることを基本とし、継続9時間を下回らないものとされています。ただし、宿泊を伴う長距離貨物運送など一定の条件を満たす場合には、週2回まで拘束時間を16時間まで、休息期間を継続8時間以上までとする例外が設けられています。自社の運行がこの例外に該当するかどうかは、制約として書き下す前に確認しておく必要があります。
これらは、配車計画の定式化の側から見れば、そのまま制約として書き下す対象です。1日の拘束時間の上限は、車両kのルートについて、出発から帰着までの経過時間が上限を超えないという制約になります。連続運転時間の上限は、休憩を挟まずに走り続ける時間を測る変数を置き、上限に達する前に休憩を入れる制約として表します。休憩そのものを、荷物のない訪問先として経路に組み込む書き方もあります。運転時間、荷役時間、待機時間のどこまでを拘束時間として数えるかは業務側の運用と照らして決める必要があり、ここは定式化の担当者が独断で決められる部分ではありません。
規制が制約として入ると、これまで成り立っていた配送計画が実行不可能になる場面が出てきます。1日で回りきれていた件数が回りきれなくなる、あるいは車両を増やさなければ計画が組めなくなる、という形です。ここで数理最適化が果たせる役割は2つあります。1つは、規制を守ったうえで実行可能な計画が存在するかどうかを、担当者の試行錯誤ではなく計算で判定できることです。もう1つは、実行可能な計画が複数あるときに、走行距離や車両台数の観点で良いものを選べることです。規制の遵守そのものは最適化で実現できるものではありませんが、遵守を前提にした計画づくりの負荷は、定式化によって確実に下げられます。
配送計画は、厳密な最適解にこだわらない判断が正当化されやすい領域です。理由は3つあります。
1つ目は、計画を出さなければならない時刻が決まっていることです。前日の受注が締め切られてから翌朝の出発までに使える時間は限られており、その間に計画が出なければ、どれほど良い解であっても業務上の価値はありません。第3章で触れたとおり、厳密解法で手が出ない規模に対して実用に耐える答えを短時間で返すのがヒューリスティクスの役割であり、配送計画はその典型的な適用先です。
2つ目は、入力データ自体に誤差があることです。地点間の距離や所要時間は、道路状況や時間帯によって変動します。ある日の実測値をもとに計算した最適解が、翌日にも最適である保証はありません。厳密解と、それより総距離が1%長い解があったとして、その差は所要時間の見積もり誤差に埋もれます。データの精度を超えた精密さを解に求めても、業務上の意味は増えません。
3つ目は、実行可能な解を1つ作ること自体が難しい場合があることです。時間枠、積載量、労働時間の制約がすべて入った問題では、条件をすべて満たす計画を見つけるだけでも手間がかかります。この段階では、最適性を議論する前に、まず条件を満たす計画を作ることが目標になります。近くの地点から順につないでいく方法などで初期の計画を作り、経路の一部を入れ替えて総距離が縮むなら採用する、という改善を繰り返す進め方が実務では広く使われます。
ヒューリスティクスを採用する場合は、解の品質をどう説明するかを設計に含める必要があります。よく使われるのは、計算時間の上限をあらかじめ決めておき、その時点での最良解を採用する運用です。あわせて、整数条件を外した緩和問題を解いて得られる下界と比較すれば、「今の解は理論上の限界からこの程度の範囲に収まっている」という形で品質を数値化できます。関係者に対して「最適です」と言えない代わりに、「最適との差はこの範囲に収まっています」と言えるようにしておくことが、運用を継続させるうえで効きます。
定式化が正しくても、それだけで配送計画が回るわけではありません。この型で特に負荷が大きいのは、距離と所要時間のデータです。直線距離では実務に耐えず、道路網に沿った実距離と所要時間が必要になります。地点数が100であれば、地点間の組み合わせは1万近くあり、これを地図サービスから取得して更新し続ける仕組みが要ります。行きと帰りで所要時間が違う一方通行や右左折の制約も、正しく反映するなら \(d_{i,j}\) と \(d_{j,i}\) を別の値として持たなければなりません。この非対称性を無視すると、計算上は最短でも現場では走れない経路が出てきます。
住所から座標への変換も、精度を確認しておく必要がある工程です。同じ建物でも入口が複数ある、大規模施設は敷地の中心と搬入口が離れている、といった事情は距離の計算に直接効きます。配送先マスタの住所表記が揺れていると変換に失敗し、その地点だけ距離が異常な値になって、経路全体が不自然な形になります。計画がおかしいときに定式化を疑う前に、まず入力データを確認するほうが早い場合が多いといえます。
もう1つは、数式に載っていない条件の扱いです。荷台の奥に積んだ荷物は先に降ろせないため、積み付けの順序が訪問順序を縛ることがあります。特定のドライバーしか入れない納品先、車両の大きさで進入できない道、届け先との個別の取り決めといった条件も現場には存在します。これらをすべて制約として書こうとすると、モデルは急速に重くなります。実務では、計画の骨格を計算で作り、細部は担当者が手直しできる形にしておく設計が現実的です。計算結果を修正不可の指示として出すのではなく、修正の余地を残した計画案として出すほうが、現場に受け入れられやすくなります。
効果の測り方も、あらかじめ決めておきます。総走行距離、車両の稼働台数、計画作成にかかる時間、時間枠を守れた割合といった指標を、導入前の実績と比べられる形にしておきます。特に計画作成時間は、配車担当者の負荷が直接減る部分であり、走行距離の削減額よりも先に効果として現れることがあります。担当者の経験に依存していた判断の一部が計算に置き換わることで、担当者が不在でも一定水準の計画が出せるようになる点も、継続的な効果として評価に含めてよい部分です。

次章では、ここまでの定式化をPythonのコードとして動かす方法を扱います。
『メタヒューリスティクスの数理』(久保幹雄、J.P.ペドロソ、共立出版):この章で扱った、厳密解を諦めて良い解を短時間で得るという方針を、手法の側から体系的に確認できる一冊です。巡回セールスマン問題や配車計画問題は、この分野で繰り返し題材にされてきた対象でもあるため、初期解の作り方と改善の繰り返し方を具体的にたどりたい方に向いています。
定式化を書き上げたあとに待っているのは、それを計算機に解かせて答えを取り出す工程です。ここは業務課題そのものではなく、業務課題を扱うための作業環境をどう用意するかという問題になります。どのライブラリを使うのか、ソルバーに費用はかかるのか、答えが返ってこなかったときに誰がどう調べるのか。この3点が決まっていないと、定式化が正しくても検証が進まず、プロジェクトが机上の議論から先に出ません。
この工程は、決まった型に落とし込んで進めるというより、道具立ての理解と手順の整備で決まります。無料の道具だけで検証を終えられる範囲は年々広がっており、費用の判断を先送りしたまま着手できます。一方で、答えが返ってこないときの切り分けは経験に依存しやすく、ここを手順として持っているかどうかが、実務での進み方をはっきり分けます。この章では、コードに落とす作業の実際と、詰まったときの調べ方を扱います。
最初に押さえておきたいのは、Pythonから最適化を扱うときに登場する道具が2層に分かれているという点です。上の層が、決定変数と目的関数と制約を書き下すためのモデリングライブラリ、下の層が、書き下された問題を実際に探索して答えを出すソルバーです。両者は別の製品であり、別々に選べます。
この分離は、実務では調達の面で効いてきます。モデリングライブラリの記法でモデルを書いておけば、下のソルバーだけを差し替えられるためです。検証段階は無料のソルバーで進め、規模が大きくなって計算時間が問題になった段階で商用ソルバーの評価に移る、という進め方が取れます。このとき書き直しが必要になるのはソルバーを呼び出す1行程度で、モデルの本体には手を入れずに済みます。最初から高価なソルバーを買う判断を迫られる構造ではない、ということです。
Pythonで最初に手を付けるモデリングライブラリとしてはPuLPが扱いやすい選択肢です。数式とほぼ同じ形でモデルを記述でき、コードを読み返したときに元の定式化との対応を追えます。MITライセンスで公開されているため、社内利用の可否をライセンス面から検討する手間もかかりません。
2つの層をつないでいるのは、問題そのものを記述したファイル形式です。モデリングライブラリは、書き下されたモデルをLP形式やMPS形式といった標準的な形式に変換し、それをソルバーに渡します。この形式が共通しているために、上と下を自由に組み合わせられます。実務では、この受け渡しの仕組みを知っているかどうかが検証の速度に効いてきます。ソルバーが妙な答えを返したときに、渡されたファイルを開けば、実際にソルバーが受け取った問題そのものを式の形で読めるためです。コードを追いかけて原因を探すより、渡した中身を直接見るほうが速い場面は少なくありません。
例題:施策選定のモデルをコードにする
定式化を書いたら、小さな規模でよいので実際に解いてみることをおすすめします。題材には第11章の施策選定を使います。施策候補が5件あり、費用は順に400万円、300万円、250万円、200万円、150万円、期待効果は順に500万円、420万円、300万円、290万円、180万円、予算の上限は700万円という設定です。この問題を、費用対効果の高い順に選ぶ貪欲法との比較も含めて解いたコードが次のものです。動作はPuLP 3.3で確認しました。
import pulp
costs = [400, 300, 250, 200, 150] # 施策ごとの費用(万円)
effects = [500, 420, 300, 290, 180] # 施策ごとの期待効果(万円)
budget = 700
items = range(len(costs))
knapsack_model = pulp.LpProblem("zero_one_knapsack", pulp.LpMaximize)
# 施策を採用するなら1、採用しないなら0を取る決定変数
selected = [pulp.LpVariable(f"select_{i + 1}", cat="Binary") for i in items]
# 目的関数: 期待効果の合計を最大化
knapsack_model += pulp.lpSum(effects[i] * selected[i] for i in items)
# 制約: 費用の合計は予算以下
knapsack_model += pulp.lpSum(costs[i] * selected[i] for i in items) <= budget
knapsack_model.solve(pulp.PULP_CBC_CMD(msg=False))
optimal_items = [i + 1 for i in items if pulp.value(selected[i]) > 0.5]
optimal_cost = sum(costs[i - 1] for i in optimal_items)
optimal_effect = sum(effects[i - 1] for i in optimal_items)
# 比較用: 効果を費用で割った値が高い順に、予算に入るだけ詰める貪欲法
greedy_items = []
greedy_cost = 0
greedy_effect = 0
for i in sorted(items, key=lambda j: effects[j] / costs[j], reverse=True):
if greedy_cost + costs[i] <= budget:
greedy_items.append(i + 1)
greedy_cost += costs[i]
greedy_effect += effects[i]
optimal_label = " + ".join(f"施策{i}" for i in optimal_items)
greedy_label = " + ".join(f"施策{i}" for i in sorted(greedy_items))
print(f"厳密解: {optimal_label}(費用{optimal_cost}万円・効果{optimal_effect}万円)")
print(f"貪欲法: {greedy_label}(費用{greedy_cost}万円・効果{greedy_effect}万円)")
実行結果は次のとおりです。
厳密解: 施策1 + 施策2(費用700万円・効果920万円)
貪欲法: 施策2 + 施策4 + 施策5(費用650万円・効果890万円)
数式との対応関係を見ておきます。LpVariable の cat="Binary" が0か1を取る変数の宣言、最初の knapsack_model += が目的関数、2つ目の knapsack_model += が予算制約です。定式化の3点セットが、そのままコードの3か所に対応しています。定式化さえ固まれば、コードに落とす工程は機械的な作業になるということです。
行数にすると30行ほどで、そのうち最適化に固有の記述は10行に満たない量です。プロジェクトの工数を見積もるときに、この部分を厚く見積もる必要はありません。時間がかかるのは、この10行に入れる係数を業務データから作る工程と、書くべき制約を現場から引き出す工程です。厳密解と貪欲法の差がなぜ生じるのかは第11章で扱っています。
なお、PuLPに同梱されるソルバーの扱いは版によって変わります。上のコードはPuLP 3.3で確認したものですので、導入手順と利用できるソルバーの指定方法は、実際に使う版の公式ドキュメントで確認してください。
このコードでは費用と期待効果をリストに直接書き込んでいますが、実務ではここが業務システムから取り込むデータになります。書き方として大事なのは、モデルの構造とデータを分けておくことです。上のコードでいえば、costs と effects と budget を外から与える形にしておけば、施策が5件から50件に増えてもモデルの記述は1文字も変わりません。逆に、係数を式の中に直接書き込む書き方をすると、データを差し替えるたびにモデル本体に手を入れることになり、そのたびに添字のずれや書き漏らしが混入します。定式化の内容が正しくても、この分離ができていないと運用に乗せた段階で保守が破綻します。
コードが動いて何らかの数値が返ってきても、それが書いたつもりのモデルの答えである保証はありません。プログラムとしては正しく動きながら、意図と違う問題を解いているという状態が起こり得ます。この食い違いは、答えを見ているだけでは気づけません。確認の手立てを持っておく必要があります。
最も手軽なのが、変数と制約の個数を数えることです。施策5件の問題であれば変数は5個、制約は1本のはずで、この数が想定と合わなければ添字の範囲かループの書き方が違っています。スタッフ50人と30日と3区分で組んだモデルの変数が4,500個にならなければ、どこかで組み合わせを取りこぼしています。数式を書いた時点で個数は計算できますので、コードを走らせる前に期待値を紙に書いておくと照合が早く済みます。
次に有効なのが、モデルをファイルに書き出して読むことです。PuLPには、組み上げたモデルをLP形式のファイルとして出力する機能があります。出力されたファイルには目的関数と全制約が式の形で並んでおり、係数が意図した値になっているか、書いたつもりの制約が実際に入っているかを目で確認できます。規模が大きい場合は全部を読む必要はなく、代表的な数本を抜き出して確かめれば十分です。
そして、答え合わせのできる小さなデータを用意しておくことです。手計算で最適解が分かる規模まで問題を縮め、その答えとソルバーの出力が一致することを確かめます。この章の例題は、5件の組み合わせを全て数え上げれば人手で検算できる規模であり、この用途に向いています。実データに差し替えたあとで結果がおかしくなったとき、小さいデータに戻して再現するかどうかを見れば、原因がモデルにあるのかデータにあるのかをすぐに切り分けられます。
定式化ができれば、あとはソルバーに渡すだけです。無料で始められる選択肢も充実しています。
| ツール | 種別 | 特徴 |
|---|---|---|
| PuLP | モデリングライブラリ(無料) | LPとMIPを数式に近い形で記述できる。既定でCBCソルバーが同梱され、導入直後から動く |
| OR-Tools | ライブラリ+ソルバー(無料) | Googleが開発。制約プログラミングのCP-SATはスケジューリングに強く、配車計画には専用のルーティング機能がある |
| HiGHS | ソルバー(無料) | エディンバラ大学で開発。SciPyの linprog と milp のバックエンドとして採用されており、SciPyが入っていれば実質的に利用できる |
| SciPy | 科学計算ライブラリ(無料) | データ分析で既に導入済みのことが多い。linprog でLP、milp でMIPを扱える。行列と配列で問題を渡す書き方になる |
| Gurobi、CPLEXなど | 商用ソルバー | 大規模問題での速度と安定性が際立つ。Gurobiは2024年11月に12.0、2025年11月に13.0を公開している |
| Nuorium Optimizer | 商用ソルバー(国内開発) | NTTデータ数理システムが開発・販売。日本語のドキュメントとサポートが得られる |
近年の動きとして、無料のソルバーの裾野が広がったことが挙げられます。SciPyで線形計画を解く scipy.optimize.linprog は既定でHiGHSを使う仕様になっており、混合整数計画を解く scipy.optimize.milp もHiGHSのラッパーとして提供されています。SciPyが導入済みの環境であれば、別途ソルバーを用意せずに整数計画まで解けるということです。HiGHSはMITライセンス、OR-ToolsはApache 2.0ライセンスで公開されており、いずれも社内利用にあたっての制約は緩やかです。大規模で難しい問題では商用ソルバーとの差が依然として大きいものの、定式化の検証や中規模の実務課題であれば、無料の範囲で十分に検討を進められます。
選び方の順序としては、まずPuLPで小さく書いて動かし、答えの形が業務の感覚と合うかを確かめるところから始めるのが確実です。ここで詰まる原因のほとんどは制約の書き漏れであり、ソルバーの性能ではありません。規模を実データに近づけて計算時間が問題になってきた段階で、はじめてソルバーの選択が論点になります。スケジューリングのように0か1を取る変数が大量に出る問題であればOR-ToolsのCP-SATが有力な候補になり、大規模なLPやMIPであればHiGHSや商用ソルバーの評価に進みます。この順序を飛ばして最初にソルバーを選定しにいくと、そもそも解くべき問題が固まっていない状態で製品比較の議論に入ることになり、判断の基準が作れません。
コードを書いて実行すると、何かしらの結果が返ってきます。ここで最初に確認すべきなのは変数の値ではなく、ソルバーが返した状態です。最適解が見つかったのか、条件を満たす解が存在しないと判定されたのか、時間切れで打ち切られたのかによって、その後の変数の値が持つ意味がまったく変わります。
PuLPであれば、解いたあとの model.status を pulp.LpStatus で文字列に直すと、Optimal、Infeasible、Unbounded、Undefined、Not Solved のいずれかが得られます。SciPyの linprog と milp は整数の状態コードを返し、0が最適解、1が反復回数または時間の上限に到達、2が実行不可能、3が非有界、4がその他という対応です。OR-ToolsのCP-SATは、OPTIMAL、FEASIBLE、INFEASIBLE、MODEL_INVALID、UNKNOWN を返します。FEASIBLE は条件を満たす解は見つかったが最適である保証はない状態、UNKNOWN は時間や資源の上限で打ち切られた状態を指します。
状態を確認せずに変数の値だけを取り出す実装は、実務で最も危険な作り込みの1つです。実行不可能と判定されたあとの変数には意味のある値が入っておらず、それをそのまま計画として出力すれば、制約を破った計画が現場に流れます。運用に乗せるプログラムでは、状態が最適でなければ処理を止めて担当者に通知する分岐を必ず入れておきます。時間切れで打ち切った解を採用してよいかどうかは業務判断であり、プログラムが黙って決めてよいことではありません。
ソルバーが実行不可能と返してきたとき、返ってくる情報は「条件を同時に満たす解が存在しない」という事実だけです。どの制約が原因なのかは教えてくれません。ここで手が止まる例は多く、切り分けを手順として持っているかどうかが、検証の速度をはっきり分けます。
切り分けは、次の順に進めるのが効率的です。上の段ほど原因である頻度が高く、確認にかかる時間も短いためです。
この手順に加えて、第5章で触れたとおり、疑わしい制約を違反量つきの形に書き換えて解き直す方法もあります。違反量の変数がどの制約でいくつになったかを見れば、原因の場所と不足の量が同時に分かります。切り分けの終盤で使うと効果が大きい方法です。
商用ソルバーには、この作業を支援する機能が用意されています。Gurobiには、それ以上小さくできない矛盾した制約の部分集合を計算する機能があります。ここで返される部分集合は、その中の制約を1本でも取り除けば矛盾が解消するという性質を持つため、原因の候補をごく狭い範囲に絞り込めます。ただし、返される部分集合は必ずしも最小の要素数を持つものではなく、複数存在する候補の1つである点には注意が必要です。また、この計算はLPでは比較的軽い一方、MIPでは重くなることが公式ドキュメントに明記されています。無料のソルバーにこの機能がないことは、商用ソルバーを検討する理由の1つになります。
実務で頻出する原因を、症状と確認方法の形で整理しておきます。
| 疑う原因 | 起きていること | 確認方法 |
|---|---|---|
| 需給の総量が合わない | 需要の合計が供給の合計を超えている | 制約に入れる前の生データで合計を突き合わせる |
| 上限と下限の逆転 | 同じ変数に矛盾する範囲が課されている | 変数ごとに下限と上限を並べて比較する |
| 単位の不一致 | 係数の桁が1,000倍ずれている | 係数の最大値と最小値の桁を一覧する |
| 期首在庫や初期条件の欠落 | 最初の期に使える量がゼロになっている | 1期分だけの問題に縮めて解いてみる |
| 添字のずれ | 制約が意図しない組み合わせに掛かっている | 制約の本数が想定どおりかを数える |
| 等号で書きすぎている | ちょうど一致することを求めた制約が両立しない | 等号を不等号に緩めて解き直す |
| Mが小さすぎる | 成立するはずの条件が締め付けられている | 該当する変数の実際の上限とMを見比べる |
最後に、実行不可能という結果そのものが誤りとは限らない点を押さえておく必要があります。データもモデルも正しく、そのうえで業務側が示した条件が本当に両立しない場合があります。必要人数を満たすには人が足りない、納期を守るには設備能力が足りない、という状況です。このとき出すべき答えは「計算できませんでした」ではなく、「この条件では計画が作れません。あと何人、あるいはあと何時間あれば作れます」という形の報告です。どの条件をどれだけ緩めれば成立するのかを数値で示せることは、最適化を導入する価値の1つでもあります。実行不可能を単なるエラーとして扱わず、業務側への問いとして返す設計にしておくことをおすすめします。
非有界は、目的関数を良くする方向に変数をいくらでも動かせてしまう状態です。利益を最大化する問題で、利益が無限に増やせると判定されたということになります。実行不可能とは性質が異なり、こちらは現実の業務では起こり得ません。したがって非有界が返ってきたときは、業務側の条件を疑うのではなく、モデルの記述を疑います。
疑うべき箇所は限られています。第一に、資源の上限を表す制約の書き忘れです。設備時間、原料、予算、人員のうち、どれかの上限を書き落とすと、その資源を無限に使う解が成り立ってしまいます。第二に、変数の下限の指定漏れです。非負であるべき変数に下限を付け忘れると、マイナスの生産量や負の輸送量で目的関数を改善する解が現れます。第三に、目的関数の符号や向きの誤りです。最小化すべき費用を最大化に設定していた、コストの係数を正負逆に入れていた、といった単純な取り違えがこれにあたります。
実務的な予防策として、すべての変数に業務上あり得る上限をあらかじめ付けておく方法があります。生産量なら設備能力から計算できる最大値、輸送量なら在庫量、金額なら予算総額です。上限を付けておけば、本来なら非有界になる誤りが「上限に張り付いた解」として現れます。生産量がぴったり上限値になっている変数を探せば、書き忘れた制約の場所がすぐに見つかります。非有界というメッセージだけを頼りに探すより、はるかに速く原因にたどり着けます。
もう1つ、実行不可能とも非有界とも判定されず、いつまでも計算が終わらないという状態もあります。これはモデルの誤りではなく、探索が終わらないという計算量の問題です。この場合は解の質と計算時間のどちらを優先するかという判断になり、許容できる打ち切りの基準を先に決めておくことが対処になります。この考え方は第3章で扱っています。

もう一つの動きが、大規模言語モデルによる定式化の支援です。自然言語で書かれた問題文からMIPのモデルとソルバー用コードを生成する研究が2023年以降活発になっており、複数のエージェントを役割分担させてモデル化、コード生成、デバッグ、評価を順に行う仕組みが提案されています。商用側でも、問題の説明文からモデルとコードを起こす支援ツールが提供されるようになりました。
ただし、これらは定式化の工程を丸ごと置き換えるものではありません。研究の側でも、生成されたモデルに現実には存在しない制約が混入したり、逆に必要な制約が抜け落ちたりする問題が課題として挙げられています。加えて、第1章の事例が示すように、実務の難所は数式の書き方ではなく、現場に暗黙知として存在する制約を引き出して言語化する部分にあり、この工程は入力となる文章がなければ始まりません。大規模言語モデルが効くのは、言語化された条件を数式とコードに変換する後半の工程であり、その前段の設計は引き続き人の仕事だと考えています。
現時点での使いどころとしては、書き上げた定式化をコードに変換する作業、既存のコードを別のライブラリの記法に書き換える作業、そしてこの章で扱った切り分けの補助が挙げられます。いずれも、正しさを人が検証できる工程です。逆に、業務要件の文章をそのまま渡してモデルを丸ごと生成させ、出てきた答えを検証せずに使うという進め方は勧められません。生成されたモデルに制約が1本足りなくても、ソルバーは何事もなかったように答えを返してくるためです。この章で述べた状態の確認と切り分けの手順は、生成されたコードを使う場合にも同じように必要になります。
次章では、定式化をプロジェクトとして進め、運用に定着させる進め方を扱います。
『Pythonで学ぶ数理最適化による問題解決入門』(株式会社ビープラウド、PyQチーム、斎藤努、翔泳社):この章で扱ったコードへの落とし込みを、演習を通して手を動かしながら身につけられる一冊です。定式化からコード、そして結果の解釈までを一続きの作業として練習したい方に向いています。
定式化したモデルを業務で使い続けることは、モデルを1つ書き上げることとは別の仕事です。試作の段階であれば、担当者がその場で数式を直しながら答えを出せます。しかし毎週の計画作成に組み込まれた後は、条件が変わるたびに誰かが手を入れ、出てきた答えを別の人が現場に説明し、実行した結果が翌月のデータとして戻ってきます。この循環が回らないモデルは、精度の問題ではなく運用の問題で使われなくなります。
この章で扱うのは、個別の問題の型ではなく、定式化を1つのプロジェクトとして進め、業務に定着させるまでの進め方です。第2章から第13章までで扱ったのは、いずれも「モデルをどう書くか」に関する内容でした。ここで扱うのは、そのモデルを誰と作り、何を根拠に手法を決め、どうやって運用に引き渡すかという判断になります。
実際にプロジェクトで定式化を進める際に、判断が必要になる場面を4つ挙げます。いずれも、後回しにすると手戻りが大きくなる種類の判断です。
この確認を最初に置く理由は、答えがプロジェクトの見積もりをほぼ決めてしまうからです。第3章で扱ったとおり、解ける規模と計算時間は問題の型によって桁で変わります。線形の枠に収まるなら、無償のソルバーで十分な規模まで扱え、答えが最適であることの裏付けも得られます。非線形のまま進めるなら、使える道具が限られるうえ、得られた解が全体で最良のものかどうかを保証できない場合があり、結果を関係者に説明する難易度も上がります。着手前の工数見積もりと体制の判断が、この一点に依存します。
手順としては、現場から聞き取った条件を日本語で書き出した段階で、非線形になりそうな項目に印を付けていきます。比率や割合で書かれた条件、変数どうしを掛け合わせる形になる条件、数量によって単価が変わる料金体系、いちばん悪い値を良くしたいという要望などが該当します。印を付けた項目それぞれについて、第5章の書き換えの技法で線形の形に置けないかを確かめます。多くの場合、補助変数を足して不等式を数本並べるだけで枠内に収まります。
ここで注意が必要なのは、線形に落とすために業務条件のほうを単純化してよいかという判断です。段階的な単価を平均単価で置き換える、細かい例外運用を無視する、といった簡略化は、モデルを軽くする代わりに現実との差を生みます。この判断は分析側だけで決めるものではありません。どこまで丸めてよいかを業務側に確認し、丸めたのであれば「この条件は近似して扱っている」と仕様に明記します。記録が残っていないと、運用が始まってから答えが現場の感覚と合わない原因を追えなくなります。
逆に、どうしても線形に収まらない条件が業務の本質にある場合もあります。その場合は、線形に落ちる部分だけで最初のモデルを作り、非線形の要素は計算の外側で扱う進め方が現実的です。全体を一度に解こうとして着手が遅れるより、範囲を絞って動くものを先に出したほうが、次に何を足すべきかの議論が具体的になります。
big-M法のMをできる限り小さく取る理由は第5章で扱いました。プロジェクトの運営として重要なのは、Mが技術的な定数ではなくデータの一部であるという点です。在庫であれば倉庫容量、生産量であれば設備能力、金額であれば予算上限というように、Mの根拠になる数値はどこかのマスタや台帳に存在します。設計時に「このMはどの数値を参照するのか」を1つずつ決め、参照元が更新されたらMも追随する形にしておきます。
実装の都合で十分に大きな固定値をそのまま書き込むと、後任の担当者がその数字の意味を追えなくなります。計算時間が悪化したときに原因の候補を絞れなくなり、値を小さくしてよいかどうかの判断もできません。モデルのレビューでは、登場するMを一覧にして「これは何の上限か」を確認する工程を入れておくと、この種の負債が残りにくくなります。
参照できる上限がマスタに存在しない場合は、実績データの最大値に余裕を見た値を置き、その決め方を記録に残します。実績が増えて上限を超える見込みが出てきたときに、どこを直せばよいかが分かる状態にしておくことが目的です。
第2章では、制約を種類別に洗い出す手順を扱いました。ここで挙げるのは、それより粗い2列の整理です。満たすべき需要と、使える資源の2つに分けて並べます。粗い分け方をあえて併用するのは、抜けの発見に効くためです。片方の列だけが厚く、もう片方がほとんど書かれていないという状態は、聞き取りが一方の部門に偏っているか、資源側の上限が誰にも把握されていないことを示します。
それぞれの行には、数値の根拠を併記します。需要側であれば、顧客との契約で決まった水準なのか、社内で置いている目標値なのか、法令で定められた基準なのかで、守り方の硬さが変わります。供給側であれば、設備能力が公称値なのか実測値なのか、人員が名簿上の人数なのか実働可能な人数なのかで、モデルが出す答えの現実味が変わります。根拠の欄が空のまま残っている行は、後から必ず議論になります。
両側を並べる利点は、計算する前に見立てが立つことです。総需要と総供給を突き合わせるだけで、そもそも条件を同時に満たす計画が存在しうるのかがおおよそ分かります。資源が明らかに足りていないなら、モデルを解いても解は返りません。その場合に必要なのは定式化の修正ではなく、資源を増やすか需要側の水準を下げるかという業務の判断です。この確認を設計段階で済ませておくと、運用に入ってからの混乱が減ります。
洗い出しで抜けやすいのは、供給側の目に見えない消費です。段取り替えや切り替えに要する時間、休憩、点検、教育の時間、承認待ちの期間などは、資源を確実に消費しているにもかかわらず、能力の数字には含まれていないことがあります。部門をまたいで共有している設備や人員も同様で、片方の部門へのヒアリングだけでは、もう一方が同じ資源を使っている事実が出てきません。共有資源については、使う側すべてを関係者に含めて確認します。
この判断の材料になるのは、実行の頻度、1回の意思決定が動かす金額の規模、答えを出すまでに許される時間の3つです。毎日の配車計画のように、翌朝までに必ず答えが必要な業務では、最後の数パーセントの改善よりも、締切までに使える計画が返ってくることのほうが価値を持ちます。年に一度の設備投資判断のように、金額が大きく検討期間も長い意思決定では、時間をかけて最良の答えを求め、その根拠を残す価値があります。
中間の位置づけになる業務では、計算の打ち切り時間をあらかじめ決め、その時点で得られている最良の解を採用する運用にします。このとき、得られた解が最良の可能性からどの程度離れているかの目安も併せて出す形にしておくと、業務側が採否を判断できます。打ち切り時間の設定は業務の締切から逆算して決めるものであり、技術的な都合で決めるものではありません。
この判断は、関係者との合意事項として扱う必要があります。最適化という言葉は、常に最良の答えが得られるという期待を作りやすいものです。良い解で運用する方針を採るのであれば、その方針と理由をプロジェクトの早い段階で共有しておきます。運用が始まってから「これは最適ではないのか」と問われて説明に追われる状況は、モデルへの信頼を損ないます。逆に、方針が共有されていれば、計算時間を延ばして精度を取るか、締切を優先するかという調整も業務側と一緒に行えます。
頻度の観点をもう一段進めると、そもそも同じモデルを毎日回すのか、条件を変えて何度も試算するのかという使い方の違いも設計に効きます。試算を繰り返す使い方であれば、1回の計算が数十分かかるモデルは事実上使われません。誰がどんな頻度で操作するのかを想定して、許される計算時間を決めます。
運用に乗せる段階では、解が出なかったときにどうするかを必ず設計に含めます。実行不可能と判定されたときに、どの制約が原因かを担当者が特定できる仕組みがないと、システムは使われなくなります。制約に優先順位を付け、下位の制約から順にソフト制約へ切り替えて再計算する、といった作り込みが現場での定着を左右します。切り替えの仕組みそのものは第5章で、原因を技術的に切り分ける手順は第13章で扱っています。
運用設計として決めておくべきことは、優先順位を誰が決めるかです。どの条件なら譲れるのかは業務の判断であり、分析側が決めるものではありません。制約の一覧に「絶対に守る」か「譲れる」かの列を持たせ、譲れる側については譲る順番まで業務側と合意しておきます。この順番が決まっていれば、解が出なかったときの再計算は自動で進められます。
緩和して解が得られた場合には、どの条件をどれだけ緩めたのかを結果と一緒に表示します。担当者はその情報をもとに現場へ説明でき、上位者への報告もできます。数値だけが返ってきて、なぜ通常と違う計画になったのかを誰も説明できない状態が続くと、担当者はモデルを使わずに手作業へ戻ります。
あわせて、それでも解が得られなかった場合の代替手順も決めておきます。誰に連絡するのか、締切までに何を出すのか、前回の計画を流用して手で修正するのか、といった段取りです。年に数回しか起きない事態であっても、その1回で運用が止まると、モデルは信頼されなくなります。
定式化が固まってからデータを集め始めると、決定変数の粒度に合うデータが存在しないという問題に高い確率で突き当たります。品目単位でしか管理されていないマスタに対して、モデルは製造ラインごとの能力を要求する、拠点単位の実績しかないところへ、モデルは配送先ごとの数量を要求する、といった食い違いです。この場合の選択肢は、マスタの粒度を細かくするか、モデルの粒度を粗くするかのどちらかで、いずれも工数がかかります。着手前に確認しておく価値があるのはこのためです。
実績データについては、欠測と異常値の扱いを先に決めます。特に注意が要るのは、例外的な運用を行った日のデータです。設備の故障、大口の特注、繁忙期の特別体制といった条件下の実績をそのまま平均に含めると、通常時の計画に合わない数値が入り込みます。除外するのか、別扱いの条件として明示的にモデルへ組み込むのかを、業務側と決めておきます。第2章で挙げた検算、つまり過去の実績が書き出した制約を満たすかどうかの確認を行うと、この種のデータ側の問題も同時に表面化します。
運用の観点では、データの鮮度と受け渡しの段取りが決め手になります。毎週モデルを動かすのであれば、入力データも毎週決まった時刻までに決まった形式で揃っている必要があります。誰が、いつまでに、どこへ置くのかを決め、可能な限り自動で連携させます。ここに手作業が残ると、担当者が忙しい週から順に運用が止まります。
更新の権限が別部門にあるマスタを使う場合は、その部門をプロジェクトの関係者に含めます。データの持ち主が事情を知らないまま項目の定義が変わり、モデルが静かにおかしな答えを返し始めるという事態を避けるためです。
定式化のプロジェクトが必要とする情報は、1つの部署には集まっていません。制約と例外運用を知っているのは現場、データの所在と既存システムの仕組みを知っているのは情報システム、モデルを書いて解くのは分析の担当です。三者のうちどれが欠けても、成果物が業務で使われる状態には届きません。
| 担当 | 主に持っている情報 | プロジェクトでの役割 | 欠けたときに起きること |
|---|---|---|---|
| 現場の業務部門 | 制約、例外運用、判断の基準 | 条件の提供と、出てきた計画の受け入れ判断 | 現実には実行できない計画が最適解として出る |
| 情報システム | データの所在と更新の仕組み、既存システムとの接続 | 入力データの供給と、業務システムへの組み込み | 試算はできても運用に乗らず、手作業が残る |
| 分析の担当 | 定式化と求解、結果の検証 | モデルの作成、検証、保守 | 業務の条件が数式に翻訳されないまま止まる |
小規模な取り組みでは、1人が複数の役割を兼ねることもあります。その場合でも、三者の視点が抜けていないかを確認する形でこの区分を使います。とくに現場の視点は、分析の担当が代弁できるものではありません。
もう1つ決めておくべきなのは、目的関数を最終判定する人です。第2章で扱ったとおり、何をもって良い計画とするかは業務判断であり、この判断を下せる人が特定されていないと目的関数が定まりません。複数の指標のどれを優先するかで意見が割れたときに、決められる立場の人がいるかどうかで、プロジェクトの進み方は大きく変わります。
外部の支援を受ける場合も、制約の合意と運用後の保守については社内に担当を残します。モデルの中身を説明できる人が社内にいない状態は、条件が変わった瞬間に運用が止まる状態と同じです。
第2章では、3点セットを埋めるためにどのような設問を使うかを扱いました。ここで扱うのは、その設問をどう使うか、つまり聞き取りを業務としてどう進めるかです。熟練者の判断を数式に落とす作業では、聞き方と進め方そのものが成果を左右します。
まず、対象者を1人に絞らないことです。熟練の担当者は判断の質が高い一方で、自分が何を見て決めているのかを手順として説明できないことが少なくありません。経験の浅い担当者は判断そのものは未熟でも、どこで迷い、何を先輩に確認しているかを具体的に語れます。両方に同じ業務の進め方を聞くと、その差分が、熟練者が無意識に使っている判断基準として浮かび上がります。
次に、聞く場所と使う資料です。会議室で口頭のみのやり取りにすると、説明しやすいところだけが語られます。実際に使っている帳票や表計算のファイル、業務システムの画面を開いてもらい、直近の計画を作った手順をその場でたどってもらう形にします。手が動く順番が実際の手順であり、口頭の説明よりも正確な情報になります。参照している数字がどのファイルのどの列にあるかも、この場で確認できます。
回数についても、1回で終わらせない前提で組みます。第2章のとおり書き出しと確認を往復させるわけですが、2回目以降は、こちらが日本語で書いた条件の一覧を読み上げて、誤りを指摘してもらう形にすると情報が出やすくなります。何もない状態から思い出して語ってもらうより、書かれたものを見て「これは違う」「この場合は例外がある」と反応してもらうほうが、記憶に埋もれていた条件が表に出ます。
聞き取りで最も重要な答えは「そのときによる」です。この一言の背後に、明文化されていない判断基準があります。ここで止めずに、直近の具体的な事例を3件ほど挙げてもらい、それぞれで何が違ったのかを1つずつ確認します。「大口の顧客だったから」「翌日が休みだったから」「担当者の手が空いていたから」といった説明が出てくれば、それは制約や目的関数の項の候補です。抽象的な原則を尋ねるより、具体的な事例の差分をたどるほうが確実に引き出せます。
複数の人に聞くと、条件が食い違うことがあります。その場でどちらが正しいかを決めようとせず、両方を記録して持ち帰ります。食い違いそのものが、業務のルールが定まっていない箇所を示す情報です。後日、決定権を持つ人に判定してもらい、その判定を記録します。この作業は定式化の副産物ですが、業務の標準化としての価値が高い部分でもあります。
記録は、モデルとは別の成果物として残します。制約の一覧を1つの表にまとめ、各行に次の情報を持たせます。
この一覧は、定式化の入力になるだけでなく、担当者が交代したときの引き継ぎ資料になり、業務改善の検討材料にもなります。条件を文書にした時点で、その業務の判断基準は個人の頭の中から組織の資産に移ります。モデルが将来作り直されたとしても、この一覧は使い続けられます。定式化のプロジェクトが業務に残すもののうち、最も寿命が長いのはこの部分です。
効果の測り方は、プロジェクトの着手前に決めておきます。導入後に決めると、都合の良い比較の仕方を選んでしまう余地が残り、社内での説明力が落ちます。
比較の基本形は、同じ期間の同じ条件に対して、従来のやり方で作った計画と、モデルが作った計画を並べることです。しばらくの間は両方を作る並行運用の期間を設けます。導入前後の数字だけを比べると、需要の増減、価格の変動、体制の変更といった別の要因と区別できません。同じ入力に対する2つの出力を比べる形にすれば、差はモデルの効果に絞られます。
見るべき指標は3種類あります。1つ目は目的関数に載せた指標そのもので、総コスト、総走行距離、総人時などです。2つ目は計画の作成にかかる時間です。担当者が半日かけていた作業が数分で終わるのであれば、それ自体が効果であり、条件を変えた試算を何度も回せるようになるという副次的な効果も生みます。3つ目は、出てきた計画に対する手修正の量と、作り直しの回数です。この3つ目は見落とされがちですが、定着の度合いを最もよく表します。手修正が多いのであれば、書けていない制約が残っているということです。
金額への換算には注意が要ります。計画上の改善が、そのまま損益計算書の数字として現れるとは限りません。走行距離が減っても、運送契約が固定費であれば支払額は変わりません。残業時間が減っても、その分の人員がすぐに他の業務へ移せるとは限りません。何がどこまで金額に効くのかは、経理や購買の担当を交えて確認しておきます。
金額に表れにくい効果についても、投資判断の材料として明示します。属人化していた計画作成を誰でも再現できるようになること、担当者の交代に耐えられるようになること、条件を変えた場合の見通しをすぐ出せるようになることは、いずれも継続的な価値を持ちます。
制約は必ず変わります。単価や運賃、設備能力、人員構成、取引先との条件、法令や社内規程は、いずれ更新されます。定式化のプロジェクトを一度きりの構築案件として設計すると、変更のたびに担当者が困り、やがて使われなくなります。運用に引き渡す時点で、次の項目を決めておきます。
変更後の確認には、第2章で扱った検算の考え方をそのまま使えます。直近の実績を新しい制約に当てはめ、違反が出ないことと、目的関数の値が想定の範囲に収まることを見ます。この手順を運用の手引きに書いておけば、担当者が代わっても同じ品質で確認できます。
権限の設計も決めておきます。どの条件を変えるかを決めるのは業務側、モデルに実装するのは分析または情報システム側、という分け方が基本です。一方で、需要の見込み値や優先度の重みのように、業務の判断で日常的に変わる値については、担当者が画面から変更できる形にしておくほうが使われ続けます。数式の構造を変える操作と、数値を入れ替える操作を分け、前者には手続きを置き、後者は現場で完結させるという設計です。
最後に、モデルの中身を書いた人しか分からない状態を残さないことです。数式、入力データ、実装コードの対応関係を文書として残し、変数と制約が業務のどの条件に対応するのかを日本語で併記しておきます。この記録があれば、担当者が交代しても条件の変更に追随できます。更新され続けるモデルは業務の一部になりますが、更新されないモデルは、数か月で現実と合わなくなります。
定式化をプロジェクトとして進めるうえで扱ってきた判断は、いずれも数式の外側にあります。どこまでを線形で書くか、どこまでの精度を求めるか、誰が条件を決め、誰が直すのかという判断です。これらを決めていく作業は、業務の判断基準を明文化し、その所在を組織のなかに位置づけていく作業でもあります。モデルは条件が変われば書き換わりますが、この過程で言語化された判断基準は、その後も業務に残ります。

『応用数理計画ハンドブック』(久保幹雄、田村明久、松井知己 編、朝倉書店):この章で扱ったのは進め方の側ですが、実際のプロジェクトでは、目の前の課題に対応する定式化や解法を個別に確認したい場面が繰り返し訪れます。編著による事典的な構成のため、手元に置いて必要な項目を引く使い方に向いており、本コラムの各章で扱った型からさらに踏み込みたいときの参照先になります。
本コラムでは、数理最適化の定式化を、業務課題の側から整理してきました。決定変数・目的関数・制約という3点セットを日本語で書き出すこと(第2章)、書き上げた問題がどの型に落ちれば現実的な時間で解けるのかを見分けること(第3章)、現場の条件を数式に載せる書き換えの引き出しを持つこと(第5章)。この土台の上で、生産計画から配送ルートまでの7つの業務課題を、それぞれ定番の型に当てはめて書き下してきました(第6章から第12章)。そして、モデルをPythonで動かして確かめる手順(第13章)と、プロジェクトとして進めて運用に定着させるまでの判断(第14章)を確認しました。
全編を通して繰り返し現れた論点は、3つに集約できると思います。実務の計画業務の大半は、すでに名前の付いた定番の型のどれかに収まるということ。費用対効果の高い順に選ぶといった直感的な手順は、思いのほか最適を外すということ。そして、計算そのものよりも、守るべき条件を漏れなく書き出す工程が成果を左右するということです。小さな例題の範囲でも、直感による選び方と計算による選び方の差は、金額の形で具体的に現れていました。
第1章の事例が示していたとおり、数理最適化の成果の中核は、熟練者の暗黙知を明示的な条件として書き出せたことにありました。そして第14章で見たとおり、この書き出しの成果物、つまり制約の一覧、条件の根拠、譲れるものと譲れないものの区分、用語の定義は、モデルそのものより長く生き残ります。モデルは条件が変われば書き換えられますが、言語化された判断基準は、担当者が交代しても、システムが更新されても、業務の資産として使い続けられます。
定式化とは、最適解を計算するための準備作業であると同時に、業務の判断基準を組織の共有物にする作業です。仮にソルバーを一度も動かさなかったとしても、3点セットを書き出し、制約を根拠付きで一覧にした時点で、その業務の属人性は一段下がっています。数理最適化への投資を、計算システムの導入としてだけでなく、業務の形式知化への投資として捉えていただくのが、本コラムの結論にあたります。
もう1つ組織に残るものが、共通の言葉です。決定変数、制約、ソフト制約といった用語が業務側と分析側の共通言語になると、「その条件は絶対に守るものですか、できれば守りたいものですか」という一往復の確認だけで、要件の議論は一段具体的になります。第14章で見たとおり、要件の食い違いの多くは、この区別が共有されていないところから生まれます。共通の語彙は、その食い違いを早い段階で表に出す働きをします。
読み終えたあとの進め方として、次の3つの手順をおすすめします。いずれも、大きな投資判断の前に、自社の中だけで進められるものです。
最初の1件は、小さく選ぶことをおすすめします。頻度が高く条件の明確な業務であれば、書き出しから試作、運用までの一巡を短い期間で経験でき、第14章で挙げた論点、つまりデータの粒度、体制、効果の測り方、変更管理のそれぞれが自社ではどういう形になるのかを、実物で確かめられます。そして、この3つを進めるなかで手が止まった場所があれば、そこがその業務の急所であり、外部の専門家と組む価値のある部分でもあります。止まった場所が、書き出せない条件なのか、型の引き当てなのか、解が出ない原因の切り分けなのかまで特定できていれば、相談は具体的に進みます。
Anagraftでは、AIプロジェクトの構想・課題設計から、データ分析・機械学習モデルの開発、AI人材の育成まで一貫したご支援を行っています。対象業務の見立てや定式化のご相談は、以下よりお問い合わせください。
お問い合わせ
各章末でご紹介した参考書籍を、章の順にまとめました。章末では「その章の内容とどうつながるか」を書きましたので、ここでは「その本がどういう本か」という観点で一言を添えています。全体を体系立てて学び直したい場合は第2章と第3章の書籍から、手を動かすことを優先したい場合は第4章と第13章の書籍から入る形が取り組みやすいと思います。
本文で挙げた事例の数値、法令の内容、ソルバーの仕様は、以下の一次情報にあたって確認しました。閲覧時点は2026年8月です。制度の内容やソフトウェアの仕様は改定されることがありますので、実務でご利用の際は各出典の最新の記載をご確認ください。
scipy.optimize.linprog: https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.linprog.htmlscipy.optimize.milp: https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.milp.html