يعمل هذا السيناريو على تحسين ترتيب المحطات المخصصة لمركبة بطريقة بسيطة مَعلمات التكلفة. وهو أبسط وضع لعملية تحسين المسارات، ويضمن زيارة جميع المحطات خلال الإطار الزمني المحدد.
يوضح المثال التالي سيناريو أساسي لمركبة واحدة وثلاث الشحنات التي تنشأ جميعها من موقع جغرافي واحد يُسمّى مستودعًا.
الاطّلاع على مثال لطلب
{ "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
ما إذا كان ينبغي أن يعرض تحسين populatePolylines
خطوطًا متعددة.
تُشفِّر الخدمة الخطوط المتعددة باستخدام برنامج ترميز الخطوط المتعددة في JavaScript في "خرائط Google"، والذي يمثّل
بيانات الخطوط المتعددة الثنائية باستخدام أحرف ASCII القابلة للطباعة. يمكنك استخدام
أداة ترميز الخطوط المتعددة التفاعلية لعرض المسارات التي يتم احتسابها من خلال
تحسين المسار. يضبط المثال في هذا الدليل populatePolylines
و
populateTransitionPolylines
على true، ولكن تضبط الأدلة الأخرى هاتين القيمتَين على false لمحاولة
تقليل حجم الاستجابة.
راجِع تنسيق الخوارزمية المتعدّدة الأسطر المشفَّرة للحصول على وصف للترميز. .
قيود الوقت العالمية
تمّ ضبط model.globalStartTime
وmodel.globalEndTime
على قيمة عشوائية 24.
ساعة محددة. يسهّل ذلك تفسير الطوابع الزمنية للمخرجات.
زيارة المواقع الجغرافية
يستخدم الطلب كمثال فقط السمة model.shipments[].pickups[].arrivalLocation
model.shipments[].deliveries[].arrivalLocation
تتوفر أيضًا
السمة departureLocation
للحالات التي تغادر فيها المركبة من
نقطة مختلفة عن مكان وصولها، مثل مجمع لوقوف السيارات بمدخل
على أحد جانبي المبنى ومخرج على جانب آخر. في هذه القصة والفرص اللاحق
فقط، يُفترض أن تكون نقاط الوصول والمغادرة متطابقة.
يمكنك أيضًا الوصول إلى waypoint
عند الوصول والمغادرة كبديل لـ latLng
.
يتيح Waypoint
حقلاً استخدام أرقام تعريف أماكن Google كبديل لـ LatLng
،
ويمكنك أيضًا تحديد عناوين المركبات الاطّلاع على المستندات المرجعية
(REST وgRPC) لمزيد من التفاصيل.
القيود في المثال
يقيّد هذا السيناريو المحسِّن بعدة طرق:
- يجب إكمال جميع الأنشطة بين وقت البدء ووقت الانتهاء العامين. في هذا السيناريو، يعد وقت البدء ووقت الانتهاء قيدًا متأخّرًا جدًا بالنظر إلى التقارب الوثيق بين الشحنات والإطار الزمني العالمي الواسع.
- يجب أن تكتمل جميع عمليات الشحن. هذا هو السلوك الافتراضي عندما
لم يتم تحديد تكاليف العقوبة في
shipments
. - تم ضبط
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
الخاص بـ "ShipmentRoute
"
يجب الجمع بين transitions
. يعد دمج الحقول في تسلسل
يبدو نشاط المركبات كما يلي:
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
للمُحسِّن من أجل إيجاد
الطريق الأمثل (على عكس إيجاد أي طريق ممكن).