最大シフト時間を制限する
運行管理している車両に最大シフト時間制限を導入すると、ドライバーの健康促進、疲労による事故リスクの軽減、法的規制の確実な遵守を実現できます。ピーク期間や繁忙期など、作業負荷や業務ニーズの変動の可能性によって、許容される所要時間がフリートに指定されたシフト時間 (fleet.types.shifts) を超過する場合に特にこれが当てはまります。
最大シフト時間構成を理解する
HERE Tour Planning API内では、fleet.types.limits設定にあるshiftTimeオブジェクトを使用できます。これにより、シフトの開始時間と終了時間 (shifts.start.timeとshifts.end.time) によって決定されるフリート全体のシフト時間に関係なく、各車両のシフトの最大時間 (秒単位) を指定できます。
ユースケース:法令遵守のためにドライバーの労働時間制限を適用する
たとえば、最初にスケジュールされたフリートのシフト時間が午前8時から午後11時までの合計15時間となり、ドライバーの最大労働時間である8時間を超えるユースケースを考えてみましょう。最大シフト時間を実装することで、フリート全体が15時間のシフト時間制限内で運用される一方で、最適化アルゴリズムによって各車両が8時間を超えて稼働しないようにツアーをスケジュールできます。
次の簡略化されたスニペットは、前のユースケースで説明したように、fleet.types.shiftsとfleet.types.limits.shiftTimeの構成を示しています。
{
"fleet": {
"traffic": "historicalOnly",
"types": [
{
"id": "Vehicle_1",
"profile": "car",
"costs": {...},
"shifts": [ // Shift time that defines fleet-level working hours
{
"start": {
"time": "2021-10-23T08:00:00Z",
"location": {
"lat": 51.059188,
"lng": 13.540317
}
},
"end": {
"time": "2021-10-23T23:00:00Z",
"location": {
"lat": 51.059188,
"lng": 13.540317
}
}
}
],
"limits": {
"shiftTime": 28800 // Maximum tour duration for individual vehicles
},
"capacity": [...],
"amount": ...
}
],
"profiles": [...]
}
}詳細については、「APIリファレンス」を参照してください。
問題
次の完全な問題JSONは、サンプルユースケースで前述した、2台の車両で構成されるフリートのシフトと最大シフト時間を反映しています。そのフリートのツアー計画は、11個の集荷ジョブまたは配達ジョブで構成されます。
Click to expand/collapse the sample JSON
{
"fleet": {
"traffic": "historicalOnly",
"types": [
{
"id": "Vehicle_1",
"profile": "car",
"costs": {
"fixed": 10,
"distance": 0.001,
"time": 0.002
},
"shifts": [
{
"start": {
"time": "2021-10-23T08:00:00Z",
"location": {
"lat": 51.059188,
"lng": 13.540317
}
},
"end": {
"time": "2021-10-23T23:00:00Z",
"location": {
"lat": 51.059188,
"lng": 13.540317
}
}
}
],
"limits": {
"shiftTime": 28800
},
"capacity": [
10
],
"amount": 2
}
],
"profiles": [
{
"type": "car",
"name": "car"
}
]
},
"plan": {
"jobs": [
{
"id": "Job-1_D",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 51.039189,
"lng": 13.63855
},
"duration": 2700
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job-2_P",
"tasks": {
"pickups": [
{
"places": [
{
"location": {
"lat": 51.05238,
"lng": 13.74114
},
"duration": 2700
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job-3_P",
"tasks": {
"pickups": [
{
"places": [
{
"location": {
"lat": 51.06099,
"lng": 13.75245
},
"duration": 2700
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job-4_D",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 51.06866,
"lng": 13.77273
},
"duration": 2700
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job-5_P",
"tasks": {
"pickups": [
{
"places": [
{
"location": {
"lat": 51.08511,
"lng": 13.76875
},
"duration": 2700
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job-6_P",
"tasks": {
"pickups": [
{
"places": [
{
"location": {
"lat": 51.124507,
"lng": 13.792324
},
"duration": 2700
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job-7_D",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 51.119731,
"lng": 13.76543
},
"duration": 2700
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job-8_P",
"tasks": {
"pickups": [
{
"places": [
{
"location": {
"lat": 51.11716,
"lng": 13.73054
},
"duration": 2700
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job-9_D",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 51.132473,
"lng": 13.643954
},
"duration": 2700
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job-10_D",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 51.121718,
"lng": 13.631475
},
"duration": 2700
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job-11_D",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 51.11169515690879,
"lng": 13.622580586403492
},
"duration": 2700
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job-12_D",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 51.11169515690879,
"lng": 13.622580586403492
},
"duration": 2700
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job-13_D",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 51.11169515690879,
"lng": 13.622580586403492
},
"duration": 2700
}
],
"demand": [
1
]
}
]
}
}
]
}
}ソリューション
この問題のソリューションは、最大シフト時間を設定することで、効率を維持しながら個々の車両のツアーが8時間を超えないようにする方法を示しています。
Click to expand/collapse the sample JSON
{
"statistic": {
"cost": 192.204,
"distance": 88206,
"duration": 41999,
"times": {
"driving": 6899,
"serving": 35100,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "Vehicle_1_1",
"typeId": "Vehicle_1",
"stops": [
{
"time": {
"arrival": "2021-10-23T08:00:00Z",
"departure": "2021-10-23T08:00:00Z"
},
"load": [
3
],
"activities": [
{
"jobId": "departure",
"type": "departure",
"location": {
"lat": 51.059188,
"lng": 13.540317
},
"time": {
"start": "2021-10-23T08:00:00Z",
"end": "2021-10-23T08:00:00Z"
}
}
],
"location": {
"lat": 51.059188,
"lng": 13.540317
},
"distance": 0
},
{
"time": {
"arrival": "2021-10-23T08:16:03Z",
"departure": "2021-10-23T09:01:03Z"
},
"load": [
4
],
"activities": [
{
"jobId": "Job-8_P",
"type": "pickup",
"location": {
"lat": 51.11716,
"lng": 13.73054
},
"time": {
"start": "2021-10-23T08:16:03Z",
"end": "2021-10-23T09:01:03Z"
}
}
],
"location": {
"lat": 51.11716,
"lng": 13.73054
},
"distance": 19959
},
{
"time": {
"arrival": "2021-10-23T09:05:50Z",
"departure": "2021-10-23T09:50:50Z"
},
"load": [
3
],
"activities": [
{
"jobId": "Job-7_D",
"type": "delivery",
"location": {
"lat": 51.119731,
"lng": 13.76543
},
"time": {
"start": "2021-10-23T09:05:50Z",
"end": "2021-10-23T09:50:50Z"
}
}
],
"location": {
"lat": 51.119731,
"lng": 13.76543
},
"distance": 22945
},
{
"time": {
"arrival": "2021-10-23T09:54:19Z",
"departure": "2021-10-23T10:39:19Z"
},
"load": [
4
],
"activities": [
{
"jobId": "Job-6_P",
"type": "pickup",
"location": {
"lat": 51.124507,
"lng": 13.792324
},
"time": {
"start": "2021-10-23T09:54:19Z",
"end": "2021-10-23T10:39:19Z"
}
}
],
"location": {
"lat": 51.124507,
"lng": 13.792324
},
"distance": 25659
},
{
"time": {
"arrival": "2021-10-23T10:46:57Z",
"departure": "2021-10-23T11:31:57Z"
},
"load": [
5
],
"activities": [
{
"jobId": "Job-5_P",
"type": "pickup",
"location": {
"lat": 51.08511,
"lng": 13.76875
},
"time": {
"start": "2021-10-23T10:46:57Z",
"end": "2021-10-23T11:31:57Z"
}
}
],
"location": {
"lat": 51.08511,
"lng": 13.76875
},
"distance": 31008
},
{
"time": {
"arrival": "2021-10-23T11:37:38Z",
"departure": "2021-10-23T12:22:38Z"
},
"load": [
4
],
"activities": [
{
"jobId": "Job-4_D",
"type": "delivery",
"location": {
"lat": 51.06866,
"lng": 13.77273
},
"time": {
"start": "2021-10-23T11:37:38Z",
"end": "2021-10-23T12:22:38Z"
}
}
],
"location": {
"lat": 51.06866,
"lng": 13.77273
},
"distance": 34353
},
{
"time": {
"arrival": "2021-10-23T12:27:34Z",
"departure": "2021-10-23T13:12:34Z"
},
"load": [
5
],
"activities": [
{
"jobId": "Job-3_P",
"type": "pickup",
"location": {
"lat": 51.06099,
"lng": 13.75245
},
"time": {
"start": "2021-10-23T12:27:34Z",
"end": "2021-10-23T13:12:34Z"
}
}
],
"location": {
"lat": 51.06099,
"lng": 13.75245
},
"distance": 36514
},
{
"time": {
"arrival": "2021-10-23T13:18:16Z",
"departure": "2021-10-23T14:03:16Z"
},
"load": [
6
],
"activities": [
{
"jobId": "Job-2_P",
"type": "pickup",
"location": {
"lat": 51.05238,
"lng": 13.74114
},
"time": {
"start": "2021-10-23T13:18:16Z",
"end": "2021-10-23T14:03:16Z"
}
}
],
"location": {
"lat": 51.05238,
"lng": 13.74114
},
"distance": 38810
},
{
"time": {
"arrival": "2021-10-23T14:16:20Z",
"departure": "2021-10-23T15:01:20Z"
},
"load": [
5
],
"activities": [
{
"jobId": "Job-1_D",
"type": "delivery",
"location": {
"lat": 51.039189,
"lng": 13.63855
},
"time": {
"start": "2021-10-23T14:16:20Z",
"end": "2021-10-23T15:01:20Z"
}
}
],
"location": {
"lat": 51.039189,
"lng": 13.63855
},
"distance": 47723
},
{
"time": {
"arrival": "2021-10-23T15:12:13Z",
"departure": "2021-10-23T15:12:13Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival",
"location": {
"lat": 51.059188,
"lng": 13.540317
},
"time": {
"start": "2021-10-23T15:12:13Z",
"end": "2021-10-23T15:12:13Z"
}
}
],
"location": {
"lat": 51.059188,
"lng": 13.540317
},
"distance": 57066
}
],
"statistic": {
"cost": 118.932,
"distance": 57066,
"duration": 25933,
"times": {
"driving": 4333,
"serving": 21600,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"shiftIndex": 0
},
{
"vehicleId": "Vehicle_1_2",
"typeId": "Vehicle_1",
"stops": [
{
"time": {
"arrival": "2021-10-23T08:00:00Z",
"departure": "2021-10-23T08:00:00Z"
},
"load": [
5
],
"activities": [
{
"jobId": "departure",
"type": "departure",
"location": {
"lat": 51.059188,
"lng": 13.540317
},
"time": {
"start": "2021-10-23T08:00:00Z",
"end": "2021-10-23T08:00:00Z"
}
}
],
"location": {
"lat": 51.059188,
"lng": 13.540317
},
"distance": 0
},
{
"time": {
"arrival": "2021-10-23T08:15:24Z",
"departure": "2021-10-23T10:30:24Z"
},
"load": [
2
],
"activities": [
{
"jobId": "Job-11_D",
"type": "delivery",
"location": {
"lat": 51.11169515690879,
"lng": 13.622580586403492
},
"time": {
"start": "2021-10-23T08:15:24Z",
"end": "2021-10-23T09:00:24Z"
}
},
{
"jobId": "Job-12_D",
"type": "delivery",
"location": {
"lat": 51.11169515690879,
"lng": 13.622580586403492
},
"time": {
"start": "2021-10-23T09:00:24Z",
"end": "2021-10-23T09:45:24Z"
}
},
{
"jobId": "Job-13_D",
"type": "delivery",
"location": {
"lat": 51.11169515690879,
"lng": 13.622580586403492
},
"time": {
"start": "2021-10-23T09:45:24Z",
"end": "2021-10-23T10:30:24Z"
}
}
],
"location": {
"lat": 51.11169515690879,
"lng": 13.622580586403492
},
"distance": 11544
},
{
"time": {
"arrival": "2021-10-23T10:35:54Z",
"departure": "2021-10-23T11:20:54Z"
},
"load": [
1
],
"activities": [
{
"jobId": "Job-9_D",
"type": "delivery",
"location": {
"lat": 51.132473,
"lng": 13.643954
},
"time": {
"start": "2021-10-23T10:35:54Z",
"end": "2021-10-23T11:20:54Z"
}
}
],
"location": {
"lat": 51.132473,
"lng": 13.643954
},
"distance": 15411
},
{
"time": {
"arrival": "2021-10-23T11:23:14Z",
"departure": "2021-10-23T12:08:14Z"
},
"load": [
0
],
"activities": [
{
"jobId": "Job-10_D",
"type": "delivery",
"location": {
"lat": 51.121718,
"lng": 13.631475
},
"time": {
"start": "2021-10-23T11:23:14Z",
"end": "2021-10-23T12:08:14Z"
}
}
],
"location": {
"lat": 51.121718,
"lng": 13.631475
},
"distance": 17017
},
{
"time": {
"arrival": "2021-10-23T12:27:46Z",
"departure": "2021-10-23T12:27:46Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival",
"location": {
"lat": 51.059188,
"lng": 13.540317
},
"time": {
"start": "2021-10-23T12:27:46Z",
"end": "2021-10-23T12:27:46Z"
}
}
],
"location": {
"lat": 51.059188,
"lng": 13.540317
},
"distance": 31140
}
],
"statistic": {
"cost": 73.27199999999999,
"distance": 31140,
"duration": 16066,
"times": {
"driving": 2566,
"serving": 13500,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}次の図はソリューションを図示したものです。
このソリューションが示すように、午前8時に開始して午後11時に終了するシフトの場合、アルゴリズムは2つのツアーを作成することで、最大シフト時間制限である28,800秒 (8時間) を超える車両を出さずに、作業負荷を効率的に分散し、ドライバーの労働時間の上限に関する法規制を遵守しました。
次の図は、同じ問題に対し、28,800秒の最大シフト時間制限を削除したソリューションを示しています。
このケースでは、ツアーは1台の車両だけで効率的に完了できるとアルゴリズムが判断しました。しかし、ツアーにはドライバーの最大勤務時間を超える11時間以上かかりました。
結論
通常のシフト時間と並行して個々の車両にシフト時間の上限を導入すると、フリートのリソースのより適切な計画と最適化が促進されます。作業負荷を管理可能な単位に分割することで、車両を効率的に割り当て、法的要件を遵守し、ドライバーの健康を促進しながら、タスクの割り当てが簡素化されます。
次のステップ
- HERE Tour Planning APIで問題を作成する方法の詳細については、「問題」を参照してください。
- HERE Tour Planning APIのメソッド、エンドポイント、パラメーターの詳細については、「APIリファレンス」を参照してください。
- 他の制限タイプについて詳しくは、「ルート制限を設定する」を参照してください。
26 日前の更新