Skillsを備えたVRP
車両で実行する必要がある作業には、特定のSkillsが必要になることがよくあります。輸送の特殊な条件を満たす必要があります。 これは、顧客が配管や電気などのサービスを必要とする場合、または配送や集荷に冷蔵室を備えた車両が必要な場合に発生する可能性があります。 このような場合 skills
によって、顧客の作業制約に合うように車両の要件を指定する必要があります。
7 つの異なるジョブがあり、そのいくつかが異なるSkillsを必要とする状況を考えてみましょう。
- job_1 - Skillsは不要
- job_2 - Skillsは不要
- job_3 - 冷蔵庫
- job_4 - 配管
- job_5 - 配管
- job_6 - 電気
- job_7 - Skillsは不要
これらのジョブに対し、保有する車両には、冷蔵庫と配管のSkillsを備えた十分な積載量の車両が 2 種類あり、電気のSkillsを持つ車両はないと仮定しましょう。このような制約のProblemsは、次のようになります。
Problems
{
"fleet": {
"types": [
{
"id": "qwert1234",
"profile": "car_1",
"costs": { "fixed": 7.0, "distance": 0.005, "time": 0.02 },
"shifts": [
{
"start": {
"time": "2021-08-27T08:03:00Z",
"location": { "lat": 52.530971, "lng": 13.384915 }
},
"end": {
"time": "2021-08-27T16:03:00Z",
"location": { "lat": 52.45717902261775, "lng": 13.45675245690121 }
}
}
],
"capacity": [50],
"skills": ["plumber"],
"amount": 2
},
{
"id": "abcde1234",
"profile": "car_1",
"costs": { "fixed": 7.0, "distance": 0.0, "time": 8.0 },
"shifts": [
{
"start": {
"time": "2021-08-27T08:03:00Z",
"location": { "lat": 52.530971, "lng": 13.384915 }
},
"end": {
"time": "2021-08-27T16:03:00Z",
"location": { "lat": 52.45717902261775, "lng": 13.45675245690121 }
}
}
],
"capacity": [50],
"skills": ["fridge"],
"amount": 2
}
],
"profiles": [{ "type": "car", "name": "car_1" }]
},
"plan": {
"jobs": [
{
"id": "job_1",
"tasks": {
"pickups": [
{
"places": [
{
"location": {
"lat": 52.57433728008193,
"lng": 13.414626318800853
},
"duration": 900
}
],
"demand": [2]
}
]
}
},
{
"id": "job_2",
"tasks": {
"pickups": [
{
"places": [
{
"location": {
"lat": 52.54252808824531,
"lng": 13.384239353645219
},
"duration": 720
}
],
"demand": [2]
}
]
}
},
{
"id": "job_3",
"skills": ["fridge"],
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 52.558716170353655,
"lng": 13.31823634661218
},
"duration": 240
}
],
"demand": [2]
}
]
}
},
{
"id": "job_4",
"skills": ["plumber"],
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 52.45348677617264,
"lng": 13.321459421457485
},
"duration": 60
}
],
"demand": [2]
}
]
}
},
{
"id": "job_5",
"skills": ["plumber"],
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 52.53284583231377,
"lng": 13.432577803817928
},
"duration": 300
}
],
"demand": [2]
}
]
}
},
{
"id": "job_6",
"skills": ["elecrician"],
"tasks": {
"deliveries": [
{
"places": [
{
"location": { "lat": 52.5528458, "lng": 13.4425778 },
"duration": 300
}
],
"demand": [2]
}
]
}
},
{
"id": "job_7",
"tasks": {
"deliveries": [
{
"places": [
{
"location": { "lat": 52.532845, "lng": 13.425778 },
"duration": 300
}
],
"demand": [2]
}
]
}
}
]
}
}
Solution
この問題の解決方法は次のとおりです。
{
"statistic": {
"cost": 21677.89,
"distance": 70151,
"duration": 9621,
"times": {
"driving": 7101,
"serving": 2520,
"waiting": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "qwert1234_2",
"typeId": "qwert1234",
"stops": [
{
"location": {
"lat": 52.530971,
"lng": 13.384915
},
"time": {
"arrival": "2021-08-27T08:03:00Z",
"departure": "2021-08-27T08:03:00Z"
},
"load": [
6
],
"activities": [
{
"jobId": "departure",
"type": "departure"
}
]
},
{
"location": {
"lat": 52.54252808824531,
"lng": 13.38423935364522
},
"time": {
"arrival": "2021-08-27T08:07:51Z",
"departure": "2021-08-27T08:19:51Z"
},
"load": [
8
],
"activities": [
{
"jobId": "job_2",
"type": "pickup"
}
]
},
{
"location": {
"lat": 52.57433728008193,
"lng": 13.414626318800853
},
"time": {
"arrival": "2021-08-27T08:33:37Z",
"departure": "2021-08-27T08:48:37Z"
},
"load": [
10
],
"activities": [
{
"jobId": "job_1",
"type": "pickup"
}
]
},
{
"location": {
"lat": 52.532845,
"lng": 13.425778
},
"time": {
"arrival": "2021-08-27T09:04:29Z",
"departure": "2021-08-27T09:09:29Z"
},
"load": [
8
],
"activities": [
{
"jobId": "job_7",
"type": "delivery"
}
]
},
{
"location": {
"lat": 52.53284583231377,
"lng": 13.432577803817928
},
"time": {
"arrival": "2021-08-27T09:12:02Z",
"departure": "2021-08-27T09:17:02Z"
},
"load": [
6
],
"activities": [
{
"jobId": "job_5",
"type": "delivery"
}
]
},
{
"location": {
"lat": 52.45348677617264,
"lng": 13.321459421457485
},
"time": {
"arrival": "2021-08-27T09:45:06Z",
"departure": "2021-08-27T09:46:06Z"
},
"load": [
4
],
"activities": [
{
"jobId": "job_4",
"type": "delivery"
}
]
},
{
"location": {
"lat": 52.45717902261775,
"lng": 13.45675245690121
},
"time": {
"arrival": "2021-08-27T09:58:56Z",
"departure": "2021-08-27T09:58:56Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival"
}
]
}
],
"statistic": {
"cost": 350.89,
"distance": 40954,
"duration": 6956,
"times": {
"driving": 4676,
"serving": 2280,
"waiting": 0,
"break": 0
}
}
},
{
"vehicleId": "abcde1234_1",
"typeId": "abcde1234",
"stops": [
{
"location": {
"lat": 52.530971,
"lng": 13.384915
},
"time": {
"arrival": "2021-08-27T08:03:00Z",
"departure": "2021-08-27T08:03:00Z"
},
"load": [
2
],
"activities": [
{
"jobId": "departure",
"type": "departure"
}
]
},
{
"location": {
"lat": 52.558716170353655,
"lng": 13.31823634661218
},
"time": {
"arrival": "2021-08-27T08:19:19Z",
"departure": "2021-08-27T08:23:19Z"
},
"load": [
0
],
"activities": [
{
"jobId": "job_3",
"type": "delivery"
}
]
},
{
"location": {
"lat": 52.45717902261775,
"lng": 13.45675245690121
},
"time": {
"arrival": "2021-08-27T08:47:25Z",
"departure": "2021-08-27T08:47:25Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival"
}
]
}
],
"statistic": {
"cost": 21327.0,
"distance": 29197,
"duration": 2665,
"times": {
"driving": 2425,
"serving": 240,
"waiting": 0,
"break": 0
}
}
}
],
"unassigned": [
{
"jobId": "job_6",
"reasons": [
{
"code": "SKILL_CONSTRAINT",
"description": "cannot serve required skill"
}
]
}
]
}
Solutionの評価
ソリューションからわかるように、それぞれのニーズとSkillsを持つ作業が、期待どおりに各車両に割り当てられました。 コスト、走行距離、所要時間を含む実行の合計統計と、運転、サービス、待機、休憩の正確なタイミングを確認できます。 同時に、電気のSkillsを持つ 1 つのジョブが車両のどのSkillsとも一致せず、どの車両にも割り当てられなかったこともわかります。
1 台の車両に複数のSkillsを指定することもできます。 その場合、車両には、作業でサービスを提供するために必要なすべてのSkillsが必要です。 車両は、その特定の作業では不要な追加のSkillsを持っている場合があり、それは最適化に影響を与えることはありません。