Pythonで配送ルート最適化:車両20台・燃料費15%削減の手順書

午前1時半。明日の配車表を、あなたはまたExcelで組み直している。
「Aドライバーは午前中に北エリア、Bドライバーは港方面から」と頭の中でパズルを回す。でも15件目あたりで詰まる。差し替えると別のところが崩れる。結局「だいたいこんな感じ」で確定して、画面を閉じる。
それ、あなたの段取りが悪いんじゃないんですよね。
20件の配送先を並べると、考えられるルートの組み合わせは約2.4×10¹⁸通り——2京4千兆通り以上です参考。スーパーコンピュータでも全パターンを計算し終えるのに数年かかる規模。「手動で最短ルートを作る」は、そもそも最初から不可能な問いでした。
じゃあどうするか。数学的に「十分に良い解」を高速で出すアルゴリズムを使う。それを自分のデータで動かす手段が、Pythonのオープンソースライブラリです。
この記事では、現場規模に合ったライブラリの選び方、制約設定の実例、コピペで動く最小コード、そして「導入して何が変わったか」を実数字ベースで整理します。検索上位にある「PuLPでTSPを解く」チュートリアルで終わらないために書きました。
---
配送先20件で2.4×10¹⁸通り——「手動最短化」は最初から無理だった
2024年4月、ドライバーの残業上限が年960時間に制限されました参考。数字だけ見ると「まあ守れる」と思うかもしれない。でも国土交通省の試算では、この規制でトラック輸送力が約14%不足すると弾き出されています。
さらに長期では、対策を講じなければ2030年度に輸送能力の約34%、9億トン相当が消える、とも試算されています参考。ドライバーの有効求人倍率はすでに2.64倍(全職業平均1.20倍の2倍超)。40〜50代前半に約45%が集中していて、今後10年で大量退職が視野に入っています。
「人を増やせばいい」が通じない時代に、1台1台の走行距離を削ることが唯一の突破口になりつつある。
そこで出てくるのがルート最適化アルゴリズムです。総当たりが不可能なので、「良い解を短時間で見つける」近似解法や厳密解法を使う。Pythonには、そのためのライブラリが無料で揃っています。
ひとつ誤解を解いておくと、「Pythonで最適化=エンジニアのおもちゃ」ではないんですよね。2025年施行の改正物流効率化法では、積載効率44%への引き上げと、ドライバー1人あたり年間125時間の拘束時間短縮が数値目標として明示されています参考。現場に求められる「数値化できる改善」と、Pythonで解ける問題はぴったり重なってきています。
燃料費だけ見ても、国土交通省の調査ではトラック運送事業の燃料費は営業費用の約15〜20%を占めます参考。走行距離を1割削れれば、その分が直接コスト改善に直結するわけです。
---
PuLPかOR-Tools、現場規模で選ぶ3つの判断軸
「どっちを使えばいいんですか」という質問、よく来ます。判断軸は3つだけです。
| 判断軸 | PuLP | OR-Tools |
|---|---|---|
| 得意な問題規模 | 小規模(配送先〜50件程度) | 大規模・複雑な制約に強い |
| 速度 | 中程度 | 一般的にPuLPより高速参考 |
| 学習コスト | 低(Pythonの数式に近い記述) | やや高(データ構造の理解が必要) |
| 向いている用途 | 社内PoC・小規模検証 | 本番運用・複数台VRP |
| インストール | pip install pulp | pip install ortools |
配送先が50件以下で「まず動かしてみたい」ならPuLPから入るのが素直です。本番で複数台・複雑な時間窓を扱うならOR-Toolsに移行する、という2段階が現実的だと思ってます。
補足しておくと、ネット上のチュートリアルが解いている「巡回セールスマン問題(TSP)」は「1台の車が全配送先を回る」問題です。でも現場はほぼ100%「複数台の車両に配送先を割り振る」車両経路問題(VRP)です。TSPのコードが動いても、そのままでは実務に使えません。OR-ToolsはVRPに標準対応しているので、実務では最初からOR-Toolsを選ぶ判断もあります。
---
メール登録で、その場でご覧いただけます。週刊「業界AI深掘りレポート」(準備中)の先行案内もお送りします。
配車担当Aさんの1日 vs Bさんの1日:燃料費15%減の実像
「で、実際に変わるの?」というのが正直なところだと思う。生成AI総合研究所が支援した、ドライバー30名・車両20台規模の配送会社の検証結果を見てみます参考。
Aさん(AI導入前)の1日
- 05:30 出社。Excelに昨日の残りデータを張り直す
- 06:00〜08:00 2時間かけて配車計画を手組み。詰まったら先輩に確認
- 17:30 定時だが「今日もルートに無駄があった」と感じながら退社
- 月の残業:約40時間
Bさん(AI導入後)の1日
- 05:30 出社。前日にシステムが自動生成したルート案を確認・微調整
- 06:00 30分で配車確定。差し替えが出たときだけ手を入れる
- 17:00 定時退社。燃料日報を確認すると今月も基準内
- 月の残業:約25時間
{CHART|bar|AI導入前後の改善効果(ドライバー30名・車両20台)|燃料費削減率,走行距離削減率,配送計画時間削減率,残業時間削減率|15,20,75,37.5|%|https://www.generativeai.tokyo/media/delivery-route-optimization-ai-guide/|生成AI総合研究所}
出典: 生成AI総合研究所のデータより匠座作成
燃料費は月800万円→680万円(15%削減)、走行距離は月4,000km→3,200km(20%削減)。配送計画作成は日2時間→30分(75%削減)、ドライバー残業は月40時間→25時間(37.5%削減)でした。
先日、ヤマト運輸がGoogle Route Optimization APIとAGLOPを組み合わせた事例を読んでいて唸ったんですよ。配送生産性最大20%向上、CO₂排出量最大25%削減を見込むという数字が出ていた参考。規模感の違いはあっても、「ルート最適化で出せる改善幅」が中小規模の検証結果とほぼ重なっています。アルゴリズムは規模を問わず同じ原理で効くんだな、と改めて確認した事例でした。
---
コピペで動く最小実装と「制約設定が9割」の現実
ここからが本題です。
まずOR-ToolsでVRPの最小構成を動かしてみてください。
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
def create_data_model():
"""
現場データに合わせてここを書き換える。
distance_matrix: 配送先どうしの所要時間(分)の2次元リスト
num_vehicles: 車両台数
depot: 出発地のインデックス(通常0)
"""
data = {}
data["distance_matrix"] = [
[0, 20, 35, 45, 15],
[20, 0, 30, 25, 40],
[35, 30, 0, 20, 50],
[45, 25, 20, 0, 30],
[15, 40, 50, 30, 0],
]
data["num_vehicles"] = 2
data["depot"] = 0
return data
def main():
data = create_data_model()
manager = pywrapcp.RoutingIndexManager(
len(data["distance_matrix"]),
data["num_vehicles"],
data["depot"]
)
routing = pywrapcp.RoutingModel(manager)
def distance_callback(from_index, to_index):
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return data["distance_matrix"][from_node][to_node]
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC
)
solution = routing.SolveWithParameters(search_parameters)
if solution:
for vehicle_id in range(data["num_vehicles"]):
index = routing.Start(vehicle_id)
route = []
while not routing.IsEnd(index):
route.append(manager.IndexToNode(index))
index = solution.Value(routing.NextVar(index))
route.append(manager.IndexToNode(index))
print(f"車両{vehicle_id}: {' -> '.join(map(str, route))}")
else:
print("解が見つかりませんでした")
main()
distance_matrixに実際の所要時間(分)を入れ、num_vehiclesを車両台数に変えるだけで動きます。まずはこれを手元のPCで動かしてみてください。
ここからが、チュートリアルが教えてくれない話です。
僕が匠座のAIパイプライン(毎朝の情報収集・記事品質ゲートの自動チェック)を構築するとき、いちばん時間がかかるのはアルゴリズム選択じゃなくて「どんな制約を入れるか」の定義なんですよね。配送ルート最適化も同じで、「OR-Toolsをインストールして動かす」は1時間でできる。でも「積載量上限・時間窓・ドライバーごとのエリア制限・昼休み・返品回収」を正確にモデルに落とし込む作業が、現場導入の8割を占めます。最初はシンプルな制約から始めて、動くことを確認してから1つずつ追加していくのが正解です。
コピペ用プロンプト①:自社の配送データを制約モデルに変換する
あなたは物流ルート最適化のエンジニアです。
以下の配送データをOR-ToolsのVRP制約として定義するPythonコードを書いてください。
【配送先数】[件数]件
【車両台数】[台数]台
【各車両の積載上限】[重量またはピース数]
【時間窓】[配送先ごとの受取可能時間帯、例: A社 9:00〜12:00]
【ドライバー制限】[特定ドライバーが担当できないエリアや条件]
【出発地・帰還地】[倉庫の住所またはインデックス]
add_dimension()を使って積載量と時間窓を別々に実装し、
各パラメータにコメントをつけてください。
使いどころ:制約の追加実装に詰まったとき
検証観点:「解が見つかりませんでした」が返る場合は制約が矛盾している可能性が高いので、1つずつ制約を外してどこで詰まるか確認する
---
コピペ用プロンプト②:「No solution found」のデバッグ
以下のOR-ToolsのVRPコードで「解が見つかりませんでした」が返ります。
制約の矛盾を特定して修正してください。
【コード】
[OR-ToolsのPythonコードをここに貼る]
【エラーへの対処として試したこと】
[試したこと]
考えられる原因を3つ挙げ、それぞれの確認方法と
コードの修正案を示してください。
使いどころ:実装中にソルバーが解なしを返したとき
検証観点:積載量・時間窓・車両数のどれかを一時的に緩めて問題を特定できているか確認する
---
正直な限界:Python配送ルート最適化が向かない現場
「導入すれば解決」とは言いません。向かないケースを先に出しておきます。
1. リアルタイム変更が多すぎる現場
PythonのOR-Toolsはバッチ処理が基本です。配送中に「急な追加注文」「時間指定変更」が頻発する場合、その都度再計算するアーキテクチャが必要になります。OR-ToolsだけではなくAPIサービスとの連携が現実的で、初期構築コストが跳ね上がります。
2. Excelへの依存が深く、ITに触れる人がいない組織
距離行列を作るには配送先の座標データ(緯度経度)かGoogle Maps APIが必要です。「住所はExcelに散らばっているが、コードにはさわれる人がいない」という場合、データ整備が最初のボトルネックになります。エンジニアがいないと最初の一歩が止まりやすい。
3. 配送先が10件以下の小規模ルート
件数が10以下なら、人間の経験則と目視でも十分に近い解が得られます。Pythonを持ち込む費用対効果が薄い場面です。
4. 「解けない」に気づくのが遅れやすい
制約が矛盾していてもOR-Toolsは黙って「No solution」を返します。原因の特定に時間がかかりやすく、これで手が止まる実務者が多い印象です。上のプロンプト②を手元に置いておいてください。
---
よくある質問に先に答えます
Q1. コスト感はどのくらいですか?
PuLP・OR-Toolsはオープンソースで無料です。クラウド化・本番運用を考えると、Google Maps Platformの距離行列APIのコスト(呼び出し回数課金)とインフラ維持費が変動します。SaaS系ルート最適化ツールと比較したい場合は、まずPythonで概念実証(PoC)して「どこまで自動化できるか」を確認してからにするのが失敗が少ないです。
Q2. Pythonが書けないと無理ですか?
ゼロからは難しいですが、「コードをコピペして変数を書き換える」レベルなら実務経験2〜3年のIT担当者なら動かせます。ただし「動かす」と「本番運用できる形にする」は別物です。本番化にはデータパイプライン設計とエラー処理が必要で、そこにエンジニアの工数が必要になります。
Q3. どのくらいの期間で効果が出ますか?
検証(PoC)フェーズで2〜4週間、本番移行まで2〜3か月が現実的な目線です。食品卸売企業の事例では、AI導入後に配送計画作成時間を約66%削減(1.5〜2時間→30分)、ドライバー残業を月平均45%削減しています参考。ただし「何から手をつけるか」の設計にズレがあると、PoC期間が倍以上かかることもあります。
Q4. 自社のデータを外部に出すのが不安です
OR-ToolsはローカルPCやオンプレミスサーバーで完全に閉じた環境で動きます。クラウドAPIを使わなければ配送先データが外部に出ることはありません。地図データにGoogle Maps APIを使う場合はGoogleの利用規約を個別に確認してください。
Q5. 既存の配車システムと共存できますか?
できます。PythonはCSV出力が容易なので、既存の配車システムへのインポート用ファイルとして最適化済みルートを渡す設計が現実的です。いきなり全置換するより、「出力だけ最適化ツールに任せる」部分導入から始めると現場の混乱を最小化できます。
---
ここまで読んで「自社だけでやるには手が足りない」と感じた方は、『AI鬼管理|Claude Code業務自動化トレーニング』(Claude Codeで日々の業務を自動化する実践トレーニング(無料の業務効率化診断あり))のような外部サービスという選択肢もあります。急ぎでなければ、まずは無料のチェックリストで足元を固めるのがおすすめです。
AI鬼管理|Claude Code業務自動化トレーニング ↗
今日やること:30分で始める3ステップ
まず全体の流れを確認しておきます。
| ステップ | 一言で言うと | 時間の目安 |
|---|---|---|
| 1. 環境構築 | OR-Toolsをインストールして最小サンプルを動かす | 30分 |
| 2. 自社データに置換 | 距離行列と車両数を実データに差し替える | 1〜3時間 |
| 3. 制約の追加 | 積載量・時間窓を1つずつ追加して検証 | 1〜2日 |
| 4. 効果測定 | 現行ルートとの走行距離・時間を比較 | 半日 |
| 5. 本番移行 | パイプライン化・定期実行の設計 | 1〜2週間 |
ステップ1:OR-Toolsを入れて動かす(10分)
ターミナルでpip install ortoolsを実行し、上の最小コードをそのままコピペして動かしてみてください。出力される「車両0: 0 → 3 → 2 → 1 → 4 → 0」のような文字列がルートです。
ステップ2:自社の配送先5件を入れる(15分)
distance_matrixの中身を、自社の配送先5か所の所要時間(分)に書き換えます。Google マップで手動計算でも構いません。まずリアルなデータで動かすことが最優先です。
ステップ3:出てきたルートを既存の配車と比較する(5分)
OR-Toolsが出したルートの合計時間と、今日実際に走ったルートの合計時間を比べてみてください。差が出ているなら、Pythonによる最適化は自社に効く、という仮説の第一検証になります。
この3ステップだけで「使えるかどうか」の感触は掴めるはずです。制約の追加や本番化は、動く手応えを確認してからで十分です。
---
編集長メモ:ヘリックス(執筆者について)
この記事は「動かす」が入口です。本当の勝負は制約の定義——時間窓・積載量・ドライバー制限を1つずつ加える地道な作業にあります。まず動かして、それから1個追加。
▶ あわせて読みたい:配送ルート最適化アプリの選び方と実践ノウハウ
▶ あわせて読みたい:無料の配送ルート最適化AIはどこまで使えるか:実数字で測る
メール登録で、その場でご覧いただけます。週刊「業界AI深掘りレポート」(準備中)の先行案内もお送りします。


