يحسّن هذا السيناريو ترتيب نقاط التوقف المخصّصة لمركبة باستخدام مَعلمات بسيطة للتكلفة. هذا هو أبسط وضع لتشغيل "تحسين المسار"، ويضمن زيارة جميع نقاط التوقف خلال الإطار الزمني المحدّد.
يوضّح المثال التالي سيناريو أساسيًا يتضمّن مركبة واحدة وثلاث شحنات، وكلها صادرة من موقع جغرافي واحد يُعرف باسم المستودع.
الاطّلاع على مثال لطلب
{ "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 } ] } }
حقول طلب Route Optimization
كما هو موضّح في نظرة عامة، أهم سمات طلب تحسين المسار هي vehicles
وshipments
.
بالإضافة إلى المركبة والشحنات، يتضمّن الطلب الحقول التالية:
الخطوط المتعددة
تحدِّد السمتان populatePolylines
وpopulateTransitionPolylines
ما إذا كان يجب أن تعرض خدمة Route
Optimization خطوطًا متعددة الأضلاع.
تشفّر الخدمة خطوطًا متعددة الأضلاع باستخدام برنامج الترميز الخاص بالخطوط المتعددة الأضلاع في Maps JavaScript API، والذي يمثّل بيانات الخطوط المتعددة الأضلاع الثنائية باستخدام أحرف ASCII قابلة للطباعة. يمكنك استخدام
Interactive Polyline Encoder Utility لتصوُّر المسارات التي تم احتسابها بواسطة
Route Optimization. يضبط المثال الوارد في هذا الدليل القيمتين 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
على المركبة.
يتم تناول التكاليف في مَعلمات نموذج التكلفة.
سمات الردّ في Route Optimization
الاطّلاع على ردّ على طلب المثال
{ "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
s في رسالة الطلب. الزيارة هي عمل يتم تكليفه لمركبة لإكماله في مكان ووقت محدّدَين.
يمثّل كل 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
كي يتمكّن المحسِّن من العثور على
مسار أمثل (بدلاً من العثور على أي مسار ممكن).