Hạn chế của thời gian đến lấy hàng và giao hàng

OptimizeToursRequest áp dụng các quy tắc ràng buộc cho những phần sau:

  • Lô hàng, ảnh hưởng đến cách thực hiện lô hàng
  • Xe cộ, ảnh hưởng đến cách tính toán tuyến xe
  • Áp dụng trên toàn cầu, ảnh hưởng đến cả xe và lô hàng.

Hướng dẫn này tập trung vào một quy tắc ràng buộc quan trọng đối với lô hàng: khoảng thời gian.

Khoảng thời gian là một loại quy tắc ràng buộc mà bạn cung cấp trong thông báo OptimizeToursRequest (REST, gRPC) để chỉ định các giới hạn dựa trên thời gian cho các hoạt động vận chuyển. Loại quy tắc ràng buộc này ảnh hưởng đến cả thời điểm và cách thức thực hiện một lô hàng cũng như việc chỉ định xe cho lô hàng đó. Với những quy tắc ràng buộc này, trình tối ưu hoá sẽ ưu tiên những xe có thể đáp ứng tốt nhất các quy tắc ràng buộc về thời gian của lô hàng.

Quy tắc ràng buộc về lô hàng: khung thời gian

Bạn chỉ định thời điểm có thể đến lấy hàng hoặc giao hàng trong thông báo Shipment.VisitRequest như sau:

  • Sử dụng thuộc tính timeWindows trong thông báo (REST, gRPC)
  • Chỉ định thời gian bắt đầu và kết thúc trong thông báo TimeWindow (REST, gRPC).

Ví dụ về yêu cầu có các quy tắc ràng buộc về khoảng thời gian

Ví dụ ở đây minh hoạ 3 lô hàng khác nhau, mỗi lô hàng có khoảng thời gian giao hàng riêng. Để đơn giản, ví dụ này chỉ thiết lập khoảng thời gian trên deliveries, nhưng bạn cũng có thể áp dụng khoảng thời gian cho các điểm đến. Bạn có thể chỉ định nhiều khoảng thời gian, mặc dù ví dụ này chỉ sử dụng một khoảng thời gian cho mỗi VisitRequest phân phối.

Xem ví dụ về yêu cầu có khoảng thời gian

{
  "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
      }
    ]
  }
}
    

Ví dụ về phản hồi có các quy tắc ràng buộc về khung thời gian

Trong phản hồi mẫu, thời gian bắt đầu và kết thúc của xe lần lượt là 17:35:50 và 18:17:24. Những khoảng thời gian này phản ánh việc trình tối ưu hoá giảm thiểu thời gian cần thiết để vận hành xe được chỉ định trong yêu cầu là costPerHour, đồng thời đáp ứng tất cả các điều kiện ràng buộc về khoảng thời gian. Việc sử dụng 17:35:50 làm thời gian bắt đầu sẽ giúp xe không cần phải chờ ở vị trí ghé thăm cho đến khi bắt đầu khoảng thời gian ghé thăm. Giá trị này xuất hiện trong phản hồi dưới dạng giá trị waitDuration bằng 0.

Xem phản hồi cho yêu cầu mẫu có khoảng thời gian

{
  "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
    }
  }
}
    

Khung thời gian đã sắp xếp visits của xe để các lô hàng có khung thời gian sớm nhất được giao trước.

  1. shipments[2] được phân phối lúc 17:50
  2. shipments[1] được phân phối lúc 18:00
  3. shipments[0] được phân phối lúc 18:07

Yêu cầu mẫu chỉ định các quy tắc ràng buộc cứng về khoảng thời gian, yêu cầu hoàn tất quá trình phân phối trong các khoảng thời gian đó. Nếu không thể hoàn tất VisitRequests của một lô hàng trong bất kỳ khoảng thời gian nào của lô hàng đó hoặc không hiệu quả về chi phí, thì trình tối ưu hoá sẽ bỏ qua lô hàng đó. Nếu lô hàng có penaltyCost, thì trình tối ưu hoá sẽ thêm lô hàng đó vào các chi phí được báo cáo trong phản hồi metrics. Nếu không, thuộc tính skippedMandatoryShipmentCount của thông báo OptimizeToursResponse (REST, gRPC) sẽ tăng lên.

Nếu bạn thay đổi khoảng thời gian bằng cách chuyển cửa sổ của shipment[1] vài giờ sau (từ 18:00 thành 21:00), kết quả sẽ khác như minh hoạ trong các ví dụ sau.

Xem ví dụ về yêu cầu có các khoảng thời gian không thể đáp ứng được

{
  "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
      }
    ]
  }
}
    

Xem phản hồi cho yêu cầu mẫu thứ hai có khoảng thời gian, trong đó một lô hàng bị bỏ qua

{
  "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
    }
  }
}
    

Trong ví dụ này, khoảng thời gian muộn hơn đã khiến shipment[1] bị bỏ qua vì thời gian hoạt động bổ sung của xe cần thiết để hoàn tất việc giao hàng trong khoảng thời gian đã chỉ định đã vượt quá chi phí phạt của lô hàng. Chi phí phạt cho shipment[1] xuất hiện trong metrics.costs và chỉ mục của chi phí phạt xuất hiện trong skippedShipments.

Các quy tắc ràng buộc về khoảng thời gian mềm

Như đã đề cập ngắn gọn trong phần Tham số mô hình chi phí, bạn có thể áp dụng khoảng thời gian dưới dạng quy tắc ràng buộc mềm. Các quy tắc ràng buộc mềm khác với các quy tắc ràng buộc cứng như sau:

  • Ràng buộc cứng: Không được vi phạm và trình tối ưu hoá không cung cấp giải pháp vi phạm quy tắc ràng buộc, ngay cả khi điều đó có nghĩa là bỏ qua một lô hàng.
  • Hạn chế mềm: Có thể bị vi phạm, tức là trình tối ưu hoá có thể cung cấp một giải pháp vi phạm hạn chế mềm. Tuy nhiên, trình tối ưu hoá cũng áp dụng một chi phí cho mọi lỗi vi phạm. Bạn cung cấp chi phí này dưới dạng một thuộc tính bổ sung trong khoảng thời gian, thường là chi phí mỗi giờ cho mỗi giờ trước hoặc sau khoảng thời gian diễn ra hoạt động.

Các khoảng thời gian được làm mềm bằng cách sử dụng softStartTime hoặc softEndTime thay vì startTime hoặc endTime tương ứng, đồng thời bằng cách đặt costPerHourBeforeSoftStartTime hoặc costPerHourAfterSoftEndTime.

Sử dụng các quy tắc ràng buộc về khung thời gian mềm khi việc đến lấy hàng hoặc giao hàng phải diễn ra trong một khung thời gian cụ thể, nhưng việc đến lấy hàng hoặc giao hàng trong khung thời gian đó không hoàn toàn bắt buộc. Bạn có thể sử dụng các quy tắc ràng buộc về khoảng thời gian cứng và mềm cùng nhau để thể hiện các mục tiêu kinh doanh. Ví dụ:

  • Khoảng thời gian cố định: Cho biết giờ làm việc của khách hàng, chẳng hạn như từ 9:00 đến 17:00.
  • Khoảng thời gian mềm: Cho biết khung thời gian giao hàng hoặc nhận hàng khớp với thông báo được gửi cho khách hàng, chẳng hạn như từ 9:00 đến 13:00.

Trong ví dụ này, lô hàng trước đó đã bị bỏ qua vì khoảng thời gian bắt đầu quá muộn đã được nới lỏng quy tắc ràng buộc về thời gian bắt đầu. Các lô hàng khác cũng đã được điều chỉnh thời gian kết thúc của khoảng thời gian.

Xem ví dụ về yêu cầu có khoảng thời gian cố định và mềm

{
  "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
      }
    ]
  }
}
    

Xem phản hồi cho yêu cầu mẫu có khoảng thời gian cố định và không cố định

{
  "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
    }
  }
}
    

Trong ví dụ chỉ có các quy tắc ràng buộc về khung thời gian cứng, shipment[1] đã bị bỏ qua hoàn toàn. Tuy nhiên, khi làm mềm khung thời gian phân phối, shipment[1] sẽ được phân phối trước thời gian bắt đầu của khung thời gian. Tương tự, việc làm mềm thời gian kết thúc của các lô hàng khác cho phép shipment[2] được phân phối sau khi khoảng thời gian kết thúc.

Đồng thời, cả chi phí và tổng số lô hàng đều thay đổi:

  • totalCost: giảm từ 81.283 xuống 64.797
  • tổng số đơn hàng đã hoàn tất: tăng từ 2 lên 3

Trình tối ưu hoá đã tìm thấy một giải pháp ít tốn kém hơn vì các điều kiện ràng buộc về khoảng thời gian đã được nới lỏng so với ví dụ trước.

Cuối cùng, thuộc tính metrics.costs cũng bao gồm một khoá mới để cho biết chi phí thực tế phát sinh dựa trên tích của điều kiện ràng buộc và khoảng thời gian bị lỡ khung thời gian giao hàng. Đó là:

  • costPerHourBeforeSoftStartTime phiên bản 2.0 trở lên
  • thời gian từ khi giao hàng thực tế đến thời điểm bắt đầu khoảng thời gian: 2,83583 giờ

Kết quả:

model.shipments.deliveries.time_windows.cost_per_hour_before_soft_start_time: 5,6716666666666669.

Các chỉ số này cho phép bạn phân tích chi phí để xem sự đánh đổi giữa các điều kiện ràng buộc cứng và điều kiện ràng buộc mềm. Bạn có thể sử dụng các chỉ số này để điều chỉnh các điều kiện ràng buộc cho phù hợp hơn với các quy tắc kinh doanh cụ thể của mình. Trong trường hợp này, tổng chi phí sẽ thấp hơn shipment[1].penalty_cost là 20.0. Trình tối ưu hoá đã xác định rằng việc giao hàng sớm tiết kiệm chi phí hơn so với việc bỏ qua đơn hàng.