يحسن هذا السيناريو ترتيب المحطات المخصصة لمركبة بمعلمات تكلفة بسيطة. هذا هو أبسط طريقة لتشغيل تحسين المسارات، وتضمن زيارة جميع المحطات خلال الإطار الزمني المحدد.
يوضّح المثال التالي سيناريو أساسي لمركبة واحدة وثلاث شحنات، وجميعها تنشأ من موقع واحد يُسمى مستودع.
الاطّلاع على مثال لطلب
{ "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) لمزيد من التفاصيل.
القيود في المثال
يقيّد هذا السيناريو المحسِّن بعدة طرق:
- يجب إكمال جميع الأنشطة بين وقت البدء والانتهاء العالميين. في هذا السيناريو، تُعد أوقات البدء والانتهاء قيدًا متساهلًا للغاية بالنظر إلى قُرب الشحنات والإطار الزمني العالمي الواسع.
- يجب أن تكتمل جميع عمليات الشحن. هذا هو السلوك التلقائي في حال عدم
تحديد تكاليف العقوبات في
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
و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
للمركبة كي يتمكّن مزوّد التحسين من العثور على المسار الأمثل (بدلاً من العثور على أي مسار ممكن).