Permintaan dan batas pemuatan

Panduan ini menjelaskan loadDemands dan loadLimits, serta keterkaitannya satu sama lain lainnya.

Seperti yang disebutkan dalam Batasan Periode Waktu Pengambilan dan Pengiriman, Pesan OptimizeToursRequest (REST, gRPC) berisi sejumlah properti yang menentukan batasan pada masalah yang dioptimalkan. Beberapa Properti OptimizeToursRequest mewakili batasan beban.

Kendaraan dan pengiriman memiliki sifat fisik yang harus dipertimbangkan saat merencanakan rute.

  • Kendaraan: Properti loadLimits menetapkan beban maksimum yang bisa ditangani kendaraan. Lihat pesan Vehicle (REST, gRPC) dokumentasi tambahan.
  • Pengiriman: Properti loadDemands menentukan banyaknya beban yang diberikan yang dikonsumsi oleh pengiriman. Lihat pesan Shipment (REST, gRPC) dokumentasi tambahan.

Bersama-sama, kedua batasan ini memungkinkan pengoptimal untuk menetapkan pengiriman ke kendaraan dengan cara yang paling sesuai kapasitas armada dan permintaan pengiriman Anda.

Bagian selanjutnya dari dokumen ini membahas loadLimits dan loadDemands secara mendetail.

Batas dan permintaan beban: jenis

Anda menyatakan setiap permintaan beban dan batasan batas dalam hal jenis.

Anda dapat memberikan kumpulan jenis pemuatan Anda sendiri, seperti contoh berikut:

  • bobot
  • volume
  • pengukuran linear
  • nama barang atau peralatan yang diangkut

Panduan ini menggunakan weightKg sebagai jenis contoh.

Shipment.loadDemands dan Vehicle.loadLimits menggunakan Buffering Protokol Jenis map, dengan kunci string yang mewakili jenis pemuatan.

Nilai Shipment.loadDemands menggunakan pesan Load (REST, gRPC). Pesan Load memiliki satu properti amount yang menunjukkan jumlah kapasitas diperlukan untuk menyelesaikan pengiriman dalam jenis yang ditentukan.

Nilai Vehicle.loadLimits menggunakan pesan LoadLimit (REST, gRPC). Pesan LoadLimit memiliki beberapa properti, dengan maxLoad yang menunjukkan kapasitas beban maksimum kendaraan dalam jenis yang ditentukan.

loadDemands pengiriman menggunakan loadLimits kendaraan yang ditetapkan hanya jika keduanya memiliki kunci jenis muatan yang cocok. Misalnya, pengiriman dengan loadDemands dari:

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

memerlukan 50 unit muatan dalam jenis weightKg agar pengiriman dapat dilakukan selesai. Kendaraan dengan loadLimits dari:

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

mungkin dapat menyelesaikan pengiriman, karena maxLoad kendaraan di Jenis weightKg lebih besar dari atau sama dengan loadDemands pengiriman di jenis weightKg. Namun, kendaraan dengan loadLimits:

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

secara implisit memiliki kapasitas weightKg tak terbatas karena tidak adanya Batas muatan weightKg, sehingga kendaraan tidak dibatasi oleh biaya pengiriman permintaan berat.

Transfer beban antara pengiriman dan kendaraan

Saat pengiriman diambil dan diantarkan dengan kendaraan, paket pengiriman loadDemand transfer antara pengiriman dan kendaraan. Anda dapat melihat muatan kendaraan di pesan OptimizeToursResponse (REST, Entri gRPC)routes.transitions untuk kendaraan tertentu. Urutannya adalah sebagai berikut ini:

  1. Kapasitas muat yang diperlukan ditentukan untuk pengiriman sebagai loadDemand.
  2. Pengiriman diambil oleh kendaraan yang ditugaskan kepadanya dan nomor kendaraannya vehicleLoads meningkat dengan jumlah loadDemand pengiriman. Ini transfer direpresentasikan oleh visits.loadDemands positif dalam respons untuk membuat pesan email baru.
  3. Kendaraan mengirimkan pengiriman dan vehicleLoads kendaraan menurun sebesar loadDemand pengiriman yang telah dikirim. Transfer ini yang diwakili oleh visits.loadDemands negatif dalam pesan respons.

vehicleLoads kendaraan tidak boleh melebihi loadLimits yang ditentukan kapan pun pada rutenya.

Contoh lengkap permintaan dan batas beban

Lihat contoh permintaan dengan beban batas

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

Contoh permintaan berisi beberapa parameter terkait pemuatan:

  • shipments[0] memiliki permintaan beban sebesar 50 weightKg.
  • shipments[1] memiliki permintaan beban sebesar 10 weightKg.
  • shipments[2] memiliki permintaan beban sebesar 80 weightKg.
  • vehicles[0] memiliki batas beban 100 weightKg.

Lihat respons terhadap permintaan dengan beban dan batas

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

Batasan pemuatan yang ditambahkan memengaruhi urutan visits:

  1. shipment[0] diambil
  2. shipment[1] diambil
  3. shipment[0] terkirim
  4. shipment[1] terkirim
  5. shipment[2] diambil
  6. shipment[2] terkirim

Pesanan ini menunjukkan bahwa tiga pengiriman tidak dapat diselesaikan oleh kendaraan dengan waktu yang sama karena total loadDemands mereka melebihi jumlah total loadLimits.

Setiap entri visits mencakup perubahan beban kendaraan yang dihasilkan dari penyelesaian Visit. Nilai beban positif mewakili pemuatan pengiriman saat nilai negatif mewakili bongkar muat pengiriman.

Setiap entri transitions mencakup total beban kendaraan selama Transition. Misalnya, transitions[2] memiliki beban weightKg sebesar 60, yang mewakili beban gabungan shipment[0] dan shipment[1].

Objek metrik routes[0].metrics dan metrics.aggregatedRouteMetrics disertakan properti maxLoads. Nilai untuk jenis weightKg adalah 80, yang merepresentasikan bagian rute kendaraan yang mengangkut shipments[2] ke lokasi pengiriman.

Batasan batas pemuatan lunak

Seperti halnya periode waktu yang dijelaskan di Periode Waktu Pengambilan dan Pengiriman Batasan, batasan batas pemuatan memiliki varian keras dan lunak. Tujuan Properti maxLoad dari pesan LoadLimit menunjukkan batasan ketat: kendaraan tidak boleh membawa beban yang melebihi nilai maxLoad . Properti softMaxLoad dan costPerUnitAboveSoftMax mengekspresikan soft terbatas, dengan setiap unit yang melebihi softMaxLoad akan menimbulkan Biaya costPerUnitAboveSoftMax.

Batasan batas pemuatan lunak memiliki beberapa kegunaan, seperti:

  • menyeimbangkan pengiriman di lebih banyak kendaraan dari jumlah minimum yang diperlukan kapan biayanya hemat untuk melakukannya
  • mengungkapkan preferensi pengemudi untuk jumlah item yang dapat mereka ambil dan kirim di rute tertentu
  • memuat kendaraan di bawah kapasitas fisik maksimumnya untuk membatasi keausan dan mengurangi biaya pemeliharaan

Batasan batas hard load dan soft dapat digunakan bersama. Misalnya, hard batas beban mungkin menyatakan berat kargo maksimum yang dapat dibawa dengan aman oleh kendaraan atau jumlah maksimum barang yang dapat ditampung di dalam kendaraan pada satu waktu, batas beban lunak mungkin berupa berat maksimum atau jumlah item yang dikenai pajak kemampuan pengemudi untuk memuat semua yang ada di dalam kendaraan.