مثال: محدودیت‌ها و درخواست‌های بارگذاری

این مثال نشان می‌دهد که چگونه از loadDemands و loadLimits برای مدیریت محدودیت‌های ظرفیت خودرو در درخواست Route Optimization API استفاده کنید.

برای نمای کلی مفهومی کامل، به سند مفاهیم کلیدی درخواست‌ها و محدودیت‌های بار مراجعه کنید.

درخواست نمونه

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

این درخواست نمونه حاوی پارامترهای مرتبط با بار زیر است:

  • shipments[0] با تقاضای بار amount ۵۰ weightKg.
  • shipments[1] با تقاضای بار amount ۱۰ weightKg.
  • shipments[2] با تقاضای بار amount ۸۰ weightKg.
  • ‫vehicles[0] با حد بار maxLoad ۱۰۰ weightKg.

نمونه درخواستی را با محدودیت‌ها و تقاضاهای بارگذاری ببینید

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

پاسخ نمونه

پاسخ مسیر بهینه‌سازی‌شده برای خودرو را نشان می‌دهد. چون بار کل همه محموله‌ها از ظرفیت وسیله نقلیه بیشتر است، بهینه‌ساز ترتیبی از تحویل گرفتن‌ها و تحویل دادن‌ها ایجاد می‌کند تا مطمئن شود loadLimits نقض نمی‌شود.

پاسخ به درخواست را با محدودیت‌ها و تقاضاهای بارگذاری ببینید

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

چون loadDemands ترکیبی سه محموله (۵۰ + ۱۰ + ۸۰ = ۱۴۰) از loadLimits خودرو (۱۰۰) بیشتر است، خودرو نمی‌تواند همه محموله‌ها را به‌طور هم‌زمان تحویل بگیرد. بهینه‌ساز فقط مسیرهایی را درنظر می‌گیرد که در آن‌ها shipment[0] و shipment[2] به‌طور هم‌زمان در خودرو نباشند، زیرا این محموله‌ها با وزن ترکیبی‌شان از حد مجاز بار خودرو فراتر می‌روند.

مسیر دارای visits زیر است تا از حد بار وسیله نقلیه فراتر نرود:

  1. ‫shipment[0] تحویل گرفته شد
  2. shipment[1] تحویل گرفته شد
  3. ‫shipment[0] تحویل داده شد
  4. ‫shipment[1] تحویل داده شد
  5. ‫shipment[2] تحویل گرفته شد
  6. ‫shipment[2] تحویل داده شد

بار خودرو درطول مسیر تغییر می‌کند که می‌توانید آن را در آرایه transitions مشاهده کنید. برای مثال، transitions[2] وسیله نقلیه را نشان می‌دهد که پس‌از تحویل گرفتن دو محموله اول (۵۰ + ۱۰)، محموله‌ای با بار ۶۰ weightKg را حمل می‌کند.

ویژگی maxLoads در metrics نشان می‌دهد که حداکثر بار حمل‌شده در هر نقطه از مسیر ۸۰ weightKg بوده است، که تأیید می‌کند راه‌حل با موفقیت در محدوده ۱۰۰ weightKg خودرو باقی مانده است.

حدود بارگذاری جزئی

مثال زیر نحوه استفاده از محدودیت بار نرم را برای بهینه‌سازی مسیر با چند خودرو نشان می‌دهد. این راه‌حل محموله‌ها را بین دو خودرو تقسیم می‌کند تا از جریمه هزینه به‌دلیل فراتر رفتن از حد بار نرم خودرو جلوگیری شود.

درخواست نمونه

این درخواست اکنون شامل سه محموله فقط تحویل و دو وسیله نقلیه با loadLimits و softMaxLoad یکسان است.

پارامترهای کلیدی برای این مثال عبارت‌اند از:

نمونه درخواست با حد بارگذاری نرم را ببینید

{
  "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"
          }
        ],
        
        "loadDemands": {
          "weightKg": {
            "amount": "50"
          }
        }
        
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789116,
              "longitude": -122.395080
            },
            "duration": "250s"
          }
        ],
        
        "loadDemands": {
          "weightKg": {
            "amount": "60"
          }
        }
        
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.795242,
              "longitude": -122.399347
            },
            "duration": "250s"
          }
        ],
        
        "loadDemands": {
          "weightKg": {
            "amount": "30"
          }
        }
        
      }
    ],
    "vehicles": [
      {
        "endLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "startLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "costPerHour": 40.0,
        "costPerKilometer": 10.0,
        
        "loadLimits": {
          "weightKg": {
            "maxLoad": "150",
            "softMaxLoad": "100",
            "costPerUnitAboveSoftMax": 5.0
          }
        }
        
      },
      {
        "endLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "startLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "costPerHour": 40.0,
        "costPerKilometer": 10.0,
        
        "loadLimits": {
          "weightKg": {
            "maxLoad": "150",
            "softMaxLoad": "100",
            "costPerUnitAboveSoftMax": 5.0
          }
        }
        
      }
    ]
  }
}
    

پاسخ نمونه

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

پاسخ به درخواست با حد بارگذاری نرم را ببینید

{
  "routes": [
    {
      "vehicleStartTime": "2023-01-13T16:00:00Z",
      "vehicleEndTime": "2023-01-13T16:13:31Z",
      "visits": [
        {
          "startTime": "2023-01-13T16:03:53Z",
          "detour": "0s",
          "loadDemands": {
            "weightKg": {
              "amount": "-50"
            }
          }
        }
      ],
      "transitions": [
        {
          "travelDuration": "233s",
          "travelDistanceMeters": 794,
          "waitDuration": "0s",
          "totalDuration": "233s",
          "startTime": "2023-01-13T16:00:00Z",
          "vehicleLoads": {
            "weightKg": {
              "amount": "50"
            }
          }
        },
        {
          "travelDuration": "328s",
          "travelDistanceMeters": 1188,
          "waitDuration": "0s",
          "totalDuration": "328s",
          "startTime": "2023-01-13T16:08:03Z",
          "vehicleLoads": {
            "weightKg": {}
          }
        }
      ],
      "metrics": {
        "performedShipmentCount": 1,
        "travelDuration": "561s",
        "visitDuration": "250s",
        "totalDuration": "811s",
        "travelDistanceMeters": 1982,
        "maxLoads": {
          "weightKg": {
            "amount": "50"
          }
        }
      },
      "routeCosts": {
        "model.vehicles.cost_per_kilometer": 19.82,
        "model.vehicles.cost_per_hour": 9.01
      },
      "routeTotalCost": 28.83
    },
    {
      "vehicleIndex": 1,
      "vehicleStartTime": "2023-01-13T16:00:00Z",
      "vehicleEndTime": "2023-01-13T16:21:43Z",
      "visits": [
        {
          "shipmentIndex": 1,
          "startTime": "2023-01-13T16:05:54Z",
          "detour": "0s",
          "loadDemands": {
            "weightKg": {
              "amount": "-60"
            }
          }
        },
        {
          "shipmentIndex": 2,
          "startTime": "2023-01-13T16:13:52Z",
          "detour": "473s",
          "loadDemands": {
            "weightKg": {
              "amount": "-30"
            }
          }
        }
      ],
      "transitions": [
        {
          "travelDuration": "354s",
          "travelDistanceMeters": 1196,
          "waitDuration": "0s",
          "totalDuration": "354s",
          "startTime": "2023-01-13T16:00:00Z",
          "vehicleLoads": {
            "weightKg": {
              "amount": "90"
            }
          }
        },
        {
          "travelDuration": "228s",
          "travelDistanceMeters": 808,
          "waitDuration": "0s",
          "totalDuration": "228s",
          "startTime": "2023-01-13T16:10:04Z",
          "vehicleLoads": {
            "weightKg": {
              "amount": "30"
            }
          }
        },
        {
          "travelDuration": "221s",
          "travelDistanceMeters": 655,
          "waitDuration": "0s",
          "totalDuration": "221s",
          "startTime": "2023-01-13T16:18:02Z",
          "vehicleLoads": {
            "weightKg": {}
          }
        }
      ],
      "metrics": {
        "performedShipmentCount": 2,
        "travelDuration": "803s",
        "visitDuration": "500s",
        "totalDuration": "1303s",
        "travelDistanceMeters": 2659,
        "maxLoads": {
          "weightKg": {
            "amount": "90"
          }
        }
      },
      "routeCosts": {
        "model.vehicles.cost_per_kilometer": 26.59,
        "model.vehicles.cost_per_hour": 14.48
      },
      "routeTotalCost": 41.07
    }
  ],
  "metrics": {
    "aggregatedRouteMetrics": {
      "performedShipmentCount": 3,
      "travelDuration": "1364s",
      "visitDuration": "750s",
      "totalDuration": "2114s",
      "travelDistanceMeters": 4641,
      "maxLoads": {
        "weightKg": {
          "amount": "90"
        }
      }
    },
    "usedVehicleCount": 2,
    "earliestVehicleStartTime": "2023-01-13T16:00:00Z",
    "latestVehicleEndTime": "2023-01-13T16:21:43Z",
    "totalCost": 69.90,
    "costs": {
      "model.vehicles.cost_per_kilometer": 46.41,
      "model.vehicles.cost_per_hour": 23.49
    }
  }
}
    

فیلدهای زیر نشان می‌دهند که بهینه‌ساز چگونه محموله‌ها را بین دو خودرو تقسیم کرده است تا بارها را زیر حد نرم 100 weightKg نگه دارد.

  • اولین مسیر (vehicleIndex: ۰) ۵۰ weightKg محموله را مدیریت می‌کند. maxLoads آن «۵۰» است که کمتر از حد نرم است.
  • مسیر دوم (vehicleIndex: ۱) محموله‌های ۶۰ و ۳۰ weightKg را مدیریت می‌کند. maxLoads آن «۹۰» است که این هم کمتر از حد نرم است.
  • چون هیچ‌کدام از خودروها از حد مجاز خود تجاوز نمی‌کنند، routeCosts برای هر دو مسیر هیچ costPerUnitAboveSoftMax جریمه‌ای نشان نمی‌دهد.