這個範例說明如何使用轉移屬性,優先安排由同一輛車在一個時段內,在附近取貨和送貨的路線。如要進一步瞭解轉換屬性,請參閱「使用轉換屬性建立商業邏輯模型」。
在這個例子中:
- 貨件 A、B 和 C 的送達地點在同一條路上,彼此距離很近。
- 未來還會推出更多功能。
- 外送訂單沒有指定送達時間。
- 無論造訪時間表為何,車輛都必須行駛這條道路兩次:一次是早上從車輛調度中心出發,另一次是晚上返回。
- 無論 A、B 和 C 的執行時間為何,路線的整體移動距離和時間長度一律相同。

在這種情況下,如果要求僅使用每小時費用和每公里費用,最佳化路線可能會在上午處理 A 和 B,並在晚上處理 C,而解決方案的費用與同時處理這三項作業的費用相同。
每公里費用 (設有門檻)
如要將鄰近造訪地點分組,請先選取距離門檻。這是指兩個造訪地點之間的最大距離,超過這個距離就不算在附近。這個範例使用的閾值為 100 公尺,大約相當於市區的一個街區。您可以根據業務需求和駕駛偏好,提高或降低門檻。
如要將彼此相距 100 公尺內的鄰近造訪次數歸為一組,請為每次轉換的前 100 公尺設定較高的費用,並為轉換的任何額外公尺設定較低的費用。由於前 100 公尺的費用最高,因此最佳化工具會使用短於 100 公尺門檻的轉場,盡可能節省費用,即使這代表會延長路線的整體長度。
如要設定費用,請在 ShipmentModel.transition_attributes 中新增項目,並提供下列屬性:
- 如要比對所有可能的轉移,請選取模型中任何位置都未使用的標記,例如
UNUSED_TAG。將TransitionAttributes.excluded_src_tag和TransitionAttributes.excluded_dst_tag設為這個標記。 - 使用門檻距離和費用設定
TransitionAttributes.distance_limit:- 將
DistanceLimit.soft_max_meters設為所選門檻。 - 將
DistanceLimit.cost_per_kilometer_below_soft_max設為低於門檻的每公里費用。 - 將
DistanceLimit.cost_per_kilometer_above_soft_max設為超過門檻的每公里費用。
- 將
{
"model": {
"transitionAttributes": [
{
"excluded_dst_tag": "UNUSED_TAG",
"excluded_src_tag": "UNUSED_TAG",
"distanceLimit": {
"softMaxMeters": 100,
"costPerKilometerBelowSoftMax": 50,
"costPerKilometerAboveSoftMax": 1,
}
}
]
}
}
任何運送或車輛都不得使用 #unused_tag# 標記來比對所有可能的轉移。詳情請參閱「如何比對所有造訪要求」。
「低於門檻的高費用」運作方式
本節說明成本高於和低於門檻時,對範例情境中不同解決方案總成本的影響。
解決方案 1:去程執行 A 和 B,回程執行 C
在這個解決方案中,運送作業會分成兩次行經這條道路。其中兩個會在第一次遍歷時傳送,其餘一個則會在第二次遍歷時傳送。共有 5 種轉場效果:
| 轉移 | 距離 | 低於門檻 | 高於門檻 | ||
|---|---|---|---|---|---|
| 距離 | 費用 | 距離 | 費用 | ||
| depot →A | 1000 公尺 | 100 公尺 | 5 | 900 公尺 | 0.9 |
| A→B | 50 公尺 | 50 公尺 | 2.5 | 0 公尺 | 0 |
| B→其他 | 1030 公尺 | 100 公尺 | 5 | 930 公尺 | 0.93 |
| other→C | 1000 公尺 | 100 公尺 | 5 | 900 公尺 | 0.9 |
| C→depot | 1080 公尺 | 100 公尺 | 5 | 980 公尺 | 0.98 |
| 總計 | 450 公尺 | 22.5 | 3710 公尺 | 3.71 | |
整體費用是每公里兩項費用的總和:
- 低於門檻的每公里費用 (50) 乘以低於門檻的總行駛距離 (450 公尺 = 0.45 公里)。
- 超過門檻的每公里費用 (1) 乘以超過門檻的總行經距離 (3710 公尺 = 3.71 公里)。
因此,整體費用為 0.45 * 50 + 3.71 * 1 = 22.5 + 3.71 = 26.21。
解決方法 2:在前往目的地時執行 A、B、C,返回時則不執行任何動作
與解決方案 1 不同,在這個解決方案中,所有三件貨件都會在一次道路遍歷期間「以群組形式」交付。在另一趟行程中,車輛完全不會停靠。同樣地,這裡有 5 個轉場效果,但長度和組成方式不同:
| 轉移 | 距離 | 低於門檻 | 高於門檻 | ||
|---|---|---|---|---|---|
| 距離 | 費用 | 距離 | 費用 | ||
| depot →A | 1000 公尺 | 100 公尺 | 5 | 900 公尺 | 0.9 |
| A→B | 50 公尺 | 50 公尺 | 2.5 | 0 公尺 | 0 |
| B→C | 30 公尺 | 30 公尺 | 1.5 | 0 公尺 | 0 |
| C→其他 | 1000 公尺 | 100 公尺 | 5 | 900 公尺 | 0.9 |
| other→depot | 2080 公尺 | 100 公尺 | 5 | 1980 公尺 | 1.98 |
| 總計 | 380 公尺 | 19 | 3780 公尺 | 3.78 | |
使用與解決方案 1 相同的計算方式,總成本為 0.38 * 50 + 3.78 * 1 = 19 + 3.78 = 22.78,因此一次完成所有拜訪的成本,會比分兩組完成的成本更低。您可以增加 DistanceLimit.cost_per_kilometer_below_soft_max 來強化這個效果。
為什麼每公里費用低於門檻時無法運作
由於您偏好短程轉移,而非長程轉移,因此可能會想為長程轉移設定較高的每公里費用,並為短程轉移保留較低的每公里費用。但這實際上會產生反效果:由於轉換的前 100 公尺最便宜,最佳化工具會盡量使用這些「便宜」的公尺,因此偏好接近或超過 100 公尺的轉換。
您可以在兩個範例解決方案中看到這種效果。如果將門檻以下和以上的每公里費用對調,路線費用就會改變:
| 高於門檻的高成本 | 高成本低於門檻 | |||
|---|---|---|---|---|
| 解決方案 1 | 解決方案 2 | 解決方案 1 | 解決方案 2 | |
| 公里數低於門檻 | 0.45 | 0.38 | 0.45 | 0.38 |
| 每公里費用低於門檻 | 1.00 | 1.00 | 50.00 | 50.00 |
| 高於門檻的公里數 | 3.71 | 3.78 | 3.71 | 3.78 |
| 超過門檻的每公里費用 | 50.00 | 50.00 | 1.00 | 1.00 |
| 總費用 | 185.95 | 189.38 | 26.21 | 22.78 |
在每個版本中,總費用較低的解決方案會以粗體醒目顯示。您可以看到,當您使用高於門檻的高成本時,造訪分組的路線總成本現在會較高,這與您想要達成的目標相反。