مسیریابی ناوگان: اختصاص محموله به وسایل نقلیه

این راهنما نشان می‌دهد که چگونه تعداد وسایل نقلیه ارائه شده در یک راهکار بهینه‌سازی مسیر می‌تواند بسته به پارامترهای درخواست متفاوت باشد.

API بهینه‌سازی مسیر نه تنها سفارش تکمیل حمل و نقل را بهینه می‌کند، بلکه آن محموله‌ها را به وسایل نقلیه نیز اختصاص می‌دهد تا هزینه‌ها را تحت محدودیت‌هایی که شما مدیریت می‌کنید، بهینه کند.

در مثال اول، تعداد وسایل نقلیه با تعداد محموله‌ها مطابقت دارد، و همه وسایل نقلیه هزینه و موقعیت مکانی یکسانی دارند. هر وسیله نقلیه هزینه‌ای به ازای هر ساعت کارکرد و هزینه‌ای به ازای هر کیلومتر طی شده دارد که به حداقل رساندن زمان و مسافت سفر کمک می‌کند. ممکن است انتظار داشته باشید که چندین وسیله نقلیه به محموله‌ها اختصاص داده شوند، اما پاسخ مثال، با توجه به پارامترهای مدل هزینه مشخص شده، راه‌حل با کمترین هزینه را نشان می‌دهد.

یک نمونه درخواست با چندین وسیله نقلیه را ببینید

{
  "model": {
    "globalStartTime": "2023-01-13T16:00:00-08:00",
    "globalEndTime": "2023-01-14T16:00:00-08:00",
    "shipments": [
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789456,
              "longitude": -122.390192
            },
            "duration": "250s"
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 100.0
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789116,
              "longitude": -122.395080
            },
            "duration": "250s"
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 5.0
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.795242,
              "longitude": -122.399347
            },
            "duration": "250s"
          }
        ],
        "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": 50.0,
        "costPerKilometer": 10.0
      },
      {
        "endLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "startLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "costPerHour": 50.0,
        "costPerKilometer": 10.0
      },
      {
        "endLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "startLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "costPerHour": 50.0,
        "costPerKilometer": 10.0
      }
    ]
  }
}
    

پاسخ به درخواست را با چندین وسیله نقلیه مشاهده کنید

{
  "routes": [
    {
      "vehicleStartTime": "2023-01-14T00:00:00Z",
      "vehicleEndTime": "2023-01-14T00:28:22Z",
      "visits": [
        {
          "isPickup": true,
          "startTime": "2023-01-14T00:00:00Z",
          "detour": "0s"
        },
        {
          "shipmentIndex": 2,
          "isPickup": true,
          "startTime": "2023-01-14T00:02:30Z",
          "detour": "150s"
        },
        {
          "startTime": "2023-01-14T00:08:55Z",
          "detour": "150s"
        },
        {
          "shipmentIndex": 2,
          "startTime": "2023-01-14T00:21:21Z",
          "detour": "572s"
        }
      ],
      "transitions": [
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-14T00:00:00Z"
        },
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-14T00:02:30Z"
        },
        {
          "travelDuration": "235s",
          "travelDistanceMeters": 795,
          "waitDuration": "0s",
          "totalDuration": "235s",
          "startTime": "2023-01-14T00:05:00Z"
        },
        {
          "travelDuration": "496s",
          "travelDistanceMeters": 1893,
          "waitDuration": "0s",
          "totalDuration": "496s",
          "startTime": "2023-01-14T00:13:05Z"
        },
        {
          "travelDuration": "171s",
          "travelDistanceMeters": 665,
          "waitDuration": "0s",
          "totalDuration": "171s",
          "startTime": "2023-01-14T00:25:31Z"
        }
      ],
      "metrics": {
        "performedShipmentCount": 2,
        "travelDuration": "902s",
        "waitDuration": "0s",
        "delayDuration": "0s",
        "breakDuration": "0s",
        "visitDuration": "800s",
        "totalDuration": "1702s",
        "travelDistanceMeters": 3353
      },
      "routeCosts": {
        "model.vehicles.cost_per_kilometer": 33.53,
        "model.vehicles.cost_per_hour": 23.638888888888889
      },
      "routeTotalCost": 57.168888888888887
    },
    {
      "vehicleIndex": 1
    },
    {
      "vehicleIndex": 2
    }
  ],
  "skippedShipments": [
    {
      "index": 1
    }
  ],
  "metrics": {
    "aggregatedRouteMetrics": {
      "performedShipmentCount": 2,
      "travelDuration": "902s",
      "waitDuration": "0s",
      "delayDuration": "0s",
      "breakDuration": "0s",
      "visitDuration": "800s",
      "totalDuration": "1702s",
      "travelDistanceMeters": 3353
    },
    "usedVehicleCount": 1,
    "earliestVehicleStartTime": "2023-01-14T00:00:00Z",
    "latestVehicleEndTime": "2023-01-14T00:28:22Z",
    "totalCost": 62.168888888888887,
    "costs": {
      "model.vehicles.cost_per_hour": 23.638888888888889,
      "model.shipments.penalty_cost": 5,
      "model.vehicles.cost_per_kilometer": 33.53
    }
  }
}
    

حل‌کننده، تمام محموله‌ها را فقط به یک وسیله نقلیه اختصاص می‌دهد و با وجود در دسترس بودن کافی وسیله نقلیه، از یک محموله صرف نظر می‌کند. دلیل این امر این است که هزینه عملیاتی کردن وسایل نقلیه اضافی بسیار بالاست و با توجه به هزینه جریمه پایین آن، تکمیل محموله از دست رفته برای هیچ وسیله نقلیه‌ای مقرون به صرفه نیست. با وجود ظرفیت موجود وسیله نقلیه، یک وسیله نقلیه می‌تواند تمام محموله‌های اختصاص داده شده را به مقرون به صرفه‌ترین روش انجام دهد. وسایل نقلیه موجود در درخواست، مجموعه ویژگی usedIfRouteIsEmpty را ندارند (برای جزئیات به مستندات پیام Vehicle ( REST ، gRPC ) مراجعه کنید)، بنابراین در صورت عدم استفاده، هیچ هزینه‌ای متحمل نمی‌شوند.

تغییر پارامترهای هزینه برای اولویت‌بندی راه‌حل‌های کوتاه‌تر سراسری به جای مسیرهای کوتاه‌تر انفرادی برای وسایل نقلیه، باعث می‌شود وسایل نقلیه بیشتری در راه‌حل شرکت کنند. درخواست مثال بعدی، Vehicle.costPerHour با ShipmentModel.globalDurationCostPerHour سراسری جایگزین می‌کند و راه‌حل‌هایی را که در مجموع در طول زمان عملیاتی برای هر وسیله نقلیه معین کوتاه‌تر هستند، در اولویت قرار می‌دهد. هزینه جریمه برای shipment[1] نیز افزایش می‌یابد تا احتمال نادیده گرفته شدن آن کاهش یابد.

یک درخواست نمونه با استفاده از globalDurationCostPerHour را ببینید

{
  "model": {
    "globalStartTime": "2023-01-13T16:00:00-08:00",
    "globalEndTime": "2023-01-14T16:00:00-08:00",
    "globalDurationCostPerHour": 150.0,
    "shipments": [
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789456,
              "longitude": -122.390192
            },
            "duration": "250s"
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 100.0
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789116,
              "longitude": -122.395080
            },
            "duration": "250s"
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 75.0
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.795242,
              "longitude": -122.399347
            },
            "duration": "250s"
          }
        ],
        "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
        },
        "costPerKilometer": 10.0
      },
      {
        "endLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "startLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "costPerKilometer": 10.0
      },
      {
        "endLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "startLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "costPerKilometer": 10.0
      }
    ]
  }
}
    

نتیجه نشان می‌دهد که استفاده از پارامتر هزینه کلی در هر ساعت منجر به استفاده از هر سه وسیله نقلیه به جای فقط یک وسیله نقلیه می‌شود.

مشاهده پاسخ به درخواست با استفاده از globalDurationCostPerHour

{
  "routes": [
    {
      "vehicleStartTime": "2023-01-14T00:00:00Z",
      "vehicleEndTime": "2023-01-14T00:16:20Z",
      "visits": [
        {
          "shipmentIndex": 2,
          "isPickup": true,
          "startTime": "2023-01-14T00:00:00Z",
          "detour": "0s"
        },
        {
          "shipmentIndex": 2,
          "startTime": "2023-01-14T00:09:19Z",
          "detour": "0s"
        }
      ],
      "transitions": [
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-14T00:00:00Z"
        },
        {
          "travelDuration": "409s",
          "travelDistanceMeters": 1371,
          "waitDuration": "0s",
          "totalDuration": "409s",
          "startTime": "2023-01-14T00:02:30Z"
        },
        {
          "travelDuration": "171s",
          "travelDistanceMeters": 665,
          "waitDuration": "0s",
          "totalDuration": "171s",
          "startTime": "2023-01-14T00:13:29Z"
        }
      ],
      "metrics": {
        "performedShipmentCount": 1,
        "travelDuration": "580s",
        "waitDuration": "0s",
        "delayDuration": "0s",
        "breakDuration": "0s",
        "visitDuration": "400s",
        "totalDuration": "980s",
        "travelDistanceMeters": 2036
      },
      "routeCosts": {
        "model.vehicles.cost_per_kilometer": 20.36
      },
      "routeTotalCost": 20.36
    },
    {
      "vehicleIndex": 1,
      "vehicleStartTime": "2023-01-14T00:00:00Z",
      "vehicleEndTime": "2023-01-14T00:18:54Z",
      "visits": [
        {
          "shipmentIndex": 1,
          "isPickup": true,
          "startTime": "2023-01-14T00:00:00Z",
          "detour": "0s"
        },
        {
          "shipmentIndex": 1,
          "startTime": "2023-01-14T00:08:24Z",
          "detour": "0s"
        }
      ],
      "transitions": [
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-14T00:00:00Z"
        },
        {
          "travelDuration": "354s",
          "travelDistanceMeters": 1192,
          "waitDuration": "0s",
          "totalDuration": "354s",
          "startTime": "2023-01-14T00:02:30Z"
        },
        {
          "travelDuration": "380s",
          "travelDistanceMeters": 1190,
          "waitDuration": "0s",
          "totalDuration": "380s",
          "startTime": "2023-01-14T00:12:34Z"
        }
      ],
      "metrics": {
        "performedShipmentCount": 1,
        "travelDuration": "734s",
        "waitDuration": "0s",
        "delayDuration": "0s",
        "breakDuration": "0s",
        "visitDuration": "400s",
        "totalDuration": "1134s",
        "travelDistanceMeters": 2382
      },
      "routeCosts": {
        "model.vehicles.cost_per_kilometer": 23.82
      },
      "routeTotalCost": 23.82
    },
    {
      "vehicleIndex": 2,
      "vehicleStartTime": "2023-01-14T00:00:00Z",
      "vehicleEndTime": "2023-01-14T00:16:14Z",
      "visits": [
        {
          "isPickup": true,
          "startTime": "2023-01-14T00:00:00Z",
          "detour": "0s"
        },
        {
          "startTime": "2023-01-14T00:06:25Z",
          "detour": "0s"
        }
      ],
      "transitions": [
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-14T00:00:00Z"
        },
        {
          "travelDuration": "235s",
          "travelDistanceMeters": 795,
          "waitDuration": "0s",
          "totalDuration": "235s",
          "startTime": "2023-01-14T00:02:30Z"
        },
        {
          "travelDuration": "339s",
          "travelDistanceMeters": 1276,
          "waitDuration": "0s",
          "totalDuration": "339s",
          "startTime": "2023-01-14T00:10:35Z"
        }
      ],
      "metrics": {
        "performedShipmentCount": 1,
        "travelDuration": "574s",
        "waitDuration": "0s",
        "delayDuration": "0s",
        "breakDuration": "0s",
        "visitDuration": "400s",
        "totalDuration": "974s",
        "travelDistanceMeters": 2071
      },
      "routeCosts": {
        "model.vehicles.cost_per_kilometer": 20.71
      },
      "routeTotalCost": 20.71
    }
  ],
  "metrics": {
    "aggregatedRouteMetrics": {
      "performedShipmentCount": 3,
      "travelDuration": "1888s",
      "waitDuration": "0s",
      "delayDuration": "0s",
      "breakDuration": "0s",
      "visitDuration": "1200s",
      "totalDuration": "3088s",
      "travelDistanceMeters": 6489
    },
    "usedVehicleCount": 3,
    "earliestVehicleStartTime": "2023-01-14T00:00:00Z",
    "latestVehicleEndTime": "2023-01-14T00:18:54Z",
    "totalCost": 112.14,
    "costs": {
      "model.vehicles.cost_per_kilometer": 64.89,
      "model.global_duration_cost_per_hour": 47.25
    }
  }
}
    

در این پاسخ، هر سه وسیله نقلیه در حال استفاده هستند (طبق metrics.usedVehicleCount ) و به هر وسیله نقلیه یک محموله برای تکمیل اختصاص داده شده است. با مکان‌های شروع، مکان‌های پایان و costPerKilometer یکسان، هر سه وسیله نقلیه عملاً قابل تعویض هستند، بنابراین فرقی نمی‌کند کدام محموله به کدام وسیله نقلیه اختصاص داده شده باشد.

تابع globalDurationCostPerHour باعث می‌شود بهینه‌ساز راه‌حلی پیدا کند که در کل کوتاه‌تر باشد: تفاوت بین earliestVehicleStartTime و latestVehicleEndTime تنها ۱۸ دقیقه و ۵۴ ثانیه است، در حالی که در پاسخ قبلی ۲۸ دقیقه و ۲۲ ثانیه بود. با این اوصاف، metrics.costs.model.vehicles.cost_per_kilometer افزایش یافته است که نشان‌دهنده مسافت کل طی شده بیشتر توسط سه وسیله نقلیه استفاده شده است. این نشان می‌دهد که مدل هزینه چگونه به شما امکان می‌دهد بده‌بستان انجام دهید:

  • افزایش هزینه زمانی کلی: افزایش استفاده از وسایل نقلیه برای به حداقل رساندن زمان کلی تکمیل کار، به قیمت افزایش مسافت و زمان صرف شده در حمل و نقل توسط وسایل نقلیه.
  • افزایش هزینه زمان وسیله نقلیه: کاهش استفاده از وسیله نقلیه و زمان صرف شده در حمل و نقل، به قیمت طولانی‌تر شدن کل راه حل.

توجه داشته باشید که مقدار globalDurationCostPerHour برابر با ۱۵۰.۰ در این مثال، سه برابر costPerHour هر وسیله نقلیه به صورت جداگانه (۵۰.۰) در مثال قبلی تعیین شده است. این مقدار هزینه جهانی عملاً انتظار دارد که هر سه وسیله نقلیه به طور همزمان کار کنند، اما در شرایط عملی چنین فرضیاتی ممکن است منعکس کننده واقعیت نباشند و در واقع تأثیر منفی بر کیفیت نتیجه داشته باشند.

همانطور که در پارامترهای مدل هزینه توضیح داده شد، تمام پارامترهای هزینه در واحدهای بدون بعد یکسانی بیان می‌شوند اما می‌توانند معانی بسیار متفاوتی داشته باشند. معمولاً مقادیر پارامترهای مدل هزینه باید تا حد امکان مبتنی بر واقعیت باشند، زیرا هزینه‌های مصنوعی مانند هزینه‌های موجود در این مثال ممکن است باعث شود API برای اهدافی که با هدف شما مطابقت ندارند، بهینه‌سازی شود.