منح الأولوية للزيارات القريبة باستخدام سمات الانتقال

يوضّح هذا المثال كيفية استخدام سمات الانتقال لتحديد أولويات المسارات التي يتم فيها تنفيذ عمليات الاستلام والتسليم القريبة بواسطة المركبة نفسها في فترة زمنية واحدة. لمزيد من المعلومات عن سمات الانتقال، راجِع Model Business Logic with Transition Attributes.

في هذا المثال:

  • عمليات تسليم الشحنات "أ" و"ب" و"ج" قريبة من بعضها البعض على الطريق نفسه.
  • سيتم تسليم المزيد من الطلبات في وقت لاحق.
  • لا تتضمّن عمليات التسليم مُدد تسليم محدّدة.
  • بغض النظر عن جدول الزيارات، يجب أن تسير المركبة على هذا الطريق مرتين: مرة في الصباح في طريقها من المستودع، ومرة في المساء في طريق العودة.
  • تكون المسافة الإجمالية للسفر ومدة المسار هي نفسها دائمًا، بغض النظر عن وقت تنفيذ الخطوات A وB وC.

مثال على عمليات تسليم الشحنات على الطريق نفسه هناك ثلاث شحنات A وB وC في الطريق من المستودع إلى شحنات أخرى. يقع الموقع A على بُعد 1000 متر من المستودع، ويقع الموقع B على بُعد 50 مترًا إضافيًا من المستودع، ويقع الموقع C على بُعد 30 مترًا إضافيًا في الاتجاه نفسه. هناك شحنات أخرى على بُعد 1000 متر من النقطة C.

في هذه الحالة، وبالنسبة إلى طلب يستخدم فقط التكلفة لكل ساعة والتكلفة لكل كيلومتر، يمكن التعامل مع النقطتين A وB في الصباح والنقطة C في المساء، وستكون تكلفة الحلّ هي نفسها كما لو تم التعامل مع النقاط الثلاث في الوقت نفسه.

التكلفة لكل كيلومتر مع حدّ أقصى

لتجميع الزيارات القريبة، عليك أولاً اختيار مسافة حدّية. هذه هي الحد الأقصى للمسافة بين زيارتَين تعتبرهما متجاورتَين. يستخدم هذا المثال حدًا أدنى يبلغ 100 متر، وهو ما يعادل تقريبًا مربعًا سكنيًا واحدًا في منطقة حضرية. يمكنك زيادة الحدّ أو خفضه بما يتناسب مع احتياجات نشاطك التجاري والإعدادات المفضّلة للسائقين.

لتجميع الزيارات القريبة من بعضها البعض ضمن مسافة 100 متر، عليك ضبط تكلفة عالية على أول 100 متر من كل انتقال وتكلفة أقل لأي أمتار إضافية من الانتقال. بما أنّ أول 100 متر هي الأغلى تكلفة، يحقّق المحسّن أكبر قدر من التوفير من خلال استخدام انتقالات أقصر من حد الـ 100 متر، حتى لو كان ذلك يعني إطالة المسار الإجمالي.

لإعداد التكاليف، عليك إضافة إدخال جديد إلى ShipmentModel.transition_attributes بالسمات التالية:

{
  "model": {
    "transitionAttributes": [
      {
        "excluded_dst_tag": "UNUSED_TAG",
        "excluded_src_tag": "UNUSED_TAG",
        "distanceLimit": {
          "softMaxMeters": 100,
          "costPerKilometerBelowSoftMax": 50,
          "costPerKilometerAboveSoftMax": 1,
        }
      }
    ]
  }
}

يجب ألا تستخدم أي شحنات أو مركبات العلامة #unused_tag# لمطابقة جميع حالات الانتقال المحتملة. لمزيد من المعلومات، يُرجى الاطّلاع على كيفية مطابقة جميع طلبات الزيارات.

طريقة عمل التكلفة المرتفعة التي تقلّ عن الحدّ

يوضّح هذا القسم كيف تؤثّر التكلفة التي تقلّ عن الحدّ الأدنى أو تتجاوزه في التكلفة الإجمالية للحلول المختلفة في سيناريو المثال.

الحلّ 1: تنفيذ A وB في الذهاب، وC في العودة

في هذا الحلّ، يتم تقسيم الشحنات إلى عمليتَي عبور لهذا الطريق. يتم تسليم اثنتَين منهما في عملية الاجتياز الأولى، ويتم تسليم المتبقية في عملية الاجتياز الثانية. هناك 5 انتقالات:

الانتقال المسافة أقل من الحدّ الأدنى أعلى من الحدّ
المسافة التكلفة المسافة التكلفة
depot →A 1000 متر 100 متر 5 900 متر 0.9
A→B 50 مترًا 50 مترًا 2.5 0 متر 0
B→other 1030 متر 100 متر 5 ‫930 مترًا 0.93
other→C 1000 متر 100 متر 5 900 متر 0.9
C→depot ‫1080 متر 100 متر 5 ‫980 مترًا 0.98
المجموع 450 مترًا 22.5 ‫3710 متر 3.71

يتم احتساب التكلفة الإجمالية من خلال جمع التكلفتَين لكل كيلومتر:

  • تكلفة الكيلومتر الواحد تحت الحدّ الأدنى (50) مضروبة في إجمالي المسافة المقطوعة تحت الحدّ الأدنى (450 مترًا = 0.45 كيلومتر)
  • التكلفة لكل كيلومتر فوق الحدّ (1) مضروبة في إجمالي المسافة المقطوعة فوق الحدّ (3710 متر = 3.71 كيلومتر).

وبالتالي، تكون التكلفة الإجمالية 0.45 * 50 + 3.71 * 1 = 22.5 + 3.71 = 26.21.

الحلّ 2: تنفيذ الخطوات أ، ب، ج في طريق الذهاب، وعدم تنفيذ أي خطوات في طريق العودة

في هذا الحلّ، على عكس الحلّ 1، يتم تسليم جميع الشحنات الثلاث "كمجموعة" خلال عملية نقل واحدة على الطريق. في عملية التجوال الأخرى، لا تتوقّف المركبة على الإطلاق. مرة أخرى، هناك 5 انتقالات، ولكن تختلف مدتها وتركيبتها:

الانتقال المسافة أقل من الحدّ الأدنى أعلى من الحدّ
المسافة التكلفة المسافة التكلفة
depot →A 1000 متر 100 متر 5 900 متر 0.9
A→B 50 مترًا 50 مترًا 2.5 0 متر 0
B→C ‫30 مترًا ‫30 مترًا 1.5 0 متر 0
C→other 1000 متر 100 متر 5 900 متر 0.9
other→depot ‫2080 مترًا 100 متر 5 ‫1980 مترًا 1.98
المجموع 380 متر 19 ‫3780 متر 3.78

باستخدام العملية الحسابية نفسها كما في الحلّ 1، تكون التكلفة الإجمالية 0.38 * 50 + 3.78 * 1 = 19 + 3.78 = 22.78، ويكون إجراء جميع الزيارات في فترة زمنية واحدة أقل تكلفة من إجرائها في مجموعتين. يمكنك تعزيز هذا التأثير من خلال زيادة DistanceLimit.cost_per_kilometer_below_soft_max.

سبب عدم فعالية التكلفة المنخفضة لكل كيلومتر تحت الحدّ الأدنى

بما أنّك تفضّل التنقّل باستخدام وسائل نقل قصيرة المدة على وسائل النقل الطويلة المدة، قد تميل إلى تحديد تكلفة عالية لكل كيلومتر لوسائل النقل الطويلة المدة، والحفاظ على التكلفة المنخفضة لكل كيلومتر لوسائل النقل القصيرة المدة. ولكن هذا يؤدي في الواقع إلى تأثير معاكس، فبما أنّ أول 100 متر من الانتقال هي الأرخص، يستخدم المحسِّن هذه الأمتار "الرخيصة" بأكبر قدر ممكن من الفعالية من خلال تفضيل عمليات الانتقال التي تبلغ 100 متر أو أكثر.

يمكنك الاطّلاع على هذا التأثير في نموذجي الحلّ. إذا بدّلت التكلفة لكل كيلومتر بين الحدّ الأدنى والحدّ الأقصى، ستتغير تكاليف المسار على النحو التالي:

التكلفة المرتفعة التي تتجاوز الحدّ تكلفة عالية أقل من الحدّ الأدنى
الحل 1 الحل 2 الحل 1 الحل 2
عدد الكيلومترات أقل من الحدّ الأدنى 0.45 0.38 0.45 0.38
التكلفة لكل كيلومتر أقل من الحدّ الأدنى 1.00 1.00 50.00 50.00
عدد الكيلومترات التي تتجاوز الحدّ 3.71 3.78 3.71 3.78
التكلفة لكل كيلومتر فوق الحدّ 50.00 50.00 1.00 1.00
التكلفة الإجمالية 185.95 189.38 26.21 22.78

بالنسبة إلى كل إصدار، يتم تمييز أقل التكاليف الإجمالية للحلّين بخط غليظ. يمكنك ملاحظة أنّه عند استخدام تكلفة عالية أعلى من الحدّ، يصبح إجمالي تكلفة المسار أعلى الآن للمسار الذي يتم فيه تجميع الزيارات، وهو عكس ما أردت تحقيقه.