Tải nhu cầu và giới hạn

Nhà phát triển ở Khu vực kinh tế Châu Âu (EEA)

Hướng dẫn này mô tả loadDemandsloadLimits, cũng như mối quan hệ giữa hai loại này.

Như đã đề cập trong Các ràng buộc về khung giờ nhận và giao hàng, thông báo OptimizeToursRequest (REST, gRPC) chứa một số thuộc tính chỉ định các ràng buộc đối với vấn đề cần tối ưu hoá. Một số thuộc tính OptimizeToursRequest đại diện cho các quy tắc ràng buộc khi tải.

Xe và lô hàng có các đặc tính vật lý mà bạn phải cân nhắc khi lập kế hoạch cho một tuyến đường.

  • Xe: Thuộc tính loadLimits chỉ định tải trọng tối đa mà xe có thể xử lý. Xem tài liệu về thông báo Vehicle (REST, gRPC).
  • Shipments (Lô hàng): Thuộc tính loadDemands chỉ định lượng tải mà một lô hàng nhất định tiêu thụ. Xem tài liệu về thông báo Shipment (REST, gRPC).

Hai quy tắc ràng buộc này cùng nhau giúp trình tối ưu hoá chỉ định các lô hàng cho xe một cách phù hợp theo cách phù hợp nhất với năng lực của đội xe và nhu cầu vận chuyển của bạn.

Phần còn lại của tài liệu này sẽ thảo luận chi tiết về loadLimitsloadDemands.

Nhu cầu và giới hạn tải: các loại

Bạn thể hiện từng yêu cầu về tải và hạn chế về giới hạn theo loại.

Bạn có thể cung cấp bộ loại tải của riêng mình, chẳng hạn như các ví dụ sau:

  • cân nặng
  • thể tích
  • đo lường tuyến tính
  • tên của các mặt hàng hoặc thiết bị đang được vận chuyển

Hướng dẫn này sử dụng weightKg làm loại ví dụ.

Cả Shipment.loadDemandsVehicle.loadLimits đều sử dụng kiểu Vùng đệm giao thức map, với các khoá string đại diện cho các loại tải.

Các giá trị Shipment.loadDemands sử dụng thông báo Load (REST, gRPC). Thông báo Load có một thuộc tính amount duy nhất biểu thị lượng sức chứa cần thiết để hoàn tất lô hàng theo loại được chỉ định.

Các giá trị Vehicle.loadLimits sử dụng thông báo LoadLimit (REST, gRPC). Thông báo LoadLimit có một số thuộc tính, trong đó maxLoad biểu thị tải trọng tối đa của xe theo loại được chỉ định.

loadDemands của lô hàng chỉ sử dụng loadLimits của xe được chỉ định nếu cả hai có khoá loại tải trùng khớp. Ví dụ: một lô hàng có loadDemands như sau:

"loadDemands": {
  "weightKg": {
    "amount": 50
  }
}

yêu cầu 50 đơn vị tải thuộc loại weightKg để hoàn tất lô hàng. Xe có loadLimits:

"loadLimits": {
  "weightKg": {
    "maxLoad": 100
  }
}

có thể hoàn tất chuyến hàng, vì maxLoad của xe thuộc loại weightKg lớn hơn hoặc bằng loadDemands của chuyến hàng thuộc loại weightKg. Tuy nhiên, xe có loadLimits là:

"loadLimits": {
  "equipmentRackStorage": {
    "maxLoad": 10
  }
}

ngầm định có sức chứa không giới hạn weightKg do không có giới hạn tải weightKg, nên xe không bị hạn chế bởi nhu cầu về trọng lượng của lô hàng.

Chuyển tải giữa các lô hàng và xe

Khi các lô hàng được xe đến lấy và giao, loadDemand của lô hàng sẽ chuyển giữa lô hàng và xe. Bạn có thể xem tải trọng của xe trong mục OptimizeToursResponse (REST, gRPC)routes.transitions của thông báo cho một xe cụ thể. Trình tự như sau:

  1. Tải trọng bắt buộc được xác định cho lô hàng dưới dạng loadDemand.
  2. Xe được chỉ định sẽ đến lấy lô hàng và vehicleLoads của xe sẽ tăng thêm loadDemand của lô hàng. Lệnh chuyển này được biểu thị bằng visits.loadDemands dương trong thông báo phản hồi.
  3. Xe giao lô hàng và vehicleLoads của xe giảm đi một lượng bằng với loadDemand của lô hàng đã giao. Quá trình chuyển này được biểu thị bằng số âm visits.loadDemands trong thông báo phản hồi.

vehicleLoads của một chiếc xe không được vượt quá loadLimits đã chỉ định tại bất kỳ thời điểm nào trên tuyến đường của xe.

Ví dụ đầy đủ về nhu cầu và giới hạn tải

Xem ví dụ về yêu cầu có nhu cầu và giới hạn tải

{
  "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"
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 100.0,
        "loadDemands": {
          "weightKg": {
            "amount": 50
          }
        }
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789116,
              "longitude": -122.395080
            },
            "duration": "250s"
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 15.0,
        "loadDemands": {
          "weightKg": {
            "amount": 10
          }
        }
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.795242,
              "longitude": -122.399347
            },
            "duration": "250s"
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 50.0,
        "loadDemands": {
          "weightKg": {
            "amount": 80
          }
        }
      }
    ],
    "vehicles": [
      {
        "endLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "startLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "costPerHour": 40.0,
        "costPerKilometer": 10.0,
        "loadLimits": {
          "weightKg": {
            "maxLoad": 100
          }
        }
      }
    ]
  }
}
    

Yêu cầu mẫu chứa một số thông số liên quan đến việc tải:

  • shipments[0] có nhu cầu tải là 50 weightKg.
  • shipments[1] có nhu cầu tải là 10 weightKg.
  • shipments[2] có nhu cầu tải là 80 weightKg.
  • vehicles[0] có giới hạn tải là 100 weightKg.

Xem phản hồi cho yêu cầu có nhu cầu và giới hạn tải

{
  "routes": [
    {
      "vehicleStartTime": "2023-01-13T16:00:00Z",
      "vehicleEndTime": "2023-01-13T16:43:27Z",
      "visits": [
        {
          "isPickup": true,
          "startTime": "2023-01-13T16:00:00Z",
          "detour": "0s",
          "loadDemands": {
            "weightKg": {
              "amount": "50"
            }
          }
        },
        {
          "shipmentIndex": 1,
          "isPickup": true,
          "startTime": "2023-01-13T16:02:30Z",
          "detour": "150s",
          "loadDemands": {
            "weightKg": {
              "amount": "10"
            }
          }
        },
        {
          "startTime": "2023-01-13T16:08:55Z",
          "detour": "150s",
          "loadDemands": {
            "weightKg": {
              "amount": "-50"
            }
          }
        },
        {
          "shipmentIndex": 1,
          "startTime": "2023-01-13T16:16:37Z",
          "detour": "343s",
          "loadDemands": {
            "weightKg": {
              "amount": "-10"
            }
          }
        },
        {
          "shipmentIndex": 2,
          "isPickup": true,
          "startTime": "2023-01-13T16:27:07Z",
          "detour": "1627s",
          "loadDemands": {
            "weightKg": {
              "amount": "80"
            }
          }
        },
        {
          "shipmentIndex": 2,
          "startTime": "2023-01-13T16:36:26Z",
          "detour": "0s",
          "loadDemands": {
            "weightKg": {
              "amount": "-80"
            }
          }
        }
      ],
      "transitions": [
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T16:00:00Z",
          "vehicleLoads": {
            "weightKg": {}
          }
        },
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T16:02:30Z",
          "vehicleLoads": {
            "weightKg": {
              "amount": "50"
            }
          }
        },
        {
          "travelDuration": "235s",
          "travelDistanceMeters": 795,
          "waitDuration": "0s",
          "totalDuration": "235s",
          "startTime": "2023-01-13T16:05:00Z",
          "vehicleLoads": {
            "weightKg": {
              "amount": "60"
            }
          }
        },
        {
          "travelDuration": "212s",
          "travelDistanceMeters": 791,
          "waitDuration": "0s",
          "totalDuration": "212s",
          "startTime": "2023-01-13T16:13:05Z",
          "vehicleLoads": {
            "weightKg": {
              "amount": "10"
            }
          }
        },
        {
          "travelDuration": "380s",
          "travelDistanceMeters": 1190,
          "waitDuration": "0s",
          "totalDuration": "380s",
          "startTime": "2023-01-13T16:20:47Z",
          "vehicleLoads": {
            "weightKg": {}
          }
        },
        {
          "travelDuration": "409s",
          "travelDistanceMeters": 1371,
          "waitDuration": "0s",
          "totalDuration": "409s",
          "startTime": "2023-01-13T16:29:37Z",
          "vehicleLoads": {
            "weightKg": {
              "amount": "80"
            }
          }
        },
        {
          "travelDuration": "171s",
          "travelDistanceMeters": 665,
          "waitDuration": "0s",
          "totalDuration": "171s",
          "startTime": "2023-01-13T16:40:36Z",
          "vehicleLoads": {
            "weightKg": {}
          }
        }
      ],
      "metrics": {
        "performedShipmentCount": 3,
        "travelDuration": "1407s",
        "waitDuration": "0s",
        "delayDuration": "0s",
        "breakDuration": "0s",
        "visitDuration": "1200s",
        "totalDuration": "2607s",
        "travelDistanceMeters": 4812,
        "maxLoads": {
          "weightKg": {
            "amount": "80"
          }
        }
      },
      "routeCosts": {
        "model.vehicles.cost_per_kilometer": 48.12,
        "model.vehicles.cost_per_hour": 28.966666666666665
      },
      "routeTotalCost": 77.086666666666659
    }
  ],
  "metrics": {
    "aggregatedRouteMetrics": {
      "performedShipmentCount": 3,
      "travelDuration": "1407s",
      "waitDuration": "0s",
      "delayDuration": "0s",
      "breakDuration": "0s",
      "visitDuration": "1200s",
      "totalDuration": "2607s",
      "travelDistanceMeters": 4812,
      "maxLoads": {
        "weightKg": {
          "amount": "80"
        }
      }
    },
    "usedVehicleCount": 1,
    "earliestVehicleStartTime": "2023-01-13T16:00:00Z",
    "latestVehicleEndTime": "2023-01-13T16:43:27Z",
    "totalCost": 77.086666666666659,
    "costs": {
      "model.vehicles.cost_per_hour": 28.966666666666665,
      "model.vehicles.cost_per_kilometer": 48.12
    }
  }
}
    

Các quy tắc ràng buộc về tải được thêm vào sẽ ảnh hưởng đến thứ tự của visits:

  1. Đã lấy shipment[0]
  2. Đã lấy shipment[1]
  3. shipment[0] đã được giao
  4. shipment[1] đã được giao
  5. Đã lấy shipment[2]
  6. shipment[2] đã được giao

Đơn đặt hàng này cho thấy xe không thể hoàn tất 3 lô hàng cùng một lúc vì tổng loadDemands của các lô hàng đó vượt quá loadLimits của xe.

Mỗi mục nhập visits đều bao gồm sự thay đổi về tải trọng xe do hoàn thành Visit. Giá trị tải dương biểu thị việc tải hàng lên tàu, trong khi giá trị âm biểu thị việc dỡ hàng xuống tàu.

Mỗi mục nhập transitions đều bao gồm tổng tải trọng của xe trong Transition. Ví dụ: transitions[2] có mức tải weightKg là 60, thể hiện mức tải kết hợp của shipment[0]shipment[1].

Các đối tượng chỉ số routes[0].metricsmetrics.aggregatedRouteMetrics bao gồm một thuộc tính maxLoads. Giá trị cho loại weightKg là 80, thể hiện phần tuyến đường của xe đã vận chuyển shipments[2] đến vị trí giao hàng.

Các ràng buộc về giới hạn tải linh hoạt

Giống như các khoảng thời gian được mô tả trong Các ràng buộc về khoảng thời gian nhận và giao hàng, các ràng buộc về giới hạn tải có các biến thể cứng và mềm. Thuộc tính maxLoad của thông báo LoadLimit thể hiện một ràng buộc cứng: xe không được chở hàng vượt quá giá trị maxLoad trong loại được chỉ định. Các thuộc tính softMaxLoadcostPerUnitAboveSoftMax thể hiện một ràng buộc mềm, trong đó mỗi đơn vị vượt quá softMaxLoad sẽ phải chịu chi phí costPerUnitAboveSoftMax.

Các quy tắc ràng buộc về giới hạn tải mềm có một số mục đích sử dụng, chẳng hạn như:

  • cân bằng các lô hàng trên nhiều xe hơn số lượng tối thiểu cần thiết khi việc này mang lại hiệu quả về chi phí
  • thể hiện lựa chọn ưu tiên của người lái xe về số lượng mặt hàng mà họ có thể thoải mái nhận và giao trên một tuyến đường nhất định
  • chất hàng vào xe dưới mức tải trọng tối đa để hạn chế hao mòn và giảm chi phí bảo trì

Bạn có thể sử dụng đồng thời các điều kiện ràng buộc về giới hạn tải cứng và giới hạn tải mềm. Ví dụ: giới hạn tải trọng cứng có thể biểu thị trọng lượng tối đa của hàng hoá mà một chiếc xe có thể chở một cách an toàn hoặc số lượng mặt hàng tối đa có thể vừa trong một chiếc xe cùng một lúc, trong khi giới hạn tải trọng mềm có thể là trọng lượng hoặc số lượng mặt hàng tối đa có thể gây khó khăn cho khả năng sắp xếp mọi thứ vào xe của người lái xe.