تحسين المسارات
تحسين المسارات
يحلّ Navvo Optimize مسائل التخطيط التوافقية الصعبة وراء عمليات التوصيل والخدمة الميدانية واللوجستيات: بأي ترتيب، وعلى أي مركبة، ينبغي زيارة مجموعة من المحطات لتقليل إجمالي زمن القيادة — مع مراعاة سعة المركبة، والنوافذ الزمنية للعملاء، وأسبقية الاستلام قبل التسليم، وتعدّد المستودعات.
يعمل بالاعتماد على حلّال OR-Tools ذاتي الاستضافة تتقدّمه واجهة Navvo. تُبنى مصفوفات زمن السير من محرك توجيه Navvo، فيستدلّ المحسِّن على أزمنة القيادة عبر شبكة الطرق الحقيقية — لا المسافة المستقيمة. ولأنه ذاتي الاستضافة فلا توجد رسوم تحسين لكل طلب.
النطاق المطلوب: optimize
{ lat, lng }.GET /optimize/health
فحص جاهزية خدمة التحسين. استخدمه قبل إرسال المهام الكبيرة.
{ "provider": "navvo-optimize", "available": true, "ok": true,
"service": "navvo-optimize", "solvers": ["routing", "cp-sat"] }
عندما تكون available بقيمة false، أرسل العمل كمهمة غير متزامنة (انظر التحسين كمَهمّة) وأعد المحاولة، أو استخدم ترتيبك الخاص كبديل.
POST /optimize/routes
حلّال مسألة توجيه المركبات الأساسي (CVRP / VRPTW). العنصر stops[0] هو المستودع؛ والمحطات الباقية هي الزيارات المراد ترتيبها على عدد numVehicles من المركبات.
| الحقل | النوع | ملاحظات |
|---|---|---|
stops | {lat,lng}[] | مطلوب — الفهرس 0 هو المستودع |
numVehicles | number | الافتراضي 1 |
costing | string | ملف المصفوفة: auto (افتراضي)، truck، bicycle، pedestrian |
tier | string | fast · balanced (افتراضي) · best — زمن بحث أطول = مسارات أفضل |
demands | number | حِمل كل محطة (بطول stops نفسه) |
vehicleCapacities | number | سعة كل مركبة (يُفعّل CVRP) |
timeWindows | [earliest,latest][] | نافذة خدمة كل محطة بالثواني (يُفعّل VRPTW) |
serviceTimes | number | زمن المكوث عند كل محطة بالثواني |
pickupsDeliveries | [pickupIdx,deliveryIdx][] | يفرض الاستلام قبل التسليم على المركبة نفسها |
dropPenalty | number | يسمح للحلّال بتخطّي محطة بهذه التكلفة (لمعالجة الأحمال غير القابلة للحل) |
maxRouteDuration | number | حدّ أقصى لكل مركبة بالثواني |
openEnded | boolean | تنهي المركبات عند آخر محطة بدل العودة للمستودع |
curl -X POST https://api.navvo.io/v1/optimize/routes \
-H 'authorization: Bearer <API_KEY>' -H 'content-type: application/json' \
-d '{
"stops": [
{"lat":31.9539,"lng":35.9106},
{"lat":31.9700,"lng":35.9200},
{"lat":31.9400,"lng":35.8800},
{"lat":31.9800,"lng":35.9300}
],
"numVehicles": 1, "tier": "balanced"
}'
{
"provider": "navvo-optimize",
"feasible": true,
"objective": { "totalDurationSec": 1840, "vehiclesUsed": 1 },
"dropped": [],
"routes": [
{ "vehicle": 0, "durationSec": 1840,
"order": [0, 2, 1, 3],
"stops": [ {"lat":31.9539,"lng":35.9106}, {"lat":31.94,"lng":35.88}, "…" ] }
]
}
الحقل order هو تسلسل الزيارة كفهارس داخل مصفوفة stops لديك؛ وstops هو التسلسل نفسه مُعادًا إلى إحداثيات. أي محطة اختار الحلّال تخطّيها (ممكن فقط عند ضبط dropPenalty) تظهر في dropped.
POST /optimize/reoptimize
إعادة التخطيط الحيّة في منتصف اليوم. بمعرفة موضع كل مركبة الحالي والمحطات المتبقية، يعيد تخطيط الباقي كمسارات مفتوحة النهاية (تنهي المركبات عند آخر تسليم).
| الحقل | النوع | ملاحظات |
|---|---|---|
vehiclePositions | {lat,lng}[] | مطلوب — موضع حالي لكل مركبة نشطة |
remainingStops | {lat,lng}[] | مطلوب — المحطات التي لم تُخدَم بعد |
costing | string | ملف المصفوفة، الافتراضي auto |
tier | string | الافتراضي balanced |
demands | number | حِمل كل محطة متبقية |
vehicleCapacities | number | السعة المتبقية لكل مركبة |
dropPenalty | number | يسمح بتخطّي محطة |
{
"provider": "navvo-optimize", "feasible": true,
"objective": { "totalDurationSec": 920, "vehiclesUsed": 2 },
"dropped": [],
"routes": [ { "vehicle": 0, "durationSec": 540, "stops": [ "…المحطات المتبقية بالترتيب…" ] } ]
}
يُحذف الموضع الحالي للمركبة من stops المُعادة — تحصل فقط على المحطات المتبقية بترتيبها الجديد.
POST /optimize/binpack
تعبئة الحاويات عبر CP-SAT — توزيع عناصر مُوزّنة على حاويات محدودة السعة (أي طرود تناسب أي مركبة)، مع تقليل عدد الحاويات المستخدمة.
| الحقل | النوع | ملاحظات |
|---|---|---|
itemWeights | number | مطلوب — وزن كل عنصر |
binCapacities | number | مطلوب — سعة كل حاوية متاحة |
curl -X POST https://api.navvo.io/v1/optimize/binpack \
-H 'authorization: Bearer <API_KEY>' -H 'content-type: application/json' \
-d '{ "itemWeights": [3,5,2,8], "binCapacities": [10,10] }'
{ "feasible": true, "assignment": [1, 1, 1, 0], "binsUsed": 2 }
assignment[i] هو فهرس الحاوية المختارة للعنصر i. وقيمة feasible:false تعني أن العناصر لا يمكن أن تتّسع في الحاويات المعطاة (مثلًا إجمالي الوزن يتجاوز إجمالي السعة).
POST /optimize/roster
جدولة السائقين / الورديات عبر CP-SAT. يوزّع السائقين على خانات اليوم/الوردية بحيث يُلبّى الحد الأدنى لكل وردية، مع موازنة الحِمل بإنصاف واحترام التوفّر وقواعد الراحة.
| الحقل | النوع | ملاحظات |
|---|---|---|
numDrivers | number | مطلوب |
numDays | number | مطلوب — أفق التخطيط، مثل 7 |
shiftsPerDay | number | الافتراضي 2 (مثل صباحي / مسائي) |
demand | number[][] | مطلوب — demand[day][shift] = الحد الأدنى للسائقين |
maxShiftsPerDriver | number | حدّ أقصى لورديات السائق في النافذة |
minRestDays | number | الحد الأدنى لأيام الراحة لكل سائق |
forbidden | [driver,day][] | خانات غير متاحة (إجازة / راحة أسبوعية) |
{
"feasible": true,
"shifts": [ { "driver": 0, "day": 0, "shift": 0 }, "…" ],
"perDriver": [5, 4, 5, 4],
"peakLoad": 5
}
peakLoad هو إجمالي ورديات أكثر السائقين انشغالًا — يقلّله الحلّال للحفاظ على عدالة الجدول.
التحسين كمَهمّة
قد تستغرق المسائل الكبيرة (المستوى best، محطات كثيرة) 20 ثانية أو أكثر — وهو وقت طويل لطلب متزامن. أرسلها كـ مهمة: تحصل على jobId فورًا، ثم تستعلم عن النتيجة.
POST /optimize/jobs
أضِف أي عملية حلّ كمهمة في الخلفية. الجسم هو نفسه جسم النقطة المتزامنة المقابلة، مضافًا إليه محدِّد kind.
| الحقل | النوع | ملاحظات |
|---|---|---|
kind | string | routes (افتراضي) · reoptimize · roster · binpack |
… | — | بقية الحقول هي جسم النقطة المطابقة أعلاه |
curl -X POST https://api.navvo.io/v1/optimize/jobs \
-H 'authorization: Bearer <API_KEY>' -H 'content-type: application/json' \
-d '{ "kind": "routes", "tier": "best", "numVehicles": 5, "stops": [ "…" ] }'
{ "jobId": "71005767-63e7-4dbc-af7a-95c10aa18864", "status": "running", "kind": "routes" }
GET /optimize/jobs/:id
استعلم عن مهمة. أثناء التشغيل تكون status بقيمة running؛ وعند الاكتمال تصبح completed مع result (نفس الحمولة التي تعيدها النقطة المتزامنة)، أو failed مع error.
{
"id": "71005767-63e7-4dbc-af7a-95c10aa18864",
"kind": "routes", "status": "completed",
"createdAt": 1782572676434, "finishedAt": 1782572678901,
"result": { "feasible": true, "routes": [ "…" ], "objective": { "totalDurationSec": 1840 } }
}
المعرّف غير المعروف يعيد { "error": "job not found", "status": "unknown" }. المهام مؤقتة (في الذاكرة) — استعلم حتى الاكتمال واحفظ النتيجة لديك؛ لا تعتمد على بقاء المهمة إلى أجل غير مسمى.
best.مستويات الجودة
| المستوى | زمن البحث | يُستخدم لـ |
|---|---|---|
fast | ~2 ثانية | إعادة التخطيط الحيّة، المسائل الصغيرة، الواجهات التفاعلية |
balanced | ~6 ثوانٍ | الافتراضي — مسارات جيدة للتخطيط اليومي |
best | ~20 ثانية | التخطيط الليلي/الدُّفعي لأساطيل كبيرة عبر مهمة |
ذات صلة
- دليل الأسطول واللوجستيات — عمليات توصيل متكاملة باستخدام المحسِّن.
- التوجيه — المحرك الذي يغذّي مصفوفات زمن السير.