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