בניית מודל של לוגיקה עסקית באמצעות מאפייני מעבר

במדריך הזה מוסבר איך משתמשים במאפייני מעבר. במאמר הזה תלמדו איך ליצור מודלים של תרחישים מהעולם האמיתי באמצעות שתי דוגמאות: שילוב הזמן הנדרש לחניית הרכב במסלולים שעברו אופטימיזציה, ולוודא שכל מסלול מסתיים בביקור במיקום ספציפי.

לפני שמתחילים

משתמשים במאפייני מעבר כדי להוסיף עלויות ועיכובים ספציפיים לדגם למעברים מסוימים בנתיבים שעברו אופטימיזציה. העיכובים והעלויות האלה מתווספים למשך הזמן של המעבר ולעלויות המחושבות מנתוני המפה על סמך הפרמטרים של הרכב שבו נעשה שימוש.

מעבר הוא מקטע במסלול שמקשר בין מיקום אחד למיקום הבא.

מיקום מתייחס לכל אחד מהנקודות הבאות במסלול של רכב:

  • נקודת ההתחלה של המסלול.
  • עצירה שבה מתבצע איסוף או משלוח.
  • נקודת הסיום של המסלול.

כדי להגדיר את כל מאפייני המעבר של המודל, מוסיפים אותם לרשימה ShipmentModel.transition_attributes. כל רכיב ברשימה מגדיר קבוצה אחת של מאפייני מעבר, והוא מותאם למעברים במסלולים באמצעות תגים במיקום ההתחלה ובמיקום הסיום של המעבר. למידע נוסף על מאפייני המעבר, תוכלו לקרוא את מאמרי העזרה של TransitionAttributes.

הדגמת תרחישים מהעולם האמיתי

בקטע הזה מוצגות שתי דוגמאות קצרות להטמעת אילוצים עסקיים מהעולם האמיתי באמצעות מאפייני מעבר.

הזמנת זמן לחניה

בתרחיש הזה, הנהג צריך לחנות את הרכב כדי לבקר במיקום א'. מיקום ב' נמצא בקרבת מקום, והנהג יכול להשתמש באותה מקום חניה בשני הביקורים. אם הנהג יבקר ב-B מיד אחרי A, הוא יחסוך זמן כי הוא לא יצטרך לצאת מחניון ולחנות שוב. ב-Route Optimization API, אפשר להשתמש במאפייני מעבר כדי להוסיף זמן נוסף לחניית הרכב רק כשהנהג עובר ממקום חנייה אחד למקום אחר.

כשיוצרים מודל של זמן החניה בנפרד ממשכי הזמן של הביקורים, המסלולים שבהם ביקורים שמשתמשים באותו חניון מקובצים נמשכים פחות זמן. כך תוכלו לשפר את הדיוק של המודל, וגם לגרום למטמיע להעדיף מסלולים שבהם הביקורים מקובצים.

כדי לעשות זאת בבקשה ל-Route Optimization API:

  1. יש להשתמש ב-VisitRequest.duration רק למשך הזמן הנדרש לביצוע הביקור. לדוגמה, כדי למסור את החבילה ולקבל חתימה מהלקוח.

  2. לכל מקום חנייה ייחודי שמשמש במודל, צריך להשתמש בתג חדש שלא משמש לשום דבר אחר במודל, לדוגמה PARKING_123.

  3. מוסיפים את התג הזה לפריטים הבאים:

    1. VisitRequest.tags בכל בקשות הביקור שמשתמשות במקום החניה הזה.

    2. Vehicle.start_tags אם הרכב מתחיל את המסלול במקום החניה הזה.

    3. Vehicle.end_tags אם הרכב מתחיל ומסתיים את המסלול במקום החניה הזה.

  4. לכל תג חניה חדש, מוסיפים רשומה ל-ShipmentModel.transition_attributes שמוסיפה עיכוב לחניה כשמגיעים ממקום חנייה אחר. לשם כך:

    1. מגדירים את TransitionAttributes.excluded_src_tag ואת TransitionAttributes.dst_tag לערך PARKING_123.

    2. מגדירים את TransitionAttributes.delay למספר הדקות הנדרשות לחניית הרכב.

    לדוגמה, אם התג של המיקום הוא PARKING_123 ונדרש זמן של 150 שניות כדי להחנות את הרכב, מוסיפים את הערך הבא ל-ShipmentModel.transition_attributes:

    {
      "excluded_src_tag": "PARKING_123",
      "dst_tag": "PARKING_123",
      "delay": "150s"
    }
    

חובה לנקות בסוף המסלול

בתרחיש הזה, צריך לנקות את הרכב בסוף המסלול, עם האילוצים הנוספים הבאים:

  • הניקוי מתבצע במתקן ניקוי מיוחד לפני שהרכב חוזר למגרש הרכב. המסלול המותאם אישית כולל את מכון הניקוי הטוב ביותר על סמך המיקום שלו והמיקומים של האיסוף וההעברה שבהם הרכב יבצע.
  • אחרי הניקוי, אסור שהרכב יבצע איסופים או משלוחים נוספים.
  • הזמן של הנסיעה לנקודה הזו והניקוי של הרכב נספר כחלק משעות העבודה של הנהג, והוא חייב להיכלל במשך הזמן המקסימלי של המסלול.

כדי ליצור מודל לדרישה הזו, מאפשרים רק מסלולים ריקים או מסלולים שהביקור האחרון שלהם הוא במתקן ניקוי. כדי לעשות זאת ב-Route Optimization API, צריך לאסור את המעבר לנקודת הציון הסופית של המסלול מכל מיקום מלבד מכון הניקוי או מנקודת ההתחלה של המסלול:

  1. בוחרים שני תגים חדשים שלא נמצאים בשימוש בשום מקום במודל, למשל CLEANED ו-ROUTE_END. המיקום הראשון מיועד למיקומים שבהם הרכב נקי או הופך להיות נקי, והמיקום השני מיועד לסיום המסלול.
  2. לכל רכב, מוסיפים משלוח חדש מסוג 'משלוח בלבד' שמייצג את הביקור במתקן הניקוי, עם המאפיינים הבאים:
    1. כל מיקום של מכון ניקיון צריך להיות מיוצג כבקשה לביקור של משלוח זה.
    2. מוסיפים את CLEANED ל-VisitRequest.tags של כל בקשת ביקור של משלוח למתקן הניקוי. הוא מאותת על כך שכלי רכב שיוצא מהמיקום הזה נקי. בקשות אחרות לביקור במודל לא צריכות להשתמש בתג הזה, כדי שהרכב ייחשב כ'לא נקי' כשהלקוח יוצא מהן.
    3. כדי לאפשר למטמיז לדלג על המשלוח הזה כשהרכב לא בשימוש, מגדירים את הערך של penalty_cost למספר קטן.
  3. לכל רכב, מוסיפים את CLEANED ל-Vehicle.start_tags. המאפיין הזה משמש לסימון הרכב כנקיים לפני שהוא מבצע איסופים או משלוחים, בהנחה שהוא נוקה בסוף יום העבודה הקודם, ומאפשר לו לעבור מנקודת הדרך ההתחלתית ישירות לנקודת הדרך הסופית. גם אם מסלולים כאלה לא מתרחשים בפועל, ההרשאה לאפשרות הזו עוזרת לכלי האופטימיזציה לחפש מסלולים אופטימליים בצורה יעילה יותר.

  4. לכל רכב, מוסיפים את ROUTE_END ל-Vehicle.end_tags.

  5. מוסיפים רשומה חדשה ל-ShipmentModel.transition_attributes, שמגבילה את האפשרות של רכבים להגיע לציון הדרך של סיום הנסיעה ברכב כשהם לא נקיים, עם המאפיינים הבאים:

    1. מגדירים את TransitionAttributes.excluded_src_tag לערך CLEANED.

    2. מגדירים את TransitionAttributes.dst_tag לערך ROUTE_END.

    3. מגדירים את TransitionAttributes.delay לערך גדול. אם משך ההשהיה ארוך ממשך המסלול המקסימלי, למעשה אתם אוסרים על הכלי לבצע את המעבר הזה במסלול.

    לדוגמה, כשסולם הזמן של המודל הוא יום עבודה אחד, אפשר להשתמש בהשהיה של 24 שעות (86,400 שניות) כדי לאסור את המעבר לסוף המסלול מכל מקום מלבד מכון ניקוי ומתחילת המסלול:

    {
      "excluded_src_tag": "CLEANED",
      "dst_tag": "ROUTE_END",
      "delay": "86400s"
    }
    

איך בוחרים בין עיכובים לעלויות

הבחירה בין עיכובים לעלויות תלויה בטבע של האילוצים והלוגיקה העסקית שהוגדרו. כדאי להגדיר את TransitionAttributes.delay כדי להטמיע אילוצים קשיחים או כדי להביע פשרה מבחינת משך הזמן. TransitionAttributes.cost מתאים יותר כשמיישמים העדפות רכות או איזונים שמתבטאים בעלות נוספת. אתם יכולים לשלב עיכובים ועלויות באופן שרירותי, גם מבחינת הזמן שחלף וגם מבחינת העלות.

בדוגמה לניקוי הרכב נעשה שימוש בעיכוב ארוך מאוד, כי ניקוי הרכב בסוף המסלול הוא דרישה קשיחה והעיכוב הארוך מונע מהאופטימיזטור להתעלם מהדרישה. אם תגדירו רק עלות, הכלי לאופטימיזציה עשוי לדלג על הניקוי אם הוא ימצא דרך לפצות על העלות במקום אחר, למשל על ידי ביצוע יותר משלוחים בזמן 'שנשמר' בגלל שלא ניקית את הרכב.

בדוגמה של החניה נעשה שימוש בעיכוב קצר שתואם לזמן הנוסף שנדרש כדי לחנות את הרכב. אפשר גם להשתמש בעלויות בשילוב עם עיכובים, אם הנהג עוצר בחניון בתשלום.

איך מוסיפים מאפיין מעבר שתואמת לכל בקשות הביקור

בדוגמאות שלמעלה נעשה שימוש במאפייני מעבר שתואמים למיקומים שיש להם תג נתון, או למיקומים שאין להם את התג. אבל מה קורה אם צריך להוסיף מאפייני מעבר שרלוונטיים לכל המעברים?

אי אפשר פשוט להשמיט את התגים, כי כל הודעת TransitionAttributes חייבת לכלול תג אחד מ-TransitionAttributes.src_tag ו-TransitionAttributes.excluded_src_tag ותג אחד מ-TransitionAttributes.dst_tag ו-TransitionAttributes.excluded_dst_tag.

עם זאת, אפשר להתאים את כל התגים על ידי הגדרת TransitionAttributes.excluded_src_tag או TransitionAttributes.excluded_dst_tag לתג שלא נעשה בו שימוש בשום מקום במודל. התג הזה יתאים לכל המיקומים שלא משויך להם התג הזה, אבל מכיוון שבחרתם בכוונה תג שאף מיקום לא משתמש בו, מאפייני המעבר האלה יתאימו לכל המיקומים.

קריאה נוספת