تحسين أساسيات محطات استلام الطلبات وتوصيلها

يعمل هذا السيناريو على تحسين ترتيب المحطات المخصّصة لمركبة باستخدام معلمات تكلفة بسيطة. هذا هو أبسط وضع لعملية تحسين المسار، ويضمن زيارة جميع المحطات خلال الإطار الزمني المحدد.

يوضِّح المثال التالي سيناريو أساسي لمركبة واحدة وثلاث شحنات، تنشأ جميعها من موقع واحد يسمّى مستودع.

الاطّلاع على نموذج طلب

      {
        "populatePolylines": true,
        "populateTransitionPolylines": true,
        "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"
                }
              ]
            },
            {
              "deliveries": [
                {
                  "arrivalLocation": {
                    "latitude": 37.789116,
                    "longitude": -122.395080
                  },
                  "duration": "250s"
                }
              ],
              "pickups": [
                {
                  "arrivalLocation": {
                    "latitude": 37.794465,
                    "longitude": -122.394839
                  },
                  "duration": "150s"
                }
              ]
            },
            {
              "deliveries": [
                {
                  "arrivalLocation": {
                    "latitude": 37.795242,
                    "longitude": -122.399347
                  },
                  "duration": "250s"
                }
              ],
              "pickups": [
                {
                  "arrivalLocation": {
                    "latitude": 37.794465,
                    "longitude": -122.394839
                  },
                  "duration": "150s"
                }
              ]
            }
          ],
          "vehicles": [
            {
              "endLocation": {
                "latitude": 37.794465,
                "longitude": -122.394839
              },
              "startLocation": {
                "latitude": 37.794465,
                "longitude": -122.394839
              },
              "costPerKilometer": 10.0,
              "costPerHour": 40.0
            }
          ]
        }
      }
    

حقول طلب تحسين المسار

كما ورد في نظرة عامة، أهم خصائص طلبات تحسين المسار هي vehicles وshipments.

بالإضافة إلى المركبة والشحن، يتضمن الطلب الحقول التالية:

الخطوط المتعددة

ويحدد populatePolylines وpopulateTransitionPolylines ما إذا كان يجب أن تعرض ميزة "تحسين المسار" خطوطًا متعدّدة.

تشفّر الخدمة الخطوط المتعددة باستخدام برنامج ترميز الخطوط المتعددة JS في "خرائط Google"، الذي يمثّل بيانات الخطوط المتعددة الثنائية باستخدام أحرف ASCII القابلة للطباعة. يمكنك استخدام أداة ترميز الخطوط المتعددة التفاعلية لعرض المسارات التي تم احتسابها من خلال تحسين المسار. والمثال في هذا الدليل يحدّد populatePolylines وpopulateTransitionPolylines على "صحيح"، إلا أنّ بعض الأدلة الأخرى تضبطها على "خطأ" لتقليل حجم الاستجابة.

راجِع تنسيق خوارزمية الخطوط المتعددة المشفّرة للحصول على وصف لتنسيق الترميز.

قيود زمنية عالمية

تم ضبط model.globalStartTime وmodel.globalEndTime على فترة عشوائية لمدة 24 ساعة. ويساعد ذلك في تسهيل تفسير الطوابع الزمنية للمخرجات.

زيارة المواقع الجغرافية

يستخدم نموذج الطلب السمتَين model.shipments[].pickups[].arrivalLocation وmodel.shipments[].deliveries[].arrivalLocation فقط. وتتوفّر أيضًا السمة departureLocation للإشارة إلى الحالات التي تغادر فيها المركبة من نقطة مختلفة عن تلك التي تصل إليها، مثل مجمّع مواقف للسيارات ذي مدخل على جانب واحد من المبنى ومخرج على الجانب الآخر. في هذا الدليل والأدلة اللاحقة، يُفترض أن تكون نقاط الوصول والمغادرة متطابقة.

يتوفر أيضًا خيار waypoint للوصول والمغادرة كبديل للحقل latLng. تتيح حقول Waypoint استخدام أرقام تعريف الأماكن على Google كبديل للحقل LatLng، ويمكنها أيضًا تحديد عناوين المركبات. يمكنك الاطّلاع على المستندات المرجعية (REST، gRPC) للحصول على مزيد من التفاصيل.

القيود في المثال

يقيد هذا السيناريو المحسن بعدة طرق:

  1. يجب إكمال جميع الأنشطة بين وقت البدء ووقت الانتهاء على مستوى العالم. في هذا السيناريو، يمثل وقت البدء ووقت الانتهاء عقبة بسيطة للغاية نظرًا إلى القرب القريب من الشحنات والإطار الزمني العالمي الواسع.
  2. يجب إكمال جميع عمليات الشحن. هذا هو السلوك التلقائي في حال عدم تحديد تكاليف العقوبات في shipments.
  3. تم ضبط costPerKilometer وcostPerHour على المركبة.

ويتم تناول التكاليف في مَعلمات نماذج التكلفة.

خصائص استجابة تحسين المسار

الاطّلاع على رد على نموذج الطلب

    {
      "routes": [
        {
          "vehicleStartTime": "2023-01-14T00:00:00Z",
          "vehicleEndTime": "2023-01-14T00:36:41Z",
          "visits": [
            {
              "shipmentIndex": 2,
              "isPickup": true,
              "startTime": "2023-01-14T00:00:00Z",
              "detour": "0s"
            },
            {
              "shipmentIndex": 1,
              "isPickup": true,
              "startTime": "2023-01-14T00:02:30Z",
              "detour": "150s"
            },
            {
              "isPickup": true,
              "startTime": "2023-01-14T00:05:00Z",
              "detour": "300s"
            },
            {
              "startTime": "2023-01-14T00:11:25Z",
              "detour": "0s"
            },
            {
              "shipmentIndex": 1,
              "startTime": "2023-01-14T00:19:29Z",
              "detour": "503s"
            },
            {
              "shipmentIndex": 2,
              "startTime": "2023-01-14T00:29:02Z",
              "detour": "1324s"
            }
          ],
          "transitions": [
            {
              "travelDuration": "0s",
              "waitDuration": "0s",
              "totalDuration": "0s",
              "startTime": "2023-01-14T00:00:00Z",
              "routePolyline": {}
            },
            {
              "travelDuration": "0s",
              "waitDuration": "0s",
              "totalDuration": "0s",
              "startTime": "2023-01-14T00:02:30Z",
              "routePolyline": {}
            },
            {
              "travelDuration": "0s",
              "waitDuration": "0s",
              "totalDuration": "0s",
              "startTime": "2023-01-14T00:05:00Z",
              "routePolyline": {}
            },
            {
              "travelDuration": "235s",
              "travelDistanceMeters": 795,
              "waitDuration": "0s",
              "totalDuration": "235s",
              "startTime": "2023-01-14T00:07:30Z",
              "routePolyline": {
                "points": "kvteFtfjVAA?C?C@C?A?C@AFMj@s@JKb@k@Zc@LSjA}ARWDGdAxAdAvAXa@@k@AsA\\c@FKp@_A\\c@Ze@fA{ALSFGd@o@rAgBB{BZc@"
              }
            },
            {
              "travelDuration": "234s",
              "travelDistanceMeters": 793,
              "waitDuration": "0s",
              "totalDuration": "234s",
              "startTime": "2023-01-14T00:15:35Z",
              "routePolyline": {
                "points": "cwseFti_jVRWj@w@x@eAHLNRHJbApAHLX\\V^?@hA~AT\\PVFFDHDFJNp@~@NRLNNTFFUZIJY^Y^g@p@[`@KP{@fAEFSXe@l@c@h@WZY\\?BELk@v@MNa@l@"
              }
            },
            {
              "travelDuration": "323s",
              "travelDistanceMeters": 1204,
              "waitDuration": "0s",
              "totalDuration": "323s",
              "startTime": "2023-01-14T00:23:39Z",
              "routePolyline": {
                "points": "cuseFhjVSTY`@Yb@GHEDIJEF]f@IJi@r@oAbBeCfDKLaApAKNQVIPKPCDQJIBIBM@iAJeALqBVC@C?A?QBYDI@C?_@Dc@FO@a@FDp@HfAHvABVDl@Dj@PpCQDiALsALAQASKwAOgBEe@COCYEa@Es@Eg@"
              }
            },
            {
              "travelDuration": "209s",
              "travelDistanceMeters": 665,
              "waitDuration": "0s",
              "totalDuration": "209s",
              "startTime": "2023-01-14T00:33:12Z",
              "routePolyline": {
                "points": "{zteFxbajV?CAYEc@AMC_@AOAK?E?CCWAOAKCe@CY?WScDEm@d@EFA\\ENCB?XEVC^E`@EhBUVCNEB?@?\\Er@IMUe@k@k@w@AAMQa@i@SWQWMQi@u@AC?A"
              }
            }
          ],
          "routePolyline": {
            "points": "kvteFtfjVAA?C?C@C?A?C@AFMj@s@JKb@k@Zc@LSjA}ARWDGdAxAdAvAXa@@k@AsA\\c@FKp@_A\\c@Ze@fA{ALSFGd@o@rAgBB{BZc@RWj@w@x@eAHLNRHJbApAHLX\\V^?@hA~AT\\PVFFDHDFJNp@~@NRLNNTFFUZIJY^Y^g@p@[@KP{@fAEFSXe@l@c@h@WZY\\?BELk@v@MNa@l@STY@Yb@GHEDIJEF]f@IJi@r@oAbBeCfDKLaApAKNQVIPKPCDQJIBIBM@iAJeALqBVC@C?A?QBYDI@C?_@Dc@FO@a@FDp@HfAHvABVDl@Dj@PpCQDiALsALAQASKwAOgBEe@COCYEa@Es@Eg@?CAYEc@AMC_@AOAK?E?CCWAOAKCe@CY?WScDEm@d@EFA\\ENCB?XEVC^E`@EhBUVCNEB?@?\\Er@IMUe@k@k@w@AAMQa@i@SWQWMQi@u@AC?A"
          },
          "metrics": {
            "performedShipmentCount": 3,
            "travelDuration": "1001s",
            "waitDuration": "0s",
            "delayDuration": "0s",
            "breakDuration": "0s",
            "visitDuration": "1200s",
            "totalDuration": "2201s",
            "travelDistanceMeters": 3457
          },
          "travelSteps": [
            {
              "duration": "0s",
              "routePolyline": {}
            },
            {
              "duration": "0s",
              "routePolyline": {}
            },
            {
              "duration": "0s",
              "routePolyline": {}
            },
            {
              "duration": "227s",
              "distanceMeters": 794,
              "routePolyline": {
                "points": "kvteFtfjVAA?C?C@C?A?C@AFMj@s@JKb@k@Zc@LSjA}ARWDGdAxAdAvAXa@@k@AsA\\c@FKp@_A\\c@Ze@fA{ALSFGd@o@rAgBB{BZc@"
              }
            },
            {
              "duration": "233s",
              "distanceMeters": 791,
              "routePolyline": {
                "points": "cwseFti_jVRWj@w@x@eAHLNRHJbApAHLX\\V^?@hA~AT\\PVFFDHDFJNp@~@NRLNNTFFUZIJY^Y^g@p@[`@KP{@fAEFSXe@l@c@h@WZY\\?BELk@v@MNa@l@"
              }
            },
            {
              "duration": "322s",
              "distanceMeters": 1205,
              "routePolyline": {
                "points": "cuseFhjVSTY`@Yb@GHEDIJEF]f@IJi@r@oAbBeCfDKLaApAKNQVIPKPCDQJIBIBM@iAJeALqBVC@C?A?QBYDI@C?_@Dc@FO@a@FDp@HfAHvABVDl@Dj@PpCQDiALsALAQASKwAOgBEe@COCYEa@Es@Eg@"
              }
            },
            {
              "duration": "208s",
              "distanceMeters": 666,
              "routePolyline": {
                "points": "{zteFxbajV?CAYEc@AMC_@AOAK?E?CCWAOAKCe@CY?WScDEm@d@EFA\\ENCB?XEVC^E`@EhBUVCNEB?@?\\Er@IMUe@k@k@w@AAMQa@i@SWQWMQi@u@AC?A"
              }
            }
          ],
          "vehicleDetour": "2201s",
          "routeCosts": {
            "model.vehicles.cost_per_hour": 24.455555555555556,
            "model.vehicles.cost_per_kilometer": 34.57
          },
          "routeTotalCost": 59.025555555555556
        }
      ],
      "totalCost": 59.025555555555556,
      "metrics": {
        "aggregatedRouteMetrics": {
          "performedShipmentCount": 3,
          "travelDuration": "1001s",
          "waitDuration": "0s",
          "delayDuration": "0s",
          "breakDuration": "0s",
          "visitDuration": "1200s",
          "totalDuration": "2201s",
          "travelDistanceMeters": 3457
        },
        "usedVehicleCount": 1,
        "earliestVehicleStartTime": "2023-01-14T00:00:00Z",
        "latestVehicleEndTime": "2023-01-14T00:36:41Z",
        "totalCost": 59.025555555555556,
        "costs": {
          "model.vehicles.cost_per_kilometer": 34.57,
          "model.vehicles.cost_per_hour": 24.455555555555556
        }
      }
    }
    

تتضمن استجابة تحسين المسار حقل routes من المستوى الأعلى يمثل المسارات المقترَحة، مع مسار واحد لكل مركبة. بما أنّ مثال الطلب في هذا الدليل يحدّد مركبة واحدة فقط، يتضمّن routes رسالة ShipmentRoute واحدة.

ShipmentRoute مكانًا للإقامة

السمتان الأكثر أهمية لنوع الرسالة ShipmentRoute هما visits وtransitions.

تشير كل Visit إلى اكتمال عملية استلام الطلب أو التسليم من إحدى VisitRequest الخاصة برسائل الطلب. يتم تعيين عمل للزيارة بشكل فعال لإنجازه بواسطة مركبة في مكان ووقت ما.

يمثّل كل Transition المركبة التي تتنقل من موقع جغرافي إلى آخر. يمكن أن تحدث الانتقالات بين نقطة بداية المركبة وموقع جغرافي للزيارة ونقطة نهاية المركبة.

لإعادة بناء المسار الكامل للمركبة، يجب دمج visits وtransitions في ShipmentRoute. يبدو مزيج الحقول في مراحل لاحقة من نشاط المركبة كما يلي:

request.vehicles[0].startLocation -> transitions[0] -> visits[0] ->
transitions[1] -> visits[1] -> transitions[2] -> ... -> visits[3] ->
transitions[4] -> request.vehicles[0].endLocation

تحتوي السمة ShipmentRoute دائمًا على transitions واحدة أكثر من visits، إذ يجب أن تنتقل المركبة من موقع البداية وحتى الزيارة الأولى في بداية المسار ومن الزيارة الأخيرة إلى موقع النهاية في نهاية المسار. إذا كانت المركبة لا تتضمّن موقع بدء أو موقع جغرافي للانتهاء، سيبقى هناك مقياس transitions آخر مقارنةً بالموقع الجغرافي للمركبة visits، وذلك لأنّ الموقع الجغرافي للزيارة الأولى أو الأخيرة يُستخدم كموقع بدء المركبة أو موقع انتهائها على التوالي.

في هذا المثال، تحتوي زيارات الاستلام الثلاث الأولى على انتقالات بينها بدون مسافة والمدة لأن جميع عمليات الاستلام الثلاث تشترك نفس الموقع في الطلب.

يمكنك الاطّلاع على المستندات المرجعية الخاصة بـ ShipmentRoute (REST، gRPC) للحصول على مزيد من التفاصيل.

تحسين بسيط لترتيب النقاط

وكما يوضح هذا المثال، زيارات نماذج تحسين المسار كخصائص للشحنات ولا تتضمن مفهوم نقاط الطريق أو التوقفات ككيان مستقل. مع ذلك، يمكن تمثيل المحطات أو نقاط الطرق على أنّها شحنات تشمل سمة VisitRequest واحدة فقط على أنّها عملية استلام أو توصيل. لا يزال يجب تعيين costPerHour أو costPerKilometer للمركبة حتى يعثر برنامج تحسين الأداء على المسار الأمثل (على عكس العثور على أي مسار ممكن).