تحميل الطلبات والحدود

يوضّح هذا الدليل loadDemands وloadLimits وعلاقتها ببعضها .

كما هو موضّح في قيود فترة استلام وتسليم الطلبات، تحتوي رسالة OptimizeToursRequest (REST وgRPC) على عدد من السمات التي تحدّد القيود على المشكلة التي يتم تحسينها. تمثّل عدة سمات OptimizeToursRequest قيود الحمولة.

للمركبات والشحنات خصائص مادية يجب وضعها في الاعتبار عند التخطيط لمسار.

  • المركبات: تحدد السمة loadLimits الحد الأقصى للحمولة التي يمكن للمركبة التعامل معها. اطّلِع على مستندات Vehicle message (REST وgRPC).
  • الشحنات: تحدّد السمة loadDemands مقدار الحمولة التي تستهلكها شحنة معيّنة. الاطّلاع على رسالة Shipment (REST، gRPC) التوثيق.

يتيح هذان القيدان معًا وتعيين الشحنات للمركبات بشكل مناسب بالطريقة التي سعة الأسطول ومتطلبات الشحن.

يناقش الجزء المتبقّي من هذا المستند loadLimits وloadDemands بالتفصيل.

متطلبات الحمل والحدود القصوى: الأنواع

يمكنك التعبير عن كل طلب تحميل وقيود الحدّ الأقصى من حيث النوع.

يمكنك تقديم مجموعتك الخاصة من أنواع التحميل، مثل الأمثلة التالية:

  • الوزن
  • الحجم
  • القياسات الخطية
  • أسماء السلع أو المعدّات التي يتم نقلها

يستخدم هذا الدليل weightKg كنوع من الأمثلة.

يستخدم كلّ من Shipment.loadDemands وVehicle.loadLimits نوع map حِزم بروتوكول، مع مفاتيح string التي تمثّل أنواع الحمولة.

تستخدِم قيم Shipment.loadDemands رسالة Load (REST وgRPC). تحتوي رسالة Load على سمة amount واحدة تمثّل سعة التحميل المطلوبة لإكمال الشحنة بالنوع المحدّد.

تستخدم قيم Vehicle.loadLimits الرسالة LoadLimit (REST، gRPC). تحتوي الرسالة LoadLimit على عدة خصائص، بما فيها maxLoad. تمثّل الحد الأقصى لسعة حمولة المركبة في النوع المحدد.

تستهلك السمة loadDemands للشحن قيمة loadLimits الخاصة بالمركبة المخصّصة لها فقط في حال الاثنين لهما مفاتيح نوع تحميل مطابقة. على سبيل المثال، شحنة تحتوي على loadDemands من:

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

يجب توفّر 50 وحدة تحميل من النوع weightKg لإكمال عملية الشحن. مكتملة. مركبة مع loadLimits مما يلي:

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

قد يكون بإمكانه إكمال الشحنة، لأنّ maxLoad للمركبة في نوع weightKg أكبر من أو يساوي loadDemands للشحنة في نوع weightKg. في المقابل، إذا كانت هناك مركبة بها loadLimits درجة:

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

تتضمّن بشكلٍ ضمني سعة weightKg غير محدودة بسبب عدم توفّر weightKg من الحمولة، بحيث لا تكون المركبة مقيَّدة بحدود الشحنة والطلب على الوزن.

نقل الحمولة بين الشحنات والمركبات

أثناء استلام الشحنات وتسليمها بواسطة المركبات، يتم نقل loadDemand الشحنة بين الشحنة والمركبة. يمكنك الاطّلاع على حمولات المركبة في إدخال routes.transitions لرسالة OptimizeToursResponse (REST، gRPC) لمركبة معيّنة. التسلسل هو كما يلي:

  1. يتم تحديد سعة الحمولة المطلوبة للشحن على أنّها loadDemand.
  2. حيث يتم استلام الشحنة بواسطة المركبة المخصصة تزيد قيمة vehicleLoads بمقدار loadDemand للشحن. يُمثّل هذا النقل الرمز موجب visits.loadDemands في رسالة الردّ .
  3. تُسلِّم المركبة الشحنة وتنخفض قيمة السيارة في vehicleLoads. بمقدار loadDemand للشحن الذي تم تسليمه. عملية النقل هذه يتم تمثيلها بعبارة visits.loadDemands سلبية في رسالة الرد.

لا يمكن أن يتجاوز vehicleLoads للمركبة loadLimits المحدَّد في أي وقت على مسارها.

مثال كامل يتضمن متطلبات الحمولة وحدودها

اطّلِع على مثال لطلب يتضمّن متطلبات الحمولة والقيود.

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

يحتوي مثال الطلب على عدة مَعلمات ذات صلة بالتحميل:

  • طلب الحمولة في shipments[0] هو 50 weightKg.
  • تبلغ كثافة الأحمال في shipments[1] ‏10 weightKg.
  • طلب الحمولة في shipments[2] هو 80 weightKg.
  • الحد الأقصى لتحميل التطبيقات في "vehicles[0]" هو 100 weightKg.

يمكنك رؤية استجابة للطلب مع متطلبات التحميل الحدود

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

تؤثر قيود التحميل المضافة على ترتيب visits:

  1. تم استلام shipment[0]
  2. تم استلام shipment[1]
  3. تم تسليم shipment[0]
  4. تم تسليم shipment[1]
  5. تم استلام "shipment[2]".
  6. تم تسليم shipment[2]

يشير هذا الطلب إلى أنّه لا يمكن إكمال ثلاث شحنات في الوقت نفسه باستخدام المركبة لأنّ إجمالي loadDemands يتجاوز loadLimits المركبة.

يشمل كل إدخال في "visits" التغيير في حمولة المركبة الناتج عن إلى إكمال Visit. تمثّل قيم الحمولة الموجبة تحميل الشحنة أثناء تمثّل القيم السالبة تفريغ الشحنة.

يتضمّن كل إدخال transitions إجمالي حمولة المركبة خلال Transition. على سبيل المثال، يبلغ عدد عمليات تحميل transitions[2] على weightKg‏ 60، وهو يمثّل عدد عمليات التحميل المجمّعة لكلّ من shipment[0] وshipment[1].

يتضمن عنصرا المقاييس routes[0].metrics وmetrics.aggregatedRouteMetrics ما يلي: السمة maxLoads. قيمة النوع weightKg هي 80، والتي تمثل الجزء من مسار المركبة الذي نقل shipments[2] إلى موقع التسليم.

قيود الحدّ الأقصى للتحميل

كما هو الحال مع الفترات الزمنية الموضّحة في قسم وقت التسليم والاستلام القيود، القيود المفروضة على التحميل لها صيغ ثابتة وسلسة. تُعبّر السمة maxLoad لرسالة LoadLimit عن قيد صارم: يجب ألا يحمل المركبة حمولة تتجاوز قيمة maxLoad في النوع المحدّد. الخصائص softMaxLoad وcostPerUnitAboveSoftMax تعبّر عن شكل خفيف على قيد الحياة، حيث تتجاوز كل وحدة تتعدى softMaxLoad تتسبب في تكلفة costPerUnitAboveSoftMax.

هناك عدة استخدامات لقيود الحدّ الأقصى للتحميل غير الثابت، مثل:

  • موازنة الشحنات عبر مركبات أكثر من الحد الأدنى اللازم عندما يكون تنفيذ ذلك فعّالاً من حيث التكلفة
  • والتعبير عن تفضيل السائق في ما يتعلق بعدد العناصر التي يمكنه أن يتناسب معها الاستلام أو التسليم على مسار معيّن
  • تحميل المركبات بحمولة أقل من الحد الأقصى لطاقتها المادية للحد من التآكل و خفض تكاليف الصيانة

يمكن استخدام قيود حدود التحميل الثابت والخفيف معًا. على سبيل المثال، قد يبدو قد يعبر حد الحمولة عن الحد الأقصى لوزن البضائع التي يمكن للمركبة حملها بأمان أو الحد الأقصى لعدد العناصر التي تلائم أي مركبة في وقت واحد، في حين قد يكون حد التحميل الأولي هو الحد الأقصى للوزن أو عدد العناصر التي قد تفرض ضريبة قدرة السائق على استيعاب كل شيء في المركبة.