مسیریابی ناوگان: واگذاری محموله ها به وسایل نقلیه

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

Route Optimization 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 تنها 18 دقیقه و 54 ثانیه است در حالی که در پاسخ قبلی 28 دقیقه و 22 ثانیه وجود داشت. با این اوصاف، metrics.costs.model.vehicles.cost_per_kilometer افزایش یافته است که منعکس کننده کل مسافت طی شده توسط سه وسیله نقلیه استفاده شده است. این یک روش را نشان می دهد که در آن مدل هزینه به شما امکان می دهد معاوضه کنید :

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

توجه داشته باشید که مقدار globalDurationCostPerHour 150.0 در این مثال، سه برابر costPerHour هر وسیله نقلیه 50.0 نسبت به مثال قبلی تنظیم شده است. این ارزش جهانی به طور موثر انتظار دارد که هر سه وسیله نقلیه به طور همزمان کار کنند، اما در شرایط عملی چنین فرضیاتی ممکن است واقعیت را منعکس نکنند و در واقع ممکن است تأثیر منفی بر کیفیت نتیجه داشته باشند.

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