ガイドAPIリファレンス
ガイド

休憩時間を組み込む

HERE Tour Planning APIでは、ルート中の休憩期間のタイミングと長さを指定できます。ルートの休憩期間を効率的にスケジューリングすることは、次の点で重要です。

  • 全体的なルート効率とルート中のドライバーの快適さを最適化する。
  • 交通機関などの地方自治体によって制定された法的規制または推奨事項を遵守する。
📘

現在この機能はベータ版です。ベータ機能は開発の最終段階にあり、重大なバグは存在しませんが、カバレッジ、品質、パフォーマンス、またはテストカバレッジがまだ最終形ではない可能性があります。この機能のデータモデルおよび問題定義は、以前のバージョンから安定しており変更されていません。本番環境での完全な利用に向けて機能が完成に近づく中で、動作の細かな調整が行われる可能性があることを理解した上で、ベータ機能をアプリケーションで使用できます。

詳細については、「テスト段階の機能の詳細」を参照してください。

休憩時間の設定を理解する

HERE Tour Planning APIではfleet.types.shifts problem設定内のrestTimesオブジェクトを使用して、フリートの休憩期間を指定できます。

📘

問題のコンテキストでrestTimesbreaksを同時に使用することはできません。

HERE Tour Planning APIは次のタイプの休憩期間を区別します。

  • driving:特定の総運転時間の後に特に必要となる休憩または休憩期間を指し、その間に停車が許可されます。ただし、この合計時間にカウントされるのは能動的に運転した時間のみです。
  • working:運転に加えて、商品の集荷や配送など、その他すべての業務に関連する活動に関連する期間を指します。

フリートのシフト設定を定義する際に、ドライバーの休憩、リラックス、回復の期間を、固定breaksまたはrestTimesのいずれかで指定できます。1つの問題にbreaksrestTimesを同時に含めることはできませんが、workingbreakingの休憩時間を混在させることはできます。シフト設定にworking休憩時間とdriving休憩時間の両方を同時に含めると、ソリューションを法律に準拠させることができます (現地の交通規制を反映した間隔を特定し駐車が許可されている場所で停車するようスケジュールした場合)。また、ドライバーの安全性と業務効率も最適化されます。休憩期間タイプごとに次のプロパティを指定できます。

  • type:現在、このプロパティとして指定できるタイプはfixedDurationのみです。
  • interval:休憩を取るべき頻度 (単位:秒) を指定します。
  • breakDuration:休憩時間 (単位:秒) を指定します。

次のサンプルrestTimesオブジェクト設定を考えてみましょう。

"restTimes": {
  "driving": {
    "type": "fixedDuration",
    "interval": 16200,
    "breakDuration": 2700
  },
  "working": {
    "type": "fixedDuration",
    "interval": 21600,
    "breakDuration": 1800
  }
}

前の例に基づいて、最適化アルゴリズムは次のように休憩時間を適用します。

  • 運転休憩時間
    • 4.5運転時間ごとに、ドライバーは運転から離れて休憩を取ることが義務付けられています。
    • この休憩は、restTimeでより長い時間を指定した場合を除いて、きっかり45分である必要があります。
  • 作業休憩時間
    • すべての業務関連活動 (運転を含む) において、ドライバーは6時間ごとに休憩を取ることが義務付けられています。

    • この休憩はきっかり30分である必要があります (restTimeでより長い時間を指定した場合を除く)。

      📘

      前の例では、45分の別のrestTimeを指定しているため、この作業のrestTimeの実際の長さは45分です。

シナリオ1:単一の休憩時間タイプの問題

次の例では、長距離にわたる6つのジョブで構成されるルートのルートプランの問題を示しています。問題の仕様には2時間 (7200秒) ごとに休憩が含まれています。休憩時間は30分 (1800秒) に設定されています。

Click to expand/collapse the sample JSON
{
  "fleet": {
    "types": [
      {
        "id": "vehicle_1",
        "profile": "normal_car",
        "costs": { "fixed": 22, "distance": 0.0002, "time": 0.0048 },
        "shifts": [
          {
            "start": {
              "time": "2023-09-20T08:09:00Z",
              "location": {
                "lat": 52.510945865670074,
                "lng": 13.393829563633428
              }
            },
            "end": {
              "time": "2023-09-20T20:09:00Z",
              "location": {
                "lat": 52.510945865670074,
                "lng": 13.393829563633428
              }
            },
            "restTimes": {
              "working": {
                "type": "fixedDuration",
                "interval": 7200,
                "breakDuration": 1800
              }
            }
          }
        ],
        "capacity": [10],
        "amount": 10
      }
    ],
    "profiles": [{ "name": "normal_car", "type": "car" }]
  },
  "plan": {
    "jobs": [
      {
        "id": "Job_1",
        "tasks": {
          "pickups": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.5063267065751,
                    "lng": 14.345924039737517
                  },
                  "duration": 180
                }
              ],
              "demand": [1]
            }
          ]
        }
      },
      {
        "id": "Job_2",
        "tasks": {
          "pickups": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.12369910922764,
                    "lng": 14.384487171627224
                  },
                  "duration": 180
                }
              ],
              "demand": [1]
            }
          ]
        }
      },
      {
        "id": "Job_3",
        "tasks": {
          "pickups": [
            {
              "places": [
                {
                  "location": {
                    "lat": 51.94851653436735,
                    "lng": 13.515333506728455
                  },
                  "duration": 180
                }
              ],
              "demand": [1]
            }
          ]
        }
      },
      {
        "id": "Job_4",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.22193780582256,
                    "lng": 13.011046397401525
                  },
                  "duration": 180
                }
              ],
              "demand": [1]
            }
          ]
        }
      },
      {
        "id": "Job_5",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.4756213511033,
                    "lng": 13.049609529291232
                  },
                  "duration": 180
                }
              ],
              "demand": [1]
            }
          ]
        }
      },
      {
        "id": "Job_6",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {
                    "lat": 52.44851058488946,
                    "lng": 13.384812137255604
                  },
                  "duration": 180
                }
              ],
              "demand": [1]
            }
          ]
        }
      }
    ]
  }
}

次の図は前の問題のソリューションを示しており、問題の使用で義務付けられている休憩時間を超えずに、2時間の作業 (運転時間と180秒の追加ジョブ時間を含む) ごとに生じる作業休憩時間を強調表示しています。

作業休憩時間を含むソリューション
📘

前の例と次の例では、restTimes機能について次の点を考慮してください。

  • 最適なルートプランを実現するために、アルゴリズムは作業間隔または運転間隔内の任意の時点に休憩時間を割り当てる場合があります。重要なのは、これにより間隔内の指定された時間が経過した後に休憩が発生しないよう徹底されることです。
  • アルゴリズムはルート上の任意の場所で休憩時間をスケジュールする可能性があります。
  • 作業休憩がジョブと重なる場合、そのジョブは作業休憩時間を含めるよう時間が延長されます。
  • 運転休憩時間が作業休憩時間と重なる場合、このソリューションでは必ず長い方の休憩時間が表示されます。
  • このアルゴリズムでは長時間の作業中に十分な休憩を確保することを優先するため、ジョブの時間が長い場合は休憩を作業休憩時間として分類する傾向があります。

シナリオ2:運転休憩時間と作業休憩時間の問題

このシナリオでは、workingdrivingの2つの休憩時間のタイプがあります。作業休憩時間は6時間間隔であるのに対し、運転休憩時間は4.5時間間隔です。このような間隔内で、個人には作業時間中は30分の休憩、運転時間中は45分の休憩が割り当てられます。ルートプラン内の各ジョブの所要時間は45分です。

📘

ヒント

運転期間と作業期間を理解しやすくするために、次の問題のジョブIDはスタート地点から各ジョブの場所までの移動に必要な時間に関する情報を提供します。

Click to expand/collapse the sample JSON
{
  "fleet": {
    "types": [
      {
        "id": "vehicle_1",
        "profile": "normal_truck",
        "costs": { "fixed": 22, "distance": 0.0002, "time": 0.0048 },
        "shifts": [
          {
            "start": { "time": "2023-09-20T08:00:00Z" },
            "end": {
              "time": "2023-09-22T23:00:00Z",
              "location": { "lat": 50.912724, "lng": 7.1055 }
            },
            "restTimes": {
              "working": {
                "type": "fixedDuration",
                "interval": 21600,
                "breakDuration": 1800
              },
              "driving": {
                "type": "fixedDuration",
                "interval": 16200,
                "breakDuration": 2700
              }
            }
          }
        ],
        "capacity": [10],
        "amount": 1
      }
    ],
    "profiles": [
      {
        "name": "normal_truck",
        "type": "truck",
        "traffic": { "mode": "disabled" }
      }
    ]
  },
  "plan": {
    "jobs": [
      {
        "id": "Job_1_15min_driving",
        "tasks": {
          "pickups": [
            {
              "places": [
                {
                  "location": { "lat": 48.934196, "lng": 12.687835 },
                  "duration": 2700
                }
              ],
              "demand": [1]
            }
          ]
        }
      },
      {
        "id": "Job_2_30min_driving",
        "tasks": {
          "pickups": [
            {
              "places": [
                {
                  "location": { "lat": 48.995801, "lng": 12.404328 },
                  "duration": 2700
                }
              ],
              "demand": [1]
            }
          ]
        }
      },
      {
        "id": "Job_3_1h_driving",
        "tasks": {
          "pickups": [
            {
              "places": [
                {
                  "location": { "lat": 49.066063, "lng": 11.917153 },
                  "duration": 2700
                }
              ],
              "demand": [1]
            }
          ]
        }
      },
      {
        "id": "Job_4_1h30min_driving",
        "tasks": {
          "pickups": [
            {
              "places": [
                {
                  "location": { "lat": 49.312421, "lng": 11.534065 },
                  "duration": 2700
                }
              ],
              "demand": [1]
            }
          ]
        }
      },
      {
        "id": "Job_5_2h_driving",
        "tasks": {
          "pickups": [
            {
              "places": [
                {
                  "location": { "lat": 49.526849, "lng": 11.066198 },
                  "duration": 2700
                }
              ],
              "demand": [1]
            }
          ]
        }
      },
      {
        "id": "Job_6_3h_driving",
        "tasks": {
          "pickups": [
            {
              "places": [
                {
                  "location": { "lat": 49.785296, "lng": 10.129362 },
                  "duration": 2700
                }
              ],
              "demand": [1]
            }
          ]
        }
      },
      {
        "id": "Job_7_4h_driving",
        "tasks": {
          "pickups": [
            {
              "places": [
                {
                  "location": { "lat": 49.992149, "lng": 9.153357 },
                  "duration": 2700
                }
              ],
              "demand": [1]
            }
          ]
        }
      },
      {
        "id": "Job_8_5h_driving",
        "tasks": {
          "pickups": [
            {
              "places": [
                {
                  "location": { "lat": 50.278779, "lng": 8.241558 },
                  "duration": 2700
                }
              ],
              "demand": [1]
            }
          ]
        }
      },
      {
        "id": "Job_9_6h_driving",
        "tasks": {
          "pickups": [
            {
              "places": [
                {
                  "location": { "lat": 50.672214, "lng": 7.301027 },
                  "duration": 2700
                }
              ],
              "demand": [1]
            }
          ]
        }
      }
    ]
  }
}

次の図は前の問題に対する最終的なソリューションを示しています。

運転休憩時間と作業休憩時間を含むソリューション

この可視化が示すように、前の問題のソリューションには両方のタイプの休憩時間が含まれています。

  • driving休憩時間:間隔のしきい値である4.5時間が経過するまでの約2時間
  • working休憩時間:間隔のしきい値である6時間が経過するまでの16

アルゴリズムは計画されたルートで最大限の効率を実現するために、時間の観点から見て最適な間隔でこのような休憩を戦略的に割り当てています。また、これは休憩時間の上限を超えずに (つまり過度の運転時間や作業時間を回避して)、必要な休憩回数を必要最小限に抑えて実現されています。

📘

次の例では、restTimes機能について次の点を考慮してください。

  • workingdrivingの両方の休憩時間が指定されている場合、アルゴリズムでは休憩に長い時間を確保します。最初にどちらのスケジュールが設定されていたかは関係ありません。たとえば、運転休憩時間が30分で作業休憩時間が45分の場合、作業休憩時間が先に達すると、休憩時間は45分となります。

  • 最適化アルゴリズムが休憩時間をスケジュールすると、他のタイプ休憩時間のタイマーもリセットされます。たとえば作業時間のスケジュールが設定されているものの、その時点で2時間の運転も終えている場合、作業休憩時間をスケジュールすると運転時間カウンターがリセットされます。これにより、運転時間が長すぎるために新たな休憩時間がすぐにスケジュールが設定されてしまうのを回避できます。

次のステップ

  • HERE Tour Planning APIで問題を作成する方法の詳細については、「問題」を参照してください。
  • HERE Tour Planning APIのメソッド、エンドポイント、パラメーターの詳細については、「APIリファレンス」を参照してください。