リレーションを使用して旅程を再計画する
リレーションを使用して旅程を再計画する
先ほど説明したように、任意のrelationsパラメーターを使用して、特定の車両に対するジョブの実行のルールと順序を定義できます。リレーションを使用すると、再計画プロセスと最終的なソリューションのアルゴリズムの動作に影響を与えることができます。リレーションには次の3つのタイプがあります。
- シーケンス - このリレーションで指定されたジョブは、この特定の車両によって指定された順序で実行される必要があります。実行順序は変更できません。また、このリレーションで指定されたジョブの間に追加のジョブを挿入することはできません。
"relations": [
{
"type": "sequence",
"jobs": [
"job_1",
"job_2"
"job_4"
],
"vehicleId": "Vehicle_1_1"
}
]- フレキシブル - このリレーションで指定されたジョブは、この特定の車両によって指定された順序で実行される必要があります。ジョブの実行順序は変更できませんが、このリレーションまたは別のリレーションで指定されていないジョブは、このリレーションで定義されたジョブ間であっても、この車両のツアーのどこにでも挿入できます。
"relations": [
{
"type": "flexible",
"jobs": [
"job_1",
"job_2"
"job_4"
],
"vehicleId": "Vehicle_1_1"
}
]- ツアー - このリレーションで指定されたジョブは、この特定の車両によって実行される必要がありますが、ジョブの順序は変更できます。
"relations": [
{
"type": "tour",
"jobs": [
"job_1",
"job_2"
"job_4"
],
"vehicleId": "Vehicle_1_1"
}
]sequenceまたはflexibleリレーションに追加されたジョブについては、時間枠、スキル要件、積載量違反、集荷/配達の割り当て、ルーティングの可否などの制約違反がチェックされません。これにより、実現不可能なソリューションや望ましくないソリューションが生じる可能性があります。sequenceおよびflexibleリレーションと同様に、tourリレーションに追加されたジョブは通常、制約チェックの対象になりません。その結果、制約に違反する可能性のあるソリューションが導き出され、実行不可能になる可能性があります。ただし、特定のシナリオでは、ソルバーがリレーション内の既存の制約違反を修正する場合があります。
また、複数の集荷または配達を含むジョブではリレーションを使用できません (詳細については、「マルチジョブ」を参照)。
車両のリレーションに設定できるジョブの数に制限はありません。また、同じツアーのフリート内の異なる車両に対して複数のリレーションを組み合わせる場合にも制限はありません。
また、vehicleIdは車両のtype id+_indexであることに注意してください。今回のケースでは、車両のtype idはVehicle_1で、車両の数は3であるため、この例のvehicleIdはVehicle_1_1、Vehicle_1_2、Vehicle_1_3になります。
ツアーを再計画するときに「リレーション」が問題解決にどのような影響を与えるかを確認するために、いくつかの簡単な例を試してみましょう。
シーケンス
4つのジョブを実行するのに十分な積載量と対応するシフト時間がある車両が存在すると仮定します。これら4つのジョブのうち2つは、配達または集荷の場所が互いにあまり近くないにもかかわらず、何らかの方法でつながっているため、順番に実行する必要があります。通常、これらのジョブはツアー内でより有利に最適化されますが、リレーションタイプsequenceをジョブに設定しているため、順番にしか実行できません。簡単な問題の例は次のようになります。
{
"fleet": {
"types": [
{
"id": "Vehicle_1",
"profile": "car_1",
"costs": {
"fixed": 9.0,
"distance": 0.004,
"time": 0.005
},
"shifts": [
{
"start": {
"time": "2021-08-27T08:03:00Z",
"location": {
"lat": 52.530971,
"lng": 13.384915
}
},
"end": {
"time": "2021-08-27T18:03:00Z",
"location": {
"lat": 52.530971,
"lng": 13.384915
}
}
}
],
"capacity": [
10
],
"limits": {
"maxDistance": 300000,
"shiftTime": 43200
},
"amount": 1
}
],
"profiles": [
{
"type": "car",
"name": "car_1"
}
]
},
"plan": {
"jobs": [
{
"id": "job_1",
"tasks": {
"deliveries": [
{
"places": [
{
"times": [
[
"2021-08-27T09:03:00Z",
"2021-08-27T18:03:00Z"
]
],
"location": {
"lat": 52.59175589353722,
"lng": 13.350747750372257
},
"duration": 360
}
],
"demand": [
1
]
}
]
}
},
{
"id": "job_2",
"tasks": {
"deliveries": [
{
"places": [
{
"times": [
[
"2021-08-27T11:03:00Z",
"2021-08-27T20:03:00Z"
]
],
"location": {
"lat": 52.43363386232821,
"lng": 13.403232562191313
},
"duration": 540
}
],
"demand": [
1
]
}
]
}
},
{
"id": "job_3",
"tasks": {
"deliveries": [
{
"places": [
{
"times": [
[
"2021-08-27T10:03:00Z",
"2021-08-27T16:03:00Z"
]
],
"location": {
"lat": 52.473321658918245,
"lng": 13.28972099097991
},
"duration": 660
}
],
"demand": [
1
]
}
]
}
},
{
"id": "job_4",
"tasks": {
"deliveries": [
{
"places": [
{
"times": [
[
"2021-08-27T09:03:00Z",
"2021-08-27T17:03:00Z"
]
],
"location": {
"lat": 52.54165532725351,
"lng": 13.365047170290309
},
"duration": 1140
}
],
"demand": [
1
]
}
]
}
}
],
"relations": [
{
"type": "sequence",
"jobs": [
"job_1",
"job_4"
],
"vehicleId": "Vehicle_1_1"
}
]
}
}この問題の最初のソリューションを分析すると、車両が最初にjob_2とjob_3を実行し、その後リレーションで指定されたjob_1とjob_4を実行することがわかります。このように、ツアー中にいずれかの制約が変更され、ツアーが再計算された場合でも、順序リレーションのあるジョブは指定された順序で実行されます。
{
"statistic": {
"cost": 269.051,
"distance": 55254,
"duration": 7807,
"times": {
"driving": 5107,
"serving": 2700,
"waiting": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "Vehicle_1_1",
"typeId": "Vehicle_1",
"stops": [
{
"location": {
"lat": 52.530971,
"lng": 13.384915
},
"time": {
"arrival": "2021-08-27T08:03:00Z",
"departure": "2021-08-27T10:38:23Z"
},
"load": [
4
],
"activities": [
{
"jobId": "departure",
"type": "departure"
}
],
"distance": 0
},
{
"location": {
"lat": 52.43363386232821,
"lng": 13.403232562191311
},
"time": {
"arrival": "2021-08-27T11:03:00Z",
"departure": "2021-08-27T11:12:00Z"
},
"load": [
3
],
"activities": [
{
"jobId": "job_2",
"type": "delivery"
}
],
"distance": 14847
},
{
"location": {
"lat": 52.473321658918245,
"lng": 13.28972099097991
},
"time": {
"arrival": "2021-08-27T11:30:55Z",
"departure": "2021-08-27T11:41:55Z"
},
"load": [
2
],
"activities": [
{
"jobId": "job_3",
"type": "delivery"
}
],
"distance": 28933
},
{
"location": {
"lat": 52.59175589353722,
"lng": 13.350747750372255
},
"time": {
"arrival": "2021-08-27T12:03:55Z",
"departure": "2021-08-27T12:09:55Z"
},
"load": [
1
],
"activities": [
{
"jobId": "job_1",
"type": "delivery"
}
],
"distance": 45708
},
{
"location": {
"lat": 52.54165532725351,
"lng": 13.365047170290309
},
"time": {
"arrival": "2021-08-27T12:24:34Z",
"departure": "2021-08-27T12:43:34Z"
},
"load": [
0
],
"activities": [
{
"jobId": "job_4",
"type": "delivery"
}
],
"distance": 53145
},
{
"location": {
"lat": 52.530971,
"lng": 13.384915
},
"time": {
"arrival": "2021-08-27T12:48:30Z",
"departure": "2021-08-27T12:48:30Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival"
}
],
"distance": 55249
}
],
"statistic": {
"cost": 269.051,
"distance": 55254,
"duration": 7807,
"times": {
"driving": 5107,
"serving": 2700,
"waiting": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}job_3を実行した後、近くの場所のツアーにもう1つジョブが追加されたと仮定します。通常、job_5はjob_1の後に実行されますが、sequenceリレーションを考慮すると、job_1とjob_4の間にジョブを追加できません。そのため、再計画後にjob_5がリレーションの2つのジョブの前に実行されます。その後、job_1とjob_4が順番に実行されます。
{
"statistic": {
"cost": 147.98,
"distance": 28900,
"duration": 4676,
"times": {
"driving": 2816,
"serving": 1860,
"waiting": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "Vehicle_1_1",
"typeId": "Vehicle_1",
"stops": [
{
"location": {
"lat": 52.473321658918245,
"lng": 13.28972099097991
},
"time": {
"arrival": "2021-08-27T11:41:55Z",
"departure": "2021-08-27T11:41:55Z"
},
"load": [
3
],
"activities": [
{
"jobId": "departure",
"type": "departure"
}
],
"distance": 0
},
{
"location": {
"lat": 52.57175589353722,
"lng": 13.360747750372257
},
"time": {
"arrival": "2021-08-27T12:02:47Z",
"departure": "2021-08-27T12:08:47Z"
},
"load": [
2
],
"activities": [
{
"jobId": "job_5",
"type": "delivery"
}
],
"distance": 14847
},
{
"location": {
"lat": 52.59175589353722,
"lng": 13.350747750372255
},
"time": {
"arrival": "2021-08-27T12:15:16Z",
"departure": "2021-08-27T12:21:16Z"
},
"load": [
1
],
"activities": [
{
"jobId": "job_1",
"type": "delivery"
}
],
"distance": 28933
},
{
"location": {
"lat": 52.54165532725351,
"lng": 13.365047170290309
},
"time": {
"arrival": "2021-08-27T12:35:55Z",
"departure": "2021-08-27T12:54:55Z"
},
"load": [
0
],
"activities": [
{
"jobId": "job_4",
"type": "delivery"
}
],
"distance": 45708
},
{
"location": {
"lat": 52.530971,
"lng": 13.384915
},
"time": {
"arrival": "2021-08-27T12:59:51Z",
"departure": "2021-08-27T12:59:51Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival"
}
],
"distance": 53145
}
],
"statistic": {
"cost": 147.98,
"distance": 28900,
"duration": 4676,
"times": {
"driving": 2816,
"serving": 1860,
"waiting": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}フレキシブル
4つのジョブを実行するのに十分な積載量と対応するシフト時間がある車両が存在する状況をモデル化してみましょう。これら4つのジョブのうち2つ (job_1とjob_4) は、アルゴリズムが論理的に異なる順序で解決する場合でも、配送または集荷が何らかの方法でつながっているため、順番に実行する必要があります。また、これら2つのジョブのエリアでツアー中にいくつかの新しいジョブが発生する可能性を考慮する必要があるため、その車両でもそれらのジョブの実行を許可する必要があります。
この状況では、これらのジョブにflexibleリレーションを設定する必要があるため、リレーションからジョブを実行すると、他のジョブがツアーに追加される可能性があります。このような制約に関する簡単な問題の例は次のようになります。
{
"fleet": {
"types": [
{
"id": "Vehicle_1",
"profile": "car_1",
"costs": {
"fixed": 9.0,
"distance": 0.004,
"time": 0.005
},
"shifts": [
{
"start": {
"time": "2021-08-27T08:03:00Z",
"location": {
"lat": 52.530971,
"lng": 13.384915
}
},
"end": {
"time": "2021-08-27T18:03:00Z",
"location": {
"lat": 52.530971,
"lng": 13.384915
}
}
}
],
"capacity": [
10
],
"limits": {
"maxDistance": 300000,
"shiftTime": 43200
},
"amount": 1
}
],
"profiles": [
{
"type": "car",
"name": "car_1"
}
]
},
"plan": {
"jobs": [
{
"id": "job_1",
"tasks": {
"deliveries": [
{
"places": [
{
"times": [
[
"2021-08-27T09:03:00Z",
"2021-08-27T18:03:00Z"
]
],
"location": {
"lat": 52.59175589353722,
"lng": 13.350747750372257
},
"duration": 360
}
],
"demand": [
1
]
}
]
}
},
{
"id": "job_2",
"tasks": {
"deliveries": [
{
"places": [
{
"times": [
[
"2021-08-27T11:03:00Z",
"2021-08-27T20:03:00Z"
]
],
"location": {
"lat": 52.43363386232821,
"lng": 13.403232562191313
},
"duration": 540
}
],
"demand": [
1
]
}
]
}
},
{
"id": "job_3",
"tasks": {
"deliveries": [
{
"places": [
{
"times": [
[
"2021-08-27T10:03:00Z",
"2021-08-27T16:03:00Z"
]
],
"location": {
"lat": 52.473321658918245,
"lng": 13.28972099097991
},
"duration": 660
}
],
"demand": [
1
]
}
]
}
},
{
"id": "job_4",
"tasks": {
"deliveries": [
{
"places": [
{
"times": [
[
"2021-08-27T09:03:00Z",
"2021-08-27T17:03:00Z"
]
],
"location": {
"lat": 52.54165532725351,
"lng": 13.365047170290309
},
"duration": 1140
}
],
"demand": [
1
]
}
]
}
}
],
"relations": [
{
"type": "flexible",
"jobs": [
"job_1",
"job_4"
],
"vehicleId": "Vehicle_1_1"
}
]
}
}最初のソリューションからわかるように、ツアーではjob_4がjob_1の後に解決され、これら2つのジョブがリレーション外のジョブの後に解決されるようにツアーが最適化されました。
{
"statistic": {
"cost": 269.116,
"distance": 55254,
"duration": 7820,
"times": {
"driving": 5120,
"serving": 2700,
"waiting": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "Vehicle_1_1",
"typeId": "Vehicle_1",
"stops": [
{
"location": {
"lat": 52.530971,
"lng": 13.384915
},
"time": {
"arrival": "2021-08-27T08:03:00Z",
"departure": "2021-08-27T10:38:23Z"
},
"load": [
4
],
"activities": [
{
"jobId": "departure",
"type": "departure"
}
],
"distance": 0
},
{
"location": {
"lat": 52.43363386232821,
"lng": 13.403232562191311
},
"time": {
"arrival": "2021-08-27T11:03:00Z",
"departure": "2021-08-27T11:12:00Z"
},
"load": [
3
],
"activities": [
{
"jobId": "job_2",
"type": "delivery"
}
],
"distance": 14847
},
{
"location": {
"lat": 52.473321658918245,
"lng": 13.28972099097991
},
"time": {
"arrival": "2021-08-27T11:30:55Z",
"departure": "2021-08-27T11:41:55Z"
},
"load": [
2
],
"activities": [
{
"jobId": "job_3",
"type": "delivery"
}
],
"distance": 28933
},
{
"location": {
"lat": 52.59175589353722,
"lng": 13.350747750372255
},
"time": {
"arrival": "2021-08-27T12:04:08Z",
"departure": "2021-08-27T12:10:08Z"
},
"load": [
1
],
"activities": [
{
"jobId": "job_1",
"type": "delivery"
}
],
"distance": 45708
},
{
"location": {
"lat": 52.54165532725351,
"lng": 13.365047170290309
},
"time": {
"arrival": "2021-08-27T12:24:47Z",
"departure": "2021-08-27T12:43:47Z"
},
"load": [
0
],
"activities": [
{
"jobId": "job_4",
"type": "delivery"
}
],
"distance": 53145
},
{
"location": {
"lat": 52.530971,
"lng": 13.384915
},
"time": {
"arrival": "2021-08-27T12:48:43Z",
"departure": "2021-08-27T12:48:43Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival"
}
],
"distance": 55249
}
],
"statistic": {
"cost": 269.116,
"distance": 55254,
"duration": 7820,
"times": {
"driving": 5120,
"serving": 2700,
"waiting": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}job_3を実行した後、さらに2つのジョブ (job_5とjob_6) が近くの場所のツアーに追加されたと仮定します。通常、sequenceリレーションを使用すると、新しく追加されたjob_5とjob_6はjob_4の後に実行されます。ただし、flexibleリレーションではジョブをjob_1とjob_4の間に追加できるため、job_6がjob_1の前に実行され、依然としてツアー内で順番に解決されるjob_1とjob_4の間にjob_5が挿入されるようにツアーが最適化されます。
{
"statistic": {
"cost": 158.063,
"distance": 29782,
"duration": 5987,
"times": {
"driving": 3767,
"serving": 2220,
"waiting": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "Vehicle_1_1",
"typeId": "Vehicle_1",
"stops": [
{
"location": {
"lat": 52.473321658918245,
"lng": 13.28972099097991
},
"time": {
"arrival": "2021-08-27T11:41:55Z",
"departure": "2021-08-27T11:41:55Z"
},
"load": [
4
],
"activities": [
{
"jobId": "departure",
"type": "departure"
}
],
"distance": 0
},
{
"location": {
"lat": 52.52175589353722,
"lng": 13.357747750372257
},
"time": {
"arrival": "2021-08-27T12:00:23Z",
"departure": "2021-08-27T12:06:23Z"
},
"load": [
3
],
"activities": [
{
"jobId": "job_6",
"type": "delivery"
}
],
"distance": 14847
},
{
"location": {
"lat": 52.59175589353722,
"lng": 13.350747750372255
},
"time": {
"arrival": "2021-08-27T12:28:05Z",
"departure": "2021-08-27T12:34:05Z"
},
"load": [
2
],
"activities": [
{
"jobId": "job_1",
"type": "delivery"
}
],
"distance": 28933
},
{
"location": {
"lat": 52.55175589353722,
"lng": 13.357747750372257
},
"time": {
"arrival": "2021-08-27T12:46:57Z",
"departure": "2021-08-27T12:52:57Z"
},
"load": [
1
],
"activities": [
{
"jobId": "job_5",
"type": "delivery"
}
],
"distance": 45708
},
{
"location": {
"lat": 52.54165532725351,
"lng": 13.365047170290309
},
"time": {
"arrival": "2021-08-27T12:57:46Z",
"departure": "2021-08-27T13:16:46Z"
},
"load": [
0
],
"activities": [
{
"jobId": "job_4",
"type": "delivery"
}
],
"distance": 53145
},
{
"location": {
"lat": 52.530971,
"lng": 13.384915
},
"time": {
"arrival": "2021-08-27T13:21:42Z",
"departure": "2021-08-27T13:21:42Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival"
}
],
"distance": 55249
}
],
"statistic": {
"cost": 158.063,
"distance": 29782,
"duration": 5987,
"times": {
"driving": 3767,
"serving": 2220,
"waiting": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}ツアー
フリートに複数の車両があり、一部のジョブを特定の車両で実行する必要があり、実行順序が重要ではない場合は、tourリレーションを使用する必要があります。たとえば、2台の車両からなるフリートがあり、実行するジョブが6つあるとします。ここでの計画によれば、このリストの特定のジョブを実行するには2台の車両のうちの1台が必要です。どの車両が他の3つのジョブを実行するかは重要ではありません。したがって、この例では、job_1、job_2、job_3とのtourリレーションをVehicle_1_1に設定します。これは、Vehicle_1_1がそれらのジョブのみを実行し、他のジョブの実行が制限されるという意味ではなく、Vehicle_1_1のみがそれらのジョブを実行でき、Vehicle_1_2は実行できないことを意味します。このような制約の問題は次のようになります。
{
"fleet": {
"types": [
{
"id": "Vehicle_1",
"profile": "car",
"costs": {
"fixed": 10.0,
"distance": 0.002,
"time": 0.003
},
"shifts": [
{
"start": {
"time": "2021-10-23T10:16:40Z",
"location": {
"lat": 51.08511,
"lng": 13.76875
}
},
"end": {
"time": "2021-10-23T17:00:00Z",
"location": {
"lat": 51.059188,
"lng": 13.540317
}
}
}
],
"capacity": [
5
],
"amount": 1
},
{
"id": "Vehicle_2",
"profile": "car",
"costs": {
"fixed": 12.0,
"distance": 0.002,
"time": 0.002
},
"shifts": [
{
"start": {
"time": "2021-10-23T08:00:00Z",
"location": {
"lat": 51.059188,
"lng": 13.540317
}
},
"end": {
"time": "2021-10-23T19:00:00Z",
"location": {
"lat": 51.059188,
"lng": 13.540317
}
}
}
],
"capacity": [
5
],
"amount": 1
}
],
"profiles": [
{
"type": "car",
"name": "car"
}
]
},
"plan": {
"jobs": [
{
"id": "Job_1",
"tasks": {
"deliveries": [
{
"places": [
{
"times": [
[
"2021-10-23T12:30:00Z",
"2021-10-23T14:00:00Z"
]
],
"location": {
"lat": 51.05238,
"lng": 13.74114
},
"duration": 1800
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_2",
"tasks": {
"deliveries": [
{
"places": [
{
"times": [
[
"2021-10-23T12:05:00Z",
"2021-10-23T17:30:00Z"
]
],
"location": {
"lat": 51.06099,
"lng": 13.75245
},
"duration": 2000
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_3",
"tasks": {
"deliveries": [
{
"places": [
{
"times": [
[
"2021-10-23T13:35:00Z",
"2021-10-23T17:00:00Z"
]
],
"location": {
"lat": 51.08511,
"lng": 13.76875
},
"duration": 1800
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_4",
"tasks": {
"deliveries": [
{
"places": [
{
"times": [
[
"2021-10-23T10:05:00Z",
"2021-10-23T10:30:00Z"
]
],
"location": {
"lat": 51.1323847,
"lng": 13.7779515
},
"duration": 2000
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_5",
"tasks": {
"deliveries": [
{
"places": [
{
"times": [
[
"2021-10-23T16:35:00Z",
"2021-10-23T17:00:00Z"
]
],
"location": {
"lat": 51.11716,
"lng": 13.73054
},
"duration": 1800
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_6",
"tasks": {
"deliveries": [
{
"places": [
{
"times": [
[
"2021-10-23T11:05:00Z",
"2021-10-23T11:30:00Z"
]
],
"location": {
"lat": 51.12308,
"lng": 13.76406
},
"duration": 2000
}
],
"demand": [
1
]
}
]
}
}
],
"relations": [
{
"type": "tour",
"jobs": [
"Job_1",
"Job_2",
"Job_3"
],
"vehicleId": "Vehicle_1_1"
}
]
}
}最初のソリューションからわかるように、Vehicle_1_1は、tourリレーションで指定されたjob_1、job_2、job_3だけでなく、job_4とjob_6も実行します。さらに、実行順序によって、リレーション内のジョブの順序 (job_2、job_1、およびその後のjob_3) は維持されません。Vehicle_2_1は順番が回ってくるとjob_5のみを実行します。
{
"statistic": {
"cost": 251.099,
"distance": 88444,
"duration": 18630,
"times": {
"driving": 6068,
"serving": 11400,
"waiting": 1162,
"break": 0
}
},
"tours": [
{
"vehicleId": "Vehicle_1_1",
"typeId": "Vehicle_1",
"stops": [
{
"location": {
"lat": 51.08511,
"lng": 13.76875
},
"time": {
"arrival": "2021-10-23T10:16:40Z",
"departure": "2021-10-23T10:19:10Z"
},
"load": [
5
],
"activities": [
{
"jobId": "departure",
"type": "departure"
}
],
"distance": 0
},
{
"location": {
"lat": 51.1323847,
"lng": 13.7779515
},
"time": {
"arrival": "2021-10-23T10:30:00Z",
"departure": "2021-10-23T11:03:20Z"
},
"load": [
4
],
"activities": [
{
"jobId": "Job_4",
"type": "delivery"
}
],
"distance": 6555
},
{
"location": {
"lat": 51.12308,
"lng": 13.76406
},
"time": {
"arrival": "2021-10-23T11:07:30Z",
"departure": "2021-10-23T11:40:50Z"
},
"load": [
3
],
"activities": [
{
"jobId": "Job_6",
"type": "delivery"
}
],
"distance": 8361
},
{
"location": {
"lat": 51.06099,
"lng": 13.75245
},
"time": {
"arrival": "2021-10-23T11:54:33Z",
"departure": "2021-10-23T12:38:20Z"
},
"load": [
2
],
"activities": [
{
"jobId": "Job_2",
"type": "delivery"
}
],
"distance": 16515
},
{
"location": {
"lat": 51.05238,
"lng": 13.74114
},
"time": {
"arrival": "2021-10-23T12:44:20Z",
"departure": "2021-10-23T13:14:20Z"
},
"load": [
1
],
"activities": [
{
"jobId": "Job_1",
"type": "delivery"
}
],
"distance": 18811
},
{
"location": {
"lat": 51.08511,
"lng": 13.76875
},
"time": {
"arrival": "2021-10-23T13:26:05Z",
"departure": "2021-10-23T14:05:00Z"
},
"load": [
0
],
"activities": [
{
"jobId": "Job_3",
"type": "delivery"
}
],
"distance": 24558
},
{
"location": {
"lat": 51.059188,
"lng": 13.540317
},
"time": {
"arrival": "2021-10-23T14:28:21Z",
"departure": "2021-10-23T14:28:21Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival"
}
],
"distance": 48802
}
],
"statistic": {
"cost": 152.46499999999997,
"distance": 48806,
"duration": 14951,
"times": {
"driving": 4189,
"serving": 9600,
"waiting": 1162,
"break": 0
}
},
"shiftIndex": 0
},
{
"vehicleId": "Vehicle_2_1",
"typeId": "Vehicle_2",
"stops": [
{
"location": {
"lat": 51.059188,
"lng": 13.540317
},
"time": {
"arrival": "2021-10-23T08:00:00Z",
"departure": "2021-10-23T16:18:57Z"
},
"load": [
1
],
"activities": [
{
"jobId": "departure",
"type": "departure"
}
],
"distance": 0
},
{
"location": {
"lat": 51.11716,
"lng": 13.73054
},
"time": {
"arrival": "2021-10-23T16:35:00Z",
"departure": "2021-10-23T17:05:00Z"
},
"load": [
0
],
"activities": [
{
"jobId": "Job_5",
"type": "delivery"
}
],
"distance": 19957
},
{
"location": {
"lat": 51.059188,
"lng": 13.540317
},
"time": {
"arrival": "2021-10-23T17:20:16Z",
"departure": "2021-10-23T17:20:16Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival"
}
],
"distance": 39636
}
],
"statistic": {
"cost": 98.63400000000001,
"distance": 39638,
"duration": 3679,
"times": {
"driving": 1879,
"serving": 1800,
"waiting": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}Vehicle_1_1が最初の2つのジョブ (job_4とjob_6) を実行した後、別の3つのジョブ (job_7、job_8、job_9) がツアーに追加されたと仮定します。再計画後、ソリューションは変更されましたが、それでも、tourリレーション内のジョブはVehicle_1_1による実行のために残されています。ここで、Vehicle_1_1はjob_1、job_3、job_2、job_7を実行するツアーを続行します。Vehicle_1_2は順番が回ってくるとjob_9、job_5、job_8と進みます。
{
"statistic": {
"cost": 288.165,
"distance": 106927,
"duration": 20372,
"times": {
"driving": 6972,
"serving": 13400,
"waiting": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "Vehicle_1_1",
"typeId": "Vehicle_1",
"stops": [
{
"location": {
"lat": 51.08511,
"lng": 13.76875
},
"time": {
"arrival": "2021-10-23T12:38:20Z",
"departure": "2021-10-23T12:41:08Z"
},
"load": [
4
],
"activities": [
{
"jobId": "departure",
"type": "departure"
}
],
"distance": 0
},
{
"location": {
"lat": 51.05238,
"lng": 13.74114
},
"time": {
"arrival": "2021-10-23T12:53:15Z",
"departure": "2021-10-23T13:23:15Z"
},
"load": [
3
],
"activities": [
{
"jobId": "Job_1",
"type": "delivery"
}
],
"distance": 6555
},
{
"location": {
"lat": 51.08511,
"lng": 13.76875
},
"time": {
"arrival": "2021-10-23T13:35:00Z",
"departure": "2021-10-23T14:05:00Z"
},
"load": [
2
],
"activities": [
{
"jobId": "Job_3",
"type": "delivery"
}
],
"distance": 8361
},
{
"location": {
"lat": 51.06099,
"lng": 13.75245
},
"time": {
"arrival": "2021-10-23T14:13:04Z",
"departure": "2021-10-23T14:46:24Z"
},
"load": [
1
],
"activities": [
{
"jobId": "Job_2",
"type": "delivery"
}
],
"distance": 16515
},
{
"location": {
"lat": 51.09099,
"lng": 13.65245
},
"time": {
"arrival": "2021-10-23T15:04:39Z",
"departure": "2021-10-23T15:37:59Z"
},
"load": [
0
],
"activities": [
{
"jobId": "Job_7",
"type": "delivery"
}
],
"distance": 18811
},
{
"location": {
"lat": 51.059188,
"lng": 13.540317
},
"time": {
"arrival": "2021-10-23T15:53:55Z",
"departure": "2021-10-23T15:53:55Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival"
}
],
"distance": 24558
}
],
"statistic": {
"cost": 126.51100000000001,
"distance": 40905,
"duration": 11567,
"times": {
"driving": 3967,
"serving": 7600,
"waiting": 0,
"break": 0
}
},
"shiftIndex": 0
},
{
"vehicleId": "Vehicle_2_1",
"typeId": "Vehicle_2",
"stops": [
{
"location": {
"lat": 51.059188,
"lng": 13.540317
},
"time": {
"arrival": "2021-10-23T08:00:00Z",
"departure": "2021-10-23T15:41:33Z"
},
"load": [
3
],
"activities": [
{
"jobId": "departure",
"type": "departure"
}
],
"distance": 0
},
{
"location": {
"lat": 51.16099,
"lng": 13.75245
},
"time": {
"arrival": "2021-10-23T15:58:41Z",
"departure": "2021-10-23T16:32:01Z"
},
"load": [
2
],
"activities": [
{
"jobId": "Job_9",
"type": "delivery"
}
],
"distance": 19957
},
{
"location": {
"lat": 51.11716,
"lng": 13.73054
},
"time": {
"arrival": "2021-10-23T16:45:55Z",
"departure": "2021-10-23T17:15:55Z"
},
"load": [
1
],
"activities": [
{
"jobId": "Job_5",
"type": "delivery"
}
],
"distance": 24558
},
{
"location": {
"lat": 51.11099,
"lng": 13.70245
},
"time": {
"arrival": "2021-10-23T17:20:46Z",
"departure": "2021-10-23T17:54:06Z"
},
"load": [
0
],
"activities": [
{
"jobId": "Job_8",
"type": "delivery"
}
],
"distance": 39636
},
{
"location": {
"lat": 51.059188,
"lng": 13.540317
},
"time": {
"arrival": "2021-10-23T18:08:18Z",
"departure": "2021-10-23T18:08:18Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival"
}
],
"distance": 48802
}
],
"statistic": {
"cost": 161.654,
"distance": 66022,
"duration": 8805,
"times": {
"driving": 3005,
"serving": 5800,
"waiting": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}注
If you got some unassigned jobs in the solution when using the
tourrelation, and you still need those jobs to be assigned, then you should use the higher priority for them, or usesequenceorflexibletype of relations which guarantees assignment.
次のステップ
詳細については、以下を参照してください。
- Submit a Vehicle Routing Problem to solve it synchronously (車両ルート検索問題を送信して同期的に解決する)
- Submit a Vehicle Routing Problem to solve it asynchronously (車両ルート検索問題を送信して非同期的に解決する)
26 日前の更新