Beispiel: Zeiträume

In diesem Beispiel wird gezeigt, wie Sie mit timeWindows Abhol- und Lieferzeiten für Sendungen festlegen.

Eine vollständige konzeptionelle Übersicht und weitere Informationen zur Verwendung von timeWindows finden Sie im Dokument Konzept für den Schlüssel für Zeiträume.

Szenario 1: Lieferung innerhalb von Zeitfenstern

Im folgenden Beispiel wird ein Szenario veranschaulicht, in dem ein einzelnes Fahrzeug drei Sendungen innerhalb des angegebenen timeWindows ausliefern muss.

Beispielanfrage

Diese Anfrage umfasst drei Sendungen mit jeweils unterschiedlichen Lieferadressen (TimeWindow):

  • shipments[0] Lieferfenster: 18:00 – 19:00 Uhr
  • shipments[1] Lieferfenster: 18:00–18:30 Uhr
  • shipments[2] Lieferfenster: 17:30–18:00 Uhr

Beispielanfrage mit Zeiträumen ansehen

{
  "populatePolylines": false,
  "populateTransitionPolylines": false,
  "model": {
    "globalStartTime": "2023-01-13T16:00:00Z",
    "globalEndTime": "2023-01-14T16:00:00Z",
    "shipments": [
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789456,
              "longitude": -122.390192
            },
            "duration": "250s",
            "timeWindows": [
              {
                "startTime": "2023-01-13T18:00:00Z",
                "endTime": "2023-01-13T19:00:00Z"
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 100.0
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789116,
              "longitude": -122.395080
            },
            "duration": "250s",
            "timeWindows": [
              {
                "startTime": "2023-01-13T18:00:00Z",
                "endTime": "2023-01-13T18:30:00Z"
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 20.0
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.795242,
              "longitude": -122.399347
            },
            "duration": "250s",
            "timeWindows": [
              {
                "startTime": "2023-01-13T17:30:00Z",
                "endTime": "2023-01-13T18:00:00Z"
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 50.0
      }
    ],
    "vehicles": [
      {
        "endLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "startLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "costPerHour": 40.0,
        "costPerKilometer": 10.0
      }
    ]
  }
}
    

Beispielantwort

Die Antwort zeigt, dass der Optimierer die einzelnen visits so plant, dass die Zeitfenster eingehalten werden. Sendungen mit früheren Zeitfenstern werden zuerst zugestellt.

Antwort auf die Beispielanfrage mit Zeiträumen

{
  "routes": [
    {
      "vehicleStartTime": "2023-01-13T17:35:50Z",
      "vehicleEndTime": "2023-01-13T18:17:24Z",
      "visits": [
        {
          "isPickup": true,
          "startTime": "2023-01-13T17:35:50Z",
          "detour": "0s"
        },
        {
          "shipmentIndex": 1,
          "isPickup": true,
          "startTime": "2023-01-13T17:38:20Z",
          "detour": "150s"
        },
        {
          "shipmentIndex": 2,
          "isPickup": true,
          "startTime": "2023-01-13T17:40:50Z",
          "detour": "300s"
        },
        {
          "shipmentIndex": 2,
          "startTime": "2023-01-13T17:50:09Z",
          "detour": "0s"
        },
        {
          "shipmentIndex": 1,
          "startTime": "2023-01-13T18:00:00Z",
          "detour": "796s"
        },
        {
          "startTime": "2023-01-13T18:07:35Z",
          "detour": "1520s"
        }
      ],
      "transitions": [
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T17:35:50Z"
        },
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T17:38:20Z"
        },
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T17:40:50Z"
        },
        {
          "travelDuration": "409s",
          "travelDistanceMeters": 1371,
          "waitDuration": "0s",
          "totalDuration": "409s",
          "startTime": "2023-01-13T17:43:20Z"
        },
        {
          "travelDuration": "341s",
          "travelDistanceMeters": 1312,
          "waitDuration": "0s",
          "totalDuration": "341s",
          "startTime": "2023-01-13T17:54:19Z"
        },
        {
          "travelDuration": "205s",
          "travelDistanceMeters": 636,
          "waitDuration": "0s",
          "totalDuration": "205s",
          "startTime": "2023-01-13T18:04:10Z"
        },
        {
          "travelDuration": "339s",
          "travelDistanceMeters": 1276,
          "waitDuration": "0s",
          "totalDuration": "339s",
          "startTime": "2023-01-13T18:11:45Z"
        }
      ],
      "metrics": {
        "performedShipmentCount": 3,
        "travelDuration": "1294s",
        "waitDuration": "0s",
        "delayDuration": "0s",
        "breakDuration": "0s",
        "visitDuration": "1200s",
        "totalDuration": "2494s",
        "travelDistanceMeters": 4595
      },
      "routeCosts": {
        "model.vehicles.cost_per_hour": 27.711111111111112,
        "model.vehicles.cost_per_kilometer": 45.95
      },
      "routeTotalCost": 73.661111111111111
    }
  ],
  "metrics": {
    "aggregatedRouteMetrics": {
      "performedShipmentCount": 3,
      "travelDuration": "1294s",
      "waitDuration": "0s",
      "delayDuration": "0s",
      "breakDuration": "0s",
      "visitDuration": "1200s",
      "totalDuration": "2494s",
      "travelDistanceMeters": 4595
    },
    "usedVehicleCount": 1,
    "earliestVehicleStartTime": "2023-01-13T17:35:50Z",
    "latestVehicleEndTime": "2023-01-13T18:17:24Z",
    "totalCost": 73.661111111111111,
    "costs": {
      "model.vehicles.cost_per_hour": 27.711111111111112,
      "model.vehicles.cost_per_kilometer": 45.95
    }
  }
}
    

Die Lieferung startTime für jede Sendung erfolgt innerhalb des angeforderten Zeitraums:

  • shipments[2] wird um 17:50 Uhr geliefert (innerhalb des Zeitfensters von 17:30 bis 18:00 Uhr).
  • shipments[1] wird um 18:00 Uhr geliefert (innerhalb des Zeitfensters von 18:00 bis 18:30 Uhr).
  • shipments[0] wird um 18:07 Uhr geliefert (innerhalb des Zeitfensters von 18:00 bis 19:00 Uhr).

Szenario 2: Überspringen einer Sendung aufgrund von Zeitfenstern

Im folgenden Beispiel wird ein Szenario veranschaulicht, in dem das Zeitfenster einer Sendung zu weit von den anderen entfernt ist. Daher ist es für den Optimierer kostengünstiger, die Sendung zu überspringen und die penaltyCost zu zahlen.

Beispielanfrage

Diese Anfrage entspricht dem ersten Szenario, nur dass das Lieferzeitfenster einer Sendung zu einem anderen Zeitpunkt, viel später am Tag, liegt.

  • shipments[1] Lieferzeitraum: 21:00 – 21:30 Uhr

Beispielanfrage mit Zeiträumen, die nicht erfüllt werden können

{
  "populatePolylines": false,
  "populateTransitionPolylines": false,
  "model": {
    "globalStartTime": "2023-01-13T16:00:00Z",
    "globalEndTime": "2023-01-14T16:00:00Z",
    "shipments": [
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789456,
              "longitude": -122.390192
            },
            "duration": "250s",
            "timeWindows": [
              {
                "startTime": "2023-01-13T18:00:00Z",
                "endTime": "2023-01-13T19:00:00Z"
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 100.0
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789116,
              "longitude": -122.395080
            },
            "duration": "250s",
            "timeWindows": [
              {
                "startTime": "2023-01-13T21:00:00Z",
                "endTime": "2023-01-13T21:30:00Z"
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 20.0
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.795242,
              "longitude": -122.399347
            },
            "duration": "250s",
            "timeWindows": [
              {
                "startTime": "2023-01-13T17:30:00Z",
                "endTime": "2023-01-13T18:00:00Z"
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 50.0
      }
    ],
    "vehicles": [
      {
        "endLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "startLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "costPerHour": 40.0,
        "costPerKilometer": 10.0
      }
    ]
  }
}
    

Beispielantwort

Die Antwort zeigt, dass der Optimizer shipment[1] überspringt. Das liegt daran, dass das Fahrzeug für die Zustellung dieser Sendung mehrere Stunden länger unterwegs sein müsste und die berechneten Kosten für diese Zeit höher sind als die penaltyCost der Sendung von 20,0.

Antwort auf die Beispielanfrage mit Zeitfenstern, in denen eine Sendung übersprungen wird

{
  "routes": [
    {
      "vehicleStartTime": "2023-01-13T17:37:49Z",
      "vehicleEndTime": "2023-01-13T18:09:49Z",
      "visits": [
        {
          "isPickup": true,
          "startTime": "2023-01-13T17:37:49Z",
          "detour": "0s"
        },
        {
          "shipmentIndex": 2,
          "isPickup": true,
          "startTime": "2023-01-13T17:40:19Z",
          "detour": "150s"
        },
        {
          "shipmentIndex": 2,
          "startTime": "2023-01-13T17:49:38Z",
          "detour": "0s"
        },
        {
          "startTime": "2023-01-13T18:00:00Z",
          "detour": "946s"
        }
      ],
      "transitions": [
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T17:37:49Z"
        },
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T17:40:19Z"
        },
        {
          "travelDuration": "409s",
          "travelDistanceMeters": 1371,
          "waitDuration": "0s",
          "totalDuration": "409s",
          "startTime": "2023-01-13T17:42:49Z"
        },
        {
          "travelDuration": "372s",
          "travelDistanceMeters": 1348,
          "waitDuration": "0s",
          "totalDuration": "372s",
          "startTime": "2023-01-13T17:53:48Z"
        },
        {
          "travelDuration": "339s",
          "travelDistanceMeters": 1276,
          "waitDuration": "0s",
          "totalDuration": "339s",
          "startTime": "2023-01-13T18:04:10Z"
        }
      ],
      "metrics": {
        "performedShipmentCount": 2,
        "travelDuration": "1120s",
        "waitDuration": "0s",
        "delayDuration": "0s",
        "breakDuration": "0s",
        "visitDuration": "800s",
        "totalDuration": "1920s",
        "travelDistanceMeters": 3995
      },
      "routeCosts": {
        "model.vehicles.cost_per_kilometer": 39.95,
        "model.vehicles.cost_per_hour": 21.333333333333332
      },
      "routeTotalCost": 61.283333333333331
    }
  ],
  "skippedShipments": [
    {
      "index": 1
    }
  ],
  "metrics": {
    "aggregatedRouteMetrics": {
      "performedShipmentCount": 2,
      "travelDuration": "1120s",
      "waitDuration": "0s",
      "delayDuration": "0s",
      "breakDuration": "0s",
      "visitDuration": "800s",
      "totalDuration": "1920s",
      "travelDistanceMeters": 3995
    },
    "usedVehicleCount": 1,
    "earliestVehicleStartTime": "2023-01-13T17:37:49Z",
    "latestVehicleEndTime": "2023-01-13T18:09:49Z",
    "totalCost": 81.283333333333331,
    "costs": {
      "model.shipments.penalty_cost": 20,
      "model.vehicles.cost_per_hour": 21.333333333333332,
      "model.vehicles.cost_per_kilometer": 39.95
    }
  }
}
    

Das skippedShipments-Array in der Antwort zeigt, dass die Sendung mit index: 1 nicht ausgeführt wurde. Dies wirkt sich auf die folgenden Kostenparameter aus:

Szenario 3: Verwendung von weichen Zeiträumen

Im folgenden Beispiel wird gezeigt, wie Sie ein weiches Zeitfenster verwenden, das es dem Optimierer ermöglicht, die Auslieferung außerhalb des angegebenen Zeitbereichs zu planen, allerdings zu einem bestimmten Preis.

Eine konzeptionelle Übersicht über dieses Feature finden Sie im Abschnitt Weiche Zeiträume im Dokument „Wichtige Konzepte für Zeiträume“.

Beispielanfrage

Bei dieser Anfrage wird das vorherige Szenario geändert, indem das harte Zeitfenster für shipment[1] in ein weiches Zeitfenster geändert wird. Dazu wird softStartTime verwendet und ein costPerHourBeforeSoftStartTime angegeben.

shipment[1] hat jetzt einen softStartTime von 21:00 Uhr und einen costPerHourBeforeSoftStartTime von 2.0. Das bedeutet, dass für jede Stunde, die die Lieferung vor 21:00 Uhr erfolgt, eine Gebühr anfällt.

Beispielanfrage mit harten und weichen Zeitfenstern

{
  "populatePolylines": false,
  "populateTransitionPolylines": false,
  "model": {
    "globalStartTime": "2023-01-13T16:00:00Z",
    "globalEndTime": "2023-01-14T16:00:00Z",
    "shipments": [
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789456,
              "longitude": -122.390192
            },
            "duration": "250s",
            "timeWindows": [
              {
                "startTime": "2023-01-13T18:00:00Z",
                "softEndTime": "2023-01-13T19:00:00Z",
                "costPerHourAfterSoftEndTime": 2.0
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 100.0
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789116,
              "longitude": -122.395080
            },
            "duration": "250s",
            "timeWindows": [
              {
                "softStartTime": "2023-01-13T21:00:00Z",
                "endTime": "2023-01-13T21:30:00Z",
                "costPerHourBeforeSoftStartTime": 2.0
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 20.0
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.795242,
              "longitude": -122.399347
            },
            "duration": "250s",
            "timeWindows": [
              {
                "startTime": "2023-01-13T17:30:00Z",
                "softEndTime": "2023-01-13T18:00:00Z",
                "costPerHourAfterSoftEndTime": 2.0
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 50.0
      }
    ],
    "vehicles": [
      {
        "endLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "startLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "costPerHour": 40.0,
        "costPerKilometer": 10.0
      }
    ]
  }
}
    

Beispielantwort

Die Antwort zeigt, dass der Optimierer jetzt alle drei Sendungen plant. Die Lieferung von shipment[1] wird deutlich früher als um 21:00 Uhr softStartTime geplant. Dies ist die kostengünstigste Lösung, da die Kosten für die Überschreitung des weichen Zeitfensters geringer sind als die penaltyCost für das Überspringen der Lieferung und auch niedriger als die Kosten für das Warten eines Fahrzeugs auf die Lieferung während des Zeitfensters.

Antwort auf die Beispielanfrage mit harten und weichen Zeitfenstern

{
  "routes": [
    {
      "vehicleStartTime": "2023-01-13T17:48:35Z",
      "vehicleEndTime": "2023-01-13T18:24:28Z",
      "visits": [
        {
          "isPickup": true,
          "startTime": "2023-01-13T17:48:35Z",
          "detour": "0s"
        },
        {
          "shipmentIndex": 1,
          "isPickup": true,
          "startTime": "2023-01-13T17:51:05Z",
          "detour": "150s"
        },
        {
          "shipmentIndex": 2,
          "isPickup": true,
          "startTime": "2023-01-13T17:53:35Z",
          "detour": "300s"
        },
        {
          "startTime": "2023-01-13T18:00:00Z",
          "detour": "300s"
        },
        {
          "shipmentIndex": 1,
          "startTime": "2023-01-13T18:07:42Z",
          "detour": "493s"
        },
        {
          "shipmentIndex": 2,
          "startTime": "2023-01-13T18:17:27Z",
          "detour": "873s"
        }
      ],
      "transitions": [
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T17:48:35Z"
        },
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T17:51:05Z"
        },
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T17:53:35Z"
        },
        {
          "travelDuration": "235s",
          "travelDistanceMeters": 795,
          "waitDuration": "0s",
          "totalDuration": "235s",
          "startTime": "2023-01-13T17:56:05Z"
        },
        {
          "travelDuration": "212s",
          "travelDistanceMeters": 791,
          "waitDuration": "0s",
          "totalDuration": "212s",
          "startTime": "2023-01-13T18:04:10Z"
        },
        {
          "travelDuration": "335s",
          "travelDistanceMeters": 1204,
          "waitDuration": "0s",
          "totalDuration": "335s",
          "startTime": "2023-01-13T18:11:52Z"
        },
        {
          "travelDuration": "171s",
          "travelDistanceMeters": 665,
          "waitDuration": "0s",
          "totalDuration": "171s",
          "startTime": "2023-01-13T18:21:37Z"
        }
      ],
      "metrics": {
        "performedShipmentCount": 3,
        "travelDuration": "953s",
        "waitDuration": "0s",
        "delayDuration": "0s",
        "breakDuration": "0s",
        "visitDuration": "1200s",
        "totalDuration": "2153s",
        "travelDistanceMeters": 3455
      },
      "routeCosts": {
        "model.shipments.deliveries.time_windows.cost_per_hour_after_soft_end_time": 0.58166666666666667,
        "model.shipments.deliveries.time_windows.cost_per_hour_before_soft_start_time": 5.7433333333333332,
        "model.vehicles.cost_per_hour": 23.922222222222221,
        "model.vehicles.cost_per_kilometer": 34.55
      },
      "routeTotalCost": 64.797222222222217
    }
  ],
  "metrics": {
    "aggregatedRouteMetrics": {
      "performedShipmentCount": 3,
      "travelDuration": "953s",
      "waitDuration": "0s",
      "delayDuration": "0s",
      "breakDuration": "0s",
      "visitDuration": "1200s",
      "totalDuration": "2153s",
      "travelDistanceMeters": 3455
    },
    "usedVehicleCount": 1,
    "earliestVehicleStartTime": "2023-01-13T17:48:35Z",
    "latestVehicleEndTime": "2023-01-13T18:24:28Z",
    "totalCost": 64.797222222222217,
    "costs": {
      "model.vehicles.cost_per_kilometer": 34.55,
      "model.shipments.deliveries.time_windows.cost_per_hour_before_soft_start_time": 5.7433333333333332,
      "model.shipments.deliveries.time_windows.cost_per_hour_after_soft_end_time": 0.58166666666666667,
      "model.vehicles.cost_per_hour": 23.922222222222221
    }
  }
}
    

Das weiche Zeitfenster führt zu einer besseren Lösung, was sich in den folgenden Verbesserungen widerspiegelt:

  • Alle drei Sendungen sind geplant, ohne dass eine ausgelassen wird.
  • Die totalCost beträgt jetzt 64,79 €, was niedriger ist als die Kosten der vorherigen Lösung von 81,28 €.
  • Das Objekt routeCosts enthält Kosten in Höhe von 5,74 € für die Zustellung von shipment[1] fast 3 Stunden vor dem softStartTime. Diese Kosten sind niedriger als die penaltyCost von 20, 0 und damit die kostengünstigste Option.