ShipmentModel

מודל משלוח מכיל קבוצה של משלוחים שסט של כלי רכב צריכים לבצע, תוך צמצום העלות הכוללת, שהיא הסכום של:

  • העלות של ניתוב כלי הרכב (סכום של העלות לכל זמן כולל, העלות לכל זמן נסיעה והעלות הקבועה בכל כלי הרכב).
  • את הקנסות על משלוחים שלא בוצעו.
  • עלות משך הזמן הגלובלי של המשלוחים
ייצוג ב-JSON
{
  "shipments": [
    {
      object (Shipment)
    }
  ],
  "vehicles": [
    {
      object (Vehicle)
    }
  ],
  "globalStartTime": string,
  "globalEndTime": string,
  "globalDurationCostPerHour": number,
  "durationDistanceMatrices": [
    {
      object (DurationDistanceMatrix)
    }
  ],
  "durationDistanceMatrixSrcTags": [
    string
  ],
  "durationDistanceMatrixDstTags": [
    string
  ],
  "transitionAttributes": [
    {
      object (TransitionAttributes)
    }
  ],
  "shipmentTypeIncompatibilities": [
    {
      object (ShipmentTypeIncompatibility)
    }
  ],
  "shipmentTypeRequirements": [
    {
      object (ShipmentTypeRequirement)
    }
  ],
  "precedenceRules": [
    {
      object (PrecedenceRule)
    }
  ],
  "maxActiveVehicles": integer
}
שדות
shipments[]

object (Shipment)

קבוצת משלוחים שצריך לבצע במודל.

vehicles[]

object (Vehicle)

קבוצת כלי רכב שיכולים לשמש לביצוע ביקורים.

globalStartTime

string (Timestamp format)

זמני התחלה וסיום גלובליים של המודל: שעות מחוץ לטווח הזה לא יכולות להיחשב כחוקיות.

טווח הזמן של המודל חייב להיות פחות משנה, כלומר הערכים של globalEndTime ו-globalStartTime חייבים להיות במרחק של 31,536,000 שניות זה מזה.

כשמשתמשים בשדות cost_per_*hour, מומלץ להגדיר את החלון הזה למרווח זמן קטן יותר כדי לשפר את הביצועים (לדוגמה, אם יוצרים מודל ליום אחד, צריך להגדיר את מגבלות הזמן הגלובליות לאותו יום). אם לא מגדירים את השדה, המערכת תשתמש בערך ברירת המחדל 00:00:00 UTC, 1 בינואר 1970 (כלומר, שניות: 0, ננו-שניות: 0).

חותמת זמן בפורמט UTC 'Zulu' של RFC3339, עם רזולוציה של ננו-שנייה ועד תשע ספרות עשרוניות. דוגמאות: "2014-10-02T15:01:23Z" ו-"2014-10-02T15:01:23.045123456Z".

globalEndTime

string (Timestamp format)

אם לא מגדירים ערך, המערכת תשתמש בערך ברירת המחדל 00:00:00 UTC, 1 בינואר 1971 (כלומר, שניות: 31536000, ננו-שניות: 0).

חותמת זמן בפורמט 'Zulu' בפורמט RFC3339 UTC, עם רזולוציה של ננו-שנייה ועד תשע ספרות אחרי הנקודה. דוגמאות: "2014-10-02T15:01:23Z" ו-"2014-10-02T15:01:23.045123456Z".

globalDurationCostPerHour

number

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

durationDistanceMatrices[]

object (DurationDistanceMatrix)

מציין את מטריצות משך הזמן והמרחקים שמשמשות במודל. אם השדה הזה ריק, המערכת תשתמש במקום זאת במפות Google או במרחקים גיאודזיים, בהתאם לערך של השדה useGeodesicDistances. אם השדה לא ריק, הערך של useGeodesicDistances לא יכול להיות True וגם durationDistanceMatrixSrcTags או durationDistanceMatrixDstTags לא יכולים להיות ריקים.

דוגמאות לשימוש:

  • יש שני מיקומים: locA ו-locB.
  • רכב אחד שמתחיל את המסלול ב-locA ומסתיים ב-locA.
  • בקשה אחת לאיסוף ב-locB.
model {
  vehicles { startTags: "locA"  endTags: "locA" }
  shipments { pickups { tags: "locB" } }
  durationDistanceMatrixSrcTags: "locA"
  durationDistanceMatrixSrcTags: "locB"
  durationDistanceMatrixDstTags: "locA"
  durationDistanceMatrixDstTags: "locB"
  durationDistanceMatrices {
    rows {  # from: locA
      durations { seconds: 0 }   meters: 0    # to: locA
      durations { seconds: 100 } meters: 1000 # to: locB
    }
    rows {  # from: locB
      durations { seconds: 102 } meters: 990 # to: locA
      durations { seconds: 0 }   meters: 0   # to: locB
    }
  }
}
  • יש שלושה מיקומים: locA,‏ locB ו-locC.
  • רכב אחד מתחיל את המסלול ב-locA ומסתיים ב-locB באמצעות המטריצה 'fast'.
  • רכב אחד מתחיל את המסלול ב-locB ומסתיים ב-locB באמצעות המטריצה 'איטי'.
  • רכב אחד מתחיל את המסלול ב-locB ומסתיים ב-locB באמצעות המטריצה 'fast'.
  • בקשה אחת לאיסוף עצמי ב-locC.
model {
  vehicles { startTags: "locA" endTags: "locB" startTags: "fast" }
  vehicles { startTags: "locB" endTags: "locB" startTags: "slow" }
  vehicles { startTags: "locB" endTags: "locB" startTags: "fast" }
  shipments { pickups { tags: "locC" } }
  durationDistanceMatrixSrcTags: "locA"
  durationDistanceMatrixSrcTags: "locB"
  durationDistanceMatrixSrcTags: "locC"
  durationDistanceMatrixDstTags: "locB"
  durationDistanceMatrixDstTags: "locC"
  durationDistanceMatrices {
    vehicleStartTag: "fast"
    rows {  # from: locA
      durations { seconds: 1000 } meters: 2000 # to: locB
      durations { seconds: 600 }  meters: 1000 # to: locC
    }
    rows {  # from: locB
      durations { seconds: 0 }   meters: 0    # to: locB
      durations { seconds: 700 } meters: 1200 # to: locC
    }
    rows {  # from: locC
      durations { seconds: 702 } meters: 1190 # to: locB
      durations { seconds: 0 }   meters: 0    # to: locC
    }
  }
  durationDistanceMatrices {
    vehicleStartTag: "slow"
    rows {  # from: locA
      durations { seconds: 1800 } meters: 2001 # to: locB
      durations { seconds: 900 }  meters: 1002 # to: locC
    }
    rows {  # from: locB
      durations { seconds: 0 }    meters: 0    # to: locB
      durations { seconds: 1000 } meters: 1202 # to: locC
    }
    rows {  # from: locC
      durations { seconds: 1001 } meters: 1195 # to: locB
      durations { seconds: 0 }    meters: 0    # to: locC
    }
  }
}
durationDistanceMatrixSrcTags[]

string

תגים המגדירים את המקורות של מטריצות משך הזמן והמרחק; durationDistanceMatrices(i).rows(j) מגדיר משכי זמן ומרחקים מביקורים באמצעות התג durationDistanceMatrixSrcTags(j) לביקורים אחרים במטריצה i.

התגים תואמים ל-VisitRequest.tags או ל-Vehicle.start_tags. VisitRequest או Vehicle נתון חייב להתאים לתג אחד בלבד בשדה הזה. לתשומת ליבכם: תג המקור, תג היעד ותג המטריצה של Vehicle עשויים להיות זהים. באופן דומה, תגי המקור ותג היעד של VisitRequest עשויים להיות זהים. כל התגים צריכים להיות שונים ולא להיות מחרוזות ריקות. אם השדה הזה לא ריק, durationDistanceMatrices לא יכול להיות ריק.

durationDistanceMatrixDstTags[]

string

תגים המגדירים את היעדים של מטריצות משך הזמן והמרחק; durationDistanceMatrices(i).rows(j).durations(k) (resp הפונקציה durationDistanceMatrices(i).rows(j).meters(k)) מגדירה את משך (המרחק) של הנסיעה מביקורים עם התג durationDistanceMatrixSrcTags(j) לביקורים עם התג durationDistanceMatrixDstTags(k) במטריצה i.

התגים תואמים ל-VisitRequest.tags או ל-Vehicle.start_tags. VisitRequest או Vehicle נתון חייב להתאים לתג אחד בלבד בשדה הזה. שימו לב: ייתכן שתג המקור, תג היעד ותג המטריצה של Vehicle יהיו זהים. באופן דומה, ייתכן שתג המקור ותג היעד של VisitRequest יהיו זהים. כל התגים צריכים להיות שונים ולא להיות מחרוזות ריקות. אם השדה הזה לא ריק, השדה durationDistanceMatrices לא יכול להיות ריק.

transitionAttributes[]

object (TransitionAttributes)

מאפייני המעבר נוספו למודל.

shipmentTypeIncompatibilities[]

object (ShipmentTypeIncompatibility)

קבוצות של סוגי משלוח לא תואמים (מידע נוסף זמין ב-ShipmentTypeIncompatibility).

shipmentTypeRequirements[]

object (ShipmentTypeRequirement)

קבוצות של דרישות shipmentType (ראו ShipmentTypeRequirement).

precedenceRules[]

object (PrecedenceRule)

קבוצת כללי עדיפות שצריך לאכוף במודל.

maxActiveVehicles

integer

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

משלוח

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

ייצוג JSON
{
  "displayName": string,
  "pickups": [
    {
      object (VisitRequest)
    }
  ],
  "deliveries": [
    {
      object (VisitRequest)
    }
  ],
  "loadDemands": {
    string: {
      object (Load)
    },
    ...
  },
  "allowedVehicleIndices": [
    integer
  ],
  "costsPerVehicle": [
    number
  ],
  "costsPerVehicleIndices": [
    integer
  ],
  "pickupToDeliveryAbsoluteDetourLimit": string,
  "pickupToDeliveryTimeLimit": string,
  "shipmentType": string,
  "label": string,
  "ignore": boolean,
  "penaltyCost": number,
  "pickupToDeliveryRelativeDetourLimit": number
}
שדות
displayName

string

השם המוצג של המשלוח כפי שהוגדר על ידי המשתמש. הוא יכול להכיל עד 63 תווים ויכול להשתמש בתווי UTF-8.

pickups[]

object (VisitRequest)

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

deliveries[]

object (VisitRequest)

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

loadDemands

map (key: string, value: object (Load))

יש לטעון את הדרישות של המשלוח (לדוגמה, משקל, נפח, מספר המשטחים וכו'). המפתחות במפה צריכים להיות מזהים שמתארים את סוג העומס המתאים, רצוי שגם יחד עם היחידות. לדוגמה: 'weight_kg', 'volume_gallons', 'pallet_count' וכו'. אם מפתח מסוים לא מופיע במפה, העומס התואם נחשב כ-null.

allowedVehicleIndices[]

integer

קבוצת כלי הרכב שיכולים לבצע את המשלוח הזה. אם היא ריקה, היא עשויה לפעול בכל כלי הרכב. הרכבים מוצגים לפי המדד שלהם ברשימה vehicles של ShipmentModel.

costsPerVehicle[]

number

מציינת את העלות שתחול כשהמשלוח נמסר על ידי כל רכב. אם מציינים את השדה, הוא חייב לכלול:

  • אותו מספר רכיבים כמו costsPerVehicleIndices. costsPerVehicle[i] תואם לרכב costsPerVehicleIndices[i] מהדגם.
  • אותו מספר רכיבים כמו מספר כלי הרכב בדגם. הרכיב ה-i תואם לרכב מספר i מהדגם.

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

costsPerVehicleIndices[]

integer

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

pickupToDeliveryAbsoluteDetourLimit

string (Duration format)

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

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

startTime(delivery) - startTime(pickup) <=
t + pickupToDeliveryAbsoluteDetourLimit

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

משך זמן בשניות עם עד תשע ספרות עשרוניות, שמסתיים ב-'s'. דוגמה: "3.5s".

pickupToDeliveryTimeLimit

string (Duration format)

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

משך זמן בשניות עם עד תשע ספרות עשרוניות, שמסתיים ב-'s'. דוגמה: "3.5s".

shipmentType

string

מחרוזת שאינה ריקה שמציינת "סוג" למשלוח הזה. אפשר להשתמש בתכונה הזו כדי להגדיר חוסר תאימות או דרישות בין shipment_types (אפשר לעיין ב-shipmentTypeIncompatibilities וב-shipmentTypeRequirements ב-ShipmentModel).

שונה מ-visitTypes שצוין בביקור יחיד: כל האיסוף/המשלוחים ששייכים לאותו משלוח חולקים את אותו shipmentType.

label

string

תווית למשלוח הזה. התווית הזו מדווחת בתגובה בשדה shipmentLabel של ShipmentRoute.Visit התואם.

ignore

boolean

אם הערך הוא True, המערכת תדלג על המשלוח הזה, אבל לא תחיל penaltyCost.

התעלמות משליחה גורמת לשגיאת אימות אם יש shipmentTypeRequirements כלשהם במודל.

מותר להתעלם ממשלוח שמבוצע בinjectedFirstSolutionRoutes או בinjectedSolutionConstraint. המוכר מסיר את הביקורים הקשורים באיסוף או במסירה מהמסלול שמבצע את הפעולה. המערכת תתעלם גם מ-precedenceRules שמתייחסות למשלוחים שהמערכת התעלמה מהם.

penaltyCost

number

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

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

pickupToDeliveryRelativeDetourLimit

number

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

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

startTime(delivery) - startTime(pickup) <=
std::ceil(t * (1.0 + pickupToDeliveryRelativeDetourLimit))

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

VisitRequest

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

ייצוג JSON
{
  "arrivalLocation": {
    object (LatLng)
  },
  "arrivalWaypoint": {
    object (Waypoint)
  },
  "departureLocation": {
    object (LatLng)
  },
  "departureWaypoint": {
    object (Waypoint)
  },
  "tags": [
    string
  ],
  "timeWindows": [
    {
      object (TimeWindow)
    }
  ],
  "duration": string,
  "cost": number,
  "loadDemands": {
    string: {
      object (Load)
    },
    ...
  },
  "visitTypes": [
    string
  ],
  "label": string
}
שדות
arrivalLocation

object (LatLng)

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

arrivalWaypoint

object (Waypoint)

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

departureLocation

object (LatLng)

המיקום הגיאוגרפי שאליו הרכב יוצא אחרי השלמת VisitRequest. אפשר להשמיט אותה אם היא זהה ל-arrivalLocation. אם למודל המשלוח יש מטריצות של משך זמן ומרחק, אסור לציין את departureLocation.

departureWaypoint

object (Waypoint)

נקודת הציון שממנה הרכב יוצא אחרי השלמת ה-VisitRequest הזה. אפשר להשמיט אותו אם הוא זהה ל-arrivalWaypoint. אם מודל המשלוח כולל מטריצות של משך הזמן, אי אפשר לציין departureWaypoint.

tags[]

string

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

timeWindows[]

object (TimeWindow)

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

אם השדה TimeWindow לא מופיע, המשמעות היא שהרכב יכול לבצע את הביקור הזה בכל שלב.

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

אפשר להגדיר את costPerHourAfterSoftEndTime ואת softEndTime רק אם יש חלון זמן אחד.

duration

string (Duration format)

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

משך הזמן בשניות, עם עד תשע ספרות עשרוניות, שמסתיימים ב-'s'. דוגמה: "3.5s".

cost

number

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

loadDemands

map (key: string, value: object (Load))

דרישות העומס של בקשת הביקור הזו. השדה הזה דומה לשדה Shipment.load_demands, אבל הוא חל רק על VisitRequest הזה במקום על כל Shipment. הדרישות המפורטות כאן מתווספות לדרישות שמפורטות בShipment.load_demands.

visitTypes[]

string

מציין את סוגי הביקור. אפשר להשתמש בנתון הזה כדי להקצות זמן נוסף שנדרש לרכב כדי להשלים את הביקור הזה (ראו Vehicle.extra_visit_duration_for_visit_type).

סוג מסוים יכול להופיע רק פעם אחת.

label

string

תווית של VisitRequest. התווית הזו מדווחת בתשובה כ-visitLabel ב-ShipmentRoute.Visit המתאים.

LatLng

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

ייצוג ב-JSON
{
  "latitude": number,
  "longitude": number
}
שדות
latitude

number

קו הרוחב במעלות. הוא חייב להיות בטווח [-90.0, +90.0].

longitude

number

קו האורך במעלות. הוא חייב להיות בטווח [-180.0, +180.0].

נקודת ציון

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

ייצוג ב-JSON
{
  "sideOfRoad": boolean,

  // Union field location_type can be only one of the following:
  "location": {
    object (Location)
  },
  "placeId": string
  // End of list of possible types for union field location_type.
}
שדות
sideOfRoad

boolean

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

שדה איחוד location_type. דרכים שונות לייצוג מיקום. location_type יכול להיות רק אחת מהאפשרויות הבאות:
location

object (Location)

נקודה שצוינה באמצעות קואורדינטות גיאוגרפיות, כולל כותרת אופציונלית.

placeId

string

מזהה המקום של נקודת העניין שמשויך לנקודת הציון.

מיקום

עטיפה של מיקום (נקודה גיאוגרפית וכותרת אופציונלית).

ייצוג ב-JSON
{
  "latLng": {
    object (LatLng)
  },
  "heading": integer
}
שדות
latLng

object (LatLng)

הקואורדינטות הגיאוגרפיות של נקודת הציון.

heading

integer

כיוון המצפן שמשויך לכיוון של זרימת התנועה. הערך הזה משמש לציון הצד של הכביש שבו יתבצע האיסוף וההחזרה. ערכי הכיוון יכולים להיות מ-0 עד 360, כאשר 0 מציין כיוון צפון, 90 מציין כיוון מזרח וכו'.

TimeWindow

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

גבולות של חלון זמן מוגבל, startTime ו-endTime, אוכפים את הזמן המוקדם ביותר והאחרון של האירוע, למשל startTime <= event_time <= endTime. הערך התחתון של חלון הזמן הרך, softStartTime, מבטא העדפה שהאירוע יתרחש ב-softStartTime או אחריו, על ידי צבירת עלות שפרופורציונלית לזמן שחולף לפני softStartTime שבו מתרחש האירוע. הגבול העליון של חלון הזמן הרך, softEndTime, מבטא העדפה שהאירוע יתרחש בתאריך softEndTime או לפניו, על ידי צבירת עלות ביחס למשך הזמן שאחרי softEndTime האירוע. startTime, endTime, softStartTime ו-softEndTime צריכים לעמוד במגבלות הזמן הגלובליות (ראו ShipmentModel.global_start_time ו-ShipmentModel.global_end_time) ועליהם לפעול בהתאם לתנאים הבאים:

  0 <= `startTime` <= `endTime` and
  0 <= `startTime` <= `softStartTime` and
  0 <= `softEndTime` <= `endTime`.
ייצוג JSON
{
  "startTime": string,
  "endTime": string,
  "softStartTime": string,
  "softEndTime": string,
  "costPerHourBeforeSoftStartTime": number,
  "costPerHourAfterSoftEndTime": number
}
שדות
startTime

string (Timestamp format)

שעת ההתחלה של החלון הקופץ. אם לא צוין ערך, הוא יוגדר ל-ShipmentModel.global_start_time.

חותמת זמן בפורמט UTC 'Zulu' של RFC3339, עם רזולוציה של ננו-שנייה ועד תשע ספרות עשרוניות. דוגמאות: "2014-10-02T15:01:23Z" ו-"2014-10-02T15:01:23.045123456Z".

endTime

string (Timestamp format)

שעת הסיום של החלון הקופץ. אם לא צוין ערך, הוא יוגדר ל-ShipmentModel.global_end_time.

חותמת זמן בפורמט 'Zulu' בפורמט RFC3339 UTC, עם רזולוציה של ננו-שנייה ועד תשע ספרות אחרי הנקודה. דוגמאות: "2014-10-02T15:01:23Z" ו-"2014-10-02T15:01:23.045123456Z".

softStartTime

string (Timestamp format)

שעת ההתחלה הרכה של חלון הזמן.

חותמת זמן בפורמט 'Zulu' בפורמט RFC3339 UTC, עם רזולוציה של ננו-שנייה ועד תשע ספרות אחרי הנקודה. דוגמאות: "2014-10-02T15:01:23Z" ו-"2014-10-02T15:01:23.045123456Z".

softEndTime

string (Timestamp format)

שעת הסיום הרכה של חלון הזמן.

חותמת זמן בפורמט UTC 'Zulu' של RFC3339, עם רזולוציה של ננו-שנייה ועד תשע ספרות עשרוניות. דוגמאות: "2014-10-02T15:01:23Z" ו-"2014-10-02T15:01:23.045123456Z".

costPerHourBeforeSoftStartTime

number

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

   max(0, softStartTime - t.seconds)
                          * costPerHourBeforeSoftStartTime / 3600,
t being the time of the event.

העלות הזו חייבת להיות חיובית, ואפשר להגדיר את השדה רק אם הוגדר ערך softStartTime.

costPerHourAfterSoftEndTime

number

עלות לשעה שתתווסף לעלויות אחרות במודל אם האירוע מתרחש אחרי softEndTime, שמחושבת כך:

   max(0, t.seconds - softEndTime.seconds)
                    * costPerHourAfterSoftEndTime / 3600,
t being the time of the event.

העלות הזו חייבת להיות מספר חיובי, ואפשר להגדיר את השדה רק אם הוגדר הערך softEndTime.

כלי רכב

זו דוגמה של רכב בבעיה במשלוח. פתרון בעיה בשליחה יוצר מסלול עבור הרכב הזה שמתחיל ב-startLocation ומסתיים ב-endLocation. מסלול הוא רצף של ביקורים (מידע נוסף זמין במאמר ShipmentRoute).

ייצוג JSON
{
  "displayName": string,
  "travelMode": enum (TravelMode),
  "routeModifiers": {
    object (RouteModifiers)
  },
  "startLocation": {
    object (LatLng)
  },
  "startWaypoint": {
    object (Waypoint)
  },
  "endLocation": {
    object (LatLng)
  },
  "endWaypoint": {
    object (Waypoint)
  },
  "startTags": [
    string
  ],
  "endTags": [
    string
  ],
  "startTimeWindows": [
    {
      object (TimeWindow)
    }
  ],
  "endTimeWindows": [
    {
      object (TimeWindow)
    }
  ],
  "unloadingPolicy": enum (UnloadingPolicy),
  "loadLimits": {
    string: {
      object (LoadLimit)
    },
    ...
  },
  "costPerHour": number,
  "costPerTraveledHour": number,
  "costPerKilometer": number,
  "fixedCost": number,
  "usedIfRouteIsEmpty": boolean,
  "routeDurationLimit": {
    object (DurationLimit)
  },
  "travelDurationLimit": {
    object (DurationLimit)
  },
  "routeDistanceLimit": {
    object (DistanceLimit)
  },
  "extraVisitDurationForVisitType": {
    string: string,
    ...
  },
  "breakRule": {
    object (BreakRule)
  },
  "label": string,
  "ignore": boolean,
  "travelDurationMultiple": number
}
שדות
displayName

string

שם הרכב שהוגדר על ידי המשתמש. השם יכול להכיל עד 63 תווים, וניתן להשתמש בתווים בתקן UTF-8.

travelMode

enum (TravelMode)

מצב הנסיעה שמשפיע על הכבישים שבהם הרכב יכול לנסוע ועל המהירות שלו. מידע נוסף מופיע כאן: travelDurationMultiple.

routeModifiers

object (RouteModifiers)

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

startLocation

object (LatLng)

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

startWaypoint

object (Waypoint)

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

endLocation

object (LatLng)

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

endWaypoint

object (Waypoint)

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

startTags[]

string

מציינת תגים שמצורפים לתחילת המסלול של הרכב.

אסור להשתמש במחרוזות ריקות או כפולות.

endTags[]

string

מציינת תגים שמחוברים לסוף המסלול של הרכב.

אסור להשתמש במחרוזות ריקות או כפולות.

startTimeWindows[]

object (TimeWindow)

חלונות זמן שבמהלכם הרכב עשוי לצאת ממיקום ההתחלה. הם צריכים להיות בתוך מגבלות הזמן הגלובליות (ראו שדות ShipmentModel.global_*). אם לא צוין אחרת, אין הגבלה מלבד מגבלות הזמן הגלובליות האלה.

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

אפשר להגדיר את costPerHourAfterSoftEndTime ו-softEndTime רק אם יש חלון זמן אחד.

endTimeWindows[]

object (TimeWindow)

חלונות זמן שבמהלכם הרכב עשוי להגיע למיקום הסיום שלו. הם חייבים להיות במסגרת מגבלות הזמן הגלובליות (עיינו בשדות ShipmentModel.global_*). אם לא צוינו, אין הגבלה מלבד מגבלות הזמן הגלובליות האלה.

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

אפשר להגדיר את costPerHourAfterSoftEndTime ו-softEndTime רק אם יש חלון זמן אחד.

unloadingPolicy

enum (UnloadingPolicy)

מדיניות הסרת הטעינה שנאכפת על הרכב.

loadLimits

map (key: string, value: object (LoadLimit))

הקיבולת של הרכב (משקל, נפח, מספר המשטחים, למשל). המפתחות במפה הם המזהים של סוג הטעינה, בהתאם למפתחות בשדה Shipment.load_demands. אם מפתח מסוים לא מופיע במפה הזו, הקיבולת המתאימה נחשבת כבלתי מוגבלת.

costPerHour

number

עלויות הרכב: כל העלויות צריכות להתווסף זו לזו, והן חייבות להיות באותה יחידה כמו Shipment.penalty_cost.

עלות לשעה של מסלול הרכב. העלות הזו חלה על הזמן הכולל במסלול, והיא כוללת את זמן הנסיעה, זמן ההמתנה וזמן הביקור. שימוש ב-costPerHour במקום ב-costPerTraveledHour בלבד עלול להוביל לזמן אחזור ארוך יותר.

costPerTraveledHour

number

העלות לשעת נסיעה במסלול הרכב. העלות הזו חלה רק על זמן הנסיעה במסלול (כלומר, שדווח ב-ShipmentRoute.transitions), ולא כוללת את זמן ההמתנה ואת זמן הביקור.

costPerKilometer

number

העלות לכל קילומטר במסלול הרכב. העלות הזו חלה על המרחק שמדווח ב-ShipmentRoute.transitions, ולא חלה על מרחק כלשהו שעבר באופן משתמע מ-arrivalLocation ל-departureLocation של VisitRequest יחיד.

fixedCost

number

החלה של עלות קבועה אם הרכב הזה משמש לטיפול במשלוח.

usedIfRouteIsEmpty

boolean

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

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

אחרת, הרכב לא נוסע ממיקום ההתחלה למיקום הסיום, ולא מתוזמנים לו breakRule או עיכוב (מ-TransitionAttributes). במקרה כזה, השדה ShipmentRoute של הרכב לא מכיל מידע מלבד המדד והתווית של הרכב.

routeDurationLimit

object (DurationLimit)

המגבלה חלה על משך הזמן הכולל של המסלול של הרכב. בOptimizeToursResponse נתון, משך המסלול של כלי רכב הוא ההפרש בין vehicleEndTime ל-vehicleStartTime.

travelDurationLimit

object (DurationLimit)

הגבלה שחלה על משך הנסיעה במסלול של הרכב. ב-OptimizeToursResponse נתון, משך הנסיעה במסלול הוא הסכום של כל ה-transitions.travel_duration שהוא מכיל.

routeDistanceLimit

object (DistanceLimit)

המגבלה חלה על המרחק הכולל של מסלול הרכב. ב-OptimizeToursResponse נתון, מרחק המסלול הוא הסכום של כל transitions.travel_distance_meters שלו.

extraVisitDurationForVisitType

map (key: string, value: string (Duration format))

מציין מפה ממחרוזות של visitTypes לאורך זמן. משך הזמן הוא זמן בנוסף ל-VisitRequest.duration שיילקח בביקורים עם visitTypes שצוין. משך הביקור הנוסף הזה מוסיף עלות אם מציינים costPerHour. מפתחות (למשל visitTypes) לא יכולים להיות מחרוזות ריקות.

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

breakRule

object (BreakRule)

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

label

string

מציינת תווית לרכב הזה. התווית הזו מדווחת בתגובה כ-vehicleLabel של ShipmentRoute התואם.

ignore

boolean

אם הערך הוא true, הערך של usedIfRouteIsEmpty חייב להיות false, והרכב הזה לא ישמש.

אם משלוח מבוצע על ידי כלי רכב שהמערכת מתעלמת ממנו בתוך injectedFirstSolutionRoutes, המערכת מדלגת עליו בפתרון הראשון, אבל ניתן לבצע אותו בתגובה ללא עלות.

אם משלוח מתבצע על ידי רכב שנדחה ב-injectedSolutionConstraint, וכל איסוף או מסירה קשורים מוגבלים להישאר ברכב (כלומר, לא הושהו לרמה RELAX_ALL_AFTER_THRESHOLD), הם יושמטו בתגובה. אם לשדה allowedVehicleIndices של משלוח מסוים יש ערך לא ריק, והמערכת מתעלמת מכל הרכבים המותרים, המשלוח יידלג בתגובה.

travelDurationMultiple

number

גורם מכפיל שאפשר להשתמש בו כדי להגדיל או להקטין את זמני הנסיעה של הרכב הזה. לדוגמה, אם ההגדרה הזו תהיה 2.0, המשמעות היא שהרכב הזה איטי יותר ומשך הנסיעה שלו הוא פי שניים מזה של כלי רכב רגילים. המכפיל הזה לא משפיע על משכי הביקורים. זה משפיע על העלות אם מציינים costPerHour או costPerTraveledHour. הערך הזה צריך להיות בטווח [0.001, 1000.0]. אם לא מגדירים את הערך, הרכב נחשב לרכב רגיל והמכפיל הזה נחשב ל-1.0.

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

מידע נוסף מופיע בקטע extraVisitDurationForVisitType שבהמשך.

TravelMode

אמצעי הגעה שאפשר להשתמש בהם ברכב.

הקבוצות האלה צריכות להיות קבוצת משנה של מצבי הנסיעה המועדפים ב-API של המסלולים בפלטפורמה של מפות Google, מידע נוסף זמין בכתובת: https://developers.google.com/maps/documentation/routes_preferred/reference/rest/Shared.Types/RouteTravelMode.

טיפוסים בני מנייה (enum)
TRAVEL_MODE_UNSPECIFIED מצב נסיעה לא מוגדר, המקביל ל-DRIVING.
DRIVING אמצעי התחבורה שמתאים למסלול נסיעה (רכב, ...).
WALKING מצב נסיעה שתואם למסלול הליכה.

RouteModifiers

האובייקט הזה מכיל קבוצה של תנאים אופציונליים שצריך לעמוד בהם כשמחשבים מסלולים לכלי רכב. הערך הזה דומה ל-RouteModifiers בממשק ה-API המועדף של מסלולים בפלטפורמה של מפות Google. מידע נוסף זמין בכתובת: https://developers.google.com/maps/documentation/routes/reference/rest/v2/RouteModifiers.

ייצוג JSON
{
  "avoidTolls": boolean,
  "avoidHighways": boolean,
  "avoidFerries": boolean,
  "avoidIndoor": boolean
}
שדות
avoidTolls

boolean

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

avoidHighways

boolean

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

avoidFerries

boolean

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

avoidIndoor

boolean

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

UnloadingPolicy

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

משלוחים אחרים מתבצעים בחינם בכל מקום במסלול, ללא קשר ל-unloadingPolicy.

טיפוסים בני מנייה (enum)
UNLOADING_POLICY_UNSPECIFIED מדיניות הסרת הנתונים שנטענו לא צוינה. המשלוחים צריכים להתבצע רק אחרי האיסוף התואם שלהם.
LAST_IN_FIRST_OUT משלוחים צריכים להתרחש בסדר הפוך.
FIRST_IN_FIRST_OUT המשלוחים חייבים להתבצע באותו סדר שבו בוצעו האיסופים

LoadLimit

הגדרת מגבלת עומס שחלה על רכב, למשל: "המשאית הזו יכולה לשאת עד 3,500 ק"ג". loadLimits.

ייצוג JSON
{
  "softMaxLoad": string,
  "costPerUnitAboveSoftMax": number,
  "startLoadInterval": {
    object (Interval)
  },
  "endLoadInterval": {
    object (Interval)
  },
  "maxLoad": string,
  "costPerKilometer": {
    object (LoadCost)
  },
  "costPerTraveledHour": {
    object (LoadCost)
  }
}
שדות
softMaxLoad

string (int64 format)

מגבלה רכה של העומס. costPerUnitAboveSoftMax.

costPerUnitAboveSoftMax

number

אם העומס בכל זאת יחרוג מ-softMaxLoad במסלול של הרכב הזה, יחול קנס העלות הבא (פעם אחת בלבד לכל רכב): (עומס - softMaxLoad) * costPerUnitAboveSoftMax. כל העלויות צריכות להתווסף, והן חייבות להיות באותה יחידה כמו Shipment.penalty_cost.

startLoadInterval

object (Interval)

מרווח הזמן המקובל לטעינה של הרכב בתחילת המסלול.

endLoadInterval

object (Interval)

מרווח העומס הקביל של הרכב בסוף המסלול.

maxLoad

string (int64 format)

עומס מקסימלי מקובל.

costPerKilometer

object (LoadCost)

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

costPerTraveledHour

object (LoadCost)

העלות של נסיעה עם יחידת עומס במשך שעה אחת ברכב הזה.

מרווח

מרווח בין סכומי העומסים הקבילים.

ייצוג JSON
{
  "min": string,
  "max": string
}
שדות
min

string (int64 format)

עומס קביל מינימלי. מספר זה חייב להיות 0 ומעלה. אם מציינים את שניהם, הערך של min חייב להיות ≤ max.

max

string (int64 format)

עומס מקסימלי מקובל. מספר זה חייב להיות 0 ומעלה. אם לא צוין ערך, העומס המקסימלי לא מוגבל על ידי ההודעה הזו. אם מציינים את שניהם, הערך של min חייב להיות ≤ max.

LoadCost

העלות של העברת יחידת עומס אחת במהלך Transition. לכל עומס נתון, העלות היא הסכום של שני חלקים:

  • min(load, loadThreshold) * costPerUnitBelowThreshold
  • max(0, load - loadThreshold) * costPerUnitAboveThreshold

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

load_limit {
  key: "weight"
  value {
    costPerKilometer {
      loadThreshold: 15
      costPerUnitBelowThreshold: 2.0
      costPerUnitAboveThreshold: 10.0
    }
  }
}

והמסלול שלו הוא start,pickup,pickup,delivery,delivery,end עם מעברים:

transition { vehicle_load['weight'] { amount: 0 }
             travelDistanceMeters: 1000.0 }
transition { vehicle_load['weight'] { amount: 10 }
             travelDistanceMeters: 1000.0 }
transition { vehicle_load['weight'] { amount: 20 }
             travelDistanceMeters: 1000.0 }
transition { vehicle_load['weight'] { amount: 10 }
             travelDistanceMeters: 1000.0 }
transition { vehicle_load['weight'] { amount: 0 }
             travelDistanceMeters: 1000.0 }

אז העלות שנצברה על ידי LoadCost היא (cost_below * load_below * kilometers + cost_above * load_above * kms)

  • transition 0: 0.0
  • מעבר 1: 2.0 * 10 * 1.0 + 10.0 * 0 * 1.0 = 20.0
  • מעבר 2: 2.0 * 15 * 1.0 + 10.0 * (20-15) * 1.0 = 80.0
  • מעבר 3: 2.0 * 10 * 1.0 + 10.0 * 0 * 1.0 = 20.0
  • מעבר 4: 0.0

לכן, הערך LoadCost לאורך המסלול הוא 120.0.

עם זאת, אם המסלול הוא התחלה,איסוף,משלוח,איסוף,משלוח,עם מעברים:

transition { vehicle_load['weight'] { amount: 0 }
             travelDistanceMeters: 1000.0 }
transition { vehicle_load['weight'] { amount: 10 }
             travelDistanceMeters: 1000.0 }
transition { vehicle_load['weight'] { amount: 0 }
             travelDistanceMeters: 1000.0 }
transition { vehicle_load['weight'] { amount: 10 }
             travelDistanceMeters: 1000.0 }
transition { vehicle_load['weight'] { amount: 0 }
             travelDistanceMeters: 1000.0 }

העלות שמשויכת לLoadCost הזה היא

  • מעבר 0: 0.0
  • מעבר 1: 2.0 * 10 * 1.0 + 10.0 * 0 * 1.0 = 20.0
  • מעבר 2: 0.0
  • מעבר 3: 2.0 * 10 * 1.0 + 10.0 * 0 * 1.0 = 20.0
  • מעבר 4: 0.0

כאן הערך של LoadCost במסלול הוא 40.0.

LoadCost מייקר את הפתרונות עם מעברים עמוסים.

ייצוג ב-JSON
{
  "loadThreshold": string,
  "costPerUnitBelowThreshold": number,
  "costPerUnitAboveThreshold": number
}
שדות
loadThreshold

string (int64 format)

כמות העומס שמעליה העלות להעברת יחידת עומס משתנה מ-costPerUnitBelowThreshold ל-costPerUnitAboveThreshold. חייב להיות >= 0.

costPerUnitBelowThreshold

number

העלות של העברת יחידת עומס, לכל יחידה בין 0 לבין סף. הערך חייב להיות סופי וגדול מ-0.

costPerUnitAboveThreshold

number

העלות של העברת יחידת עומס, לכל יחידה מעל הסף. במקרה המיוחד שבו הסף = 0, מדובר בעלות קבועה לכל יחידה. חייב להיות ערך סופי, ו- >= 0.

DurationLimit

מגבלה שמגדירה את משך הזמן המקסימלי של מסלול הרכב. הוא יכול להיות קשה או רך.

כשמגדירים שדה של מגבלה רכה, צריך להגדיר יחד גם את סף המגבלה הרכה וגם את העלות המשויכת אליה.

ייצוג ב-JSON
{
  "maxDuration": string,
  "softMaxDuration": string,
  "quadraticSoftMaxDuration": string,
  "costPerHourAfterSoftMax": number,
  "costPerSquareHourAfterQuadraticSoftMax": number
}
שדות
maxDuration

string (Duration format)

מגבלה קשיחה שמגבילה את משך הזמן למקסימום עד maxDuration.

משך הזמן בשניות, עם עד תשע ספרות עשרוניות, שמסתיימים ב-'s'. דוגמה: "3.5s".

softMaxDuration

string (Duration format)

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

אם מוגדר, softMaxDuration חייב להיות לא שלילי. אם גם maxDuration מוגדר, הערך של softMaxDuration חייב להיות קטן מ-maxDuration.

משך הזמן בשניות, עם עד תשע ספרות עשרוניות, שמסתיימים ב-'s'. דוגמה: "3.5s".

quadraticSoftMaxDuration

string (Duration format)

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

אם מוגדר, quadraticSoftMaxDuration חייב להיות לא שלילי. אם גם maxDuration מוגדר, הערך של quadraticSoftMaxDuration חייב להיות קטן מ-maxDuration וההפרש לא יכול להיות גדול מיום אחד:

maxDuration - quadraticSoftMaxDuration <= 86400 seconds

משך הזמן בשניות, עם עד תשע ספרות עשרוניות, שמסתיימים ב-'s'. דוגמה: "3.5s".

costPerHourAfterSoftMax

number

העלות לשעה שקיימת במקרה של הפרת הסף של softMaxDuration. העלות הנוספת היא 0 אם משך הזמן נמוך מהסף. אחרת, העלות תלויה במשך הזמן באופן הבא:

  costPerHourAfterSoftMax * (duration - softMaxDuration)

העלות חייבת להיות לא שלילית.

costPerSquareHourAfterQuadraticSoftMax

number

העלות לשעה בריבוע אם חלה הפרה של הסף של quadraticSoftMaxDuration.

העלות הנוספת היא 0 אם משך הזמן נמוך מהסף. אחרת, העלות תלויה במשך הזמן באופן הבא:

  costPerSquareHourAfterQuadraticSoftMax *
  (duration - quadraticSoftMaxDuration)^2

העלות חייבת להיות לא שלילית.

DistanceLimit

מגבלה שמגדירה מרחק מקסימלי שאפשר לעבור בו. הוא יכול להיות קשה או רך.

אם מוגדרת מגבלה רכה, צריך להגדיר גם את softMaxMeters וגם את costPerKilometerAboveSoftMax, והם לא יכולים להיות שליליים.

ייצוג ב-JSON
{
  "maxMeters": string,
  "softMaxMeters": string,
  "costPerKilometerBelowSoftMax": number,
  "costPerKilometerAboveSoftMax": number
}
שדות
maxMeters

string (int64 format)

מגבלה קשיחה שמגבילה את המרחק ל-maxMeters לכל היותר. המגבלה חייבת להיות לא שלילית.

softMaxMeters

string (int64 format)

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

אם softMaxMeters מוגדר, הערך שלו חייב להיות קטן מ-maxMeters ולא שלילי.

costPerKilometerBelowSoftMax

number

העלות לקילומטר שנצברו, גדלה עד ל-softMaxMeters, באמצעות הנוסחה:

  min(distanceMeters, softMaxMeters) / 1000.0 *
  costPerKilometerBelowSoftMax.

עלות זו לא נתמכת בrouteDistanceLimit.

costPerKilometerAboveSoftMax

number

עלות לקילומטר אם המרחק חורג מהמגבלה של softMaxMeters. העלות הנוספת היא 0 אם המרחק מתחת למגבלה, אחרת הנוסחה לחישוב העלות היא:

  (distanceMeters - softMaxMeters) / 1000.0 *
  costPerKilometerAboveSoftMax.

העלות חייבת להיות לא שלילית.

BreakRule

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

  • במהלך הנסיעה בין שני ביקורים (כולל הזמן שלפני הביקור או אחריו, אבל לא באמצע הביקור). במקרה כזה, זמן הנסיעה המתאים בין הביקורים יתארך.
  • או לפני הפעלת הרכב (לא ניתן להפעיל את הרכב באמצע הפסקה), במקרה כזה הוא לא משפיע על מועד הפעלת הרכב.
  • או אחרי סיום הנסיעה (כלומר, עם שעת הסיום של הרכב).
ייצוג ב-JSON
{
  "breakRequests": [
    {
      object (BreakRequest)
    }
  ],
  "frequencyConstraints": [
    {
      object (FrequencyConstraint)
    }
  ]
}
שדות
breakRequests[]

object (BreakRequest)

רצף ההפסקות. הצגת ההודעה של BreakRequest.

frequencyConstraints[]

object (FrequencyConstraint)

בכפוף לFrequencyConstraint עשויה לחול. כולם צריכים לעמוד בדרישות של הBreakRequest של הBreakRule הזה. ראו FrequencyConstraint.

BreakRequest

צריך לדעת מראש את רצף ההפסקות (כלומר, המספר והסדר שלהן) שחלים על כל רכב. ערכי ה-BreakRequest החוזרים מגדירים את הרצף הזה, בסדר שבו הם חייבים להתרחש. חלונות הזמן שלהם (earliestStartTime / latestStartTime) עשויים להיות חופפים, אבל הם צריכים להיות תואמים להזמנה (אפשרות זו מסומנת).

ייצוג JSON
{
  "earliestStartTime": string,
  "latestStartTime": string,
  "minDuration": string
}
שדות
earliestStartTime

string (Timestamp format)

חובה. הגבול התחתון (כולל) בתחילת ההפסקה.

חותמת זמן בפורמט UTC 'Zulu' של RFC3339, עם רזולוציה של ננו-שנייה ועד תשע ספרות עשרוניות. דוגמאות: "2014-10-02T15:01:23Z" ו-"2014-10-02T15:01:23.045123456Z".

latestStartTime

string (Timestamp format)

חובה. הגבול העליון (כולל) של תחילת ההפסקה.

חותמת זמן בפורמט 'Zulu' בפורמט RFC3339 UTC, עם רזולוציה של ננו-שנייה ועד תשע ספרות אחרי הנקודה. דוגמאות: "2014-10-02T15:01:23Z" ו-"2014-10-02T15:01:23.045123456Z".

minDuration

string (Duration format)

חובה. משך זמן מינימלי להפסקה. חייב להיות חיובי.

משך הזמן בשניות, עם עד תשע ספרות עשרוניות, שמסתיימים ב-'s'. דוגמה: "3.5s".

FrequencyConstraint

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

{
   minBreakDuration { seconds: 3600 }         # 1 hour.
   maxInterBreakDuration { seconds: 39600 }  # 11 hours (12 - 1 = 11).
}

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

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

  04:00 vehicle start
   .. performing travel and visits ..
  09:00 1 hour break
  10:00 end of the break
   .. performing travel and visits ..
  12:00 20-min lunch break
  12:20 end of the break
   .. performing travel and visits ..
  21:00 1 hour break
  22:00 end of the break
   .. performing travel and visits ..
  23:59 vehicle end
ייצוג ב-JSON
{
  "minBreakDuration": string,
  "maxInterBreakDuration": string
}
שדות
minBreakDuration

string (Duration format)

חובה. משך ההפסקה המינימלי לאילוץ הזה. לא שלילי. הצגת התיאור של FrequencyConstraint.

משך זמן בשניות עם עד תשע ספרות עשרוניות, שמסתיים ב-'s'. דוגמה: "3.5s".

maxInterBreakDuration

string (Duration format)

חובה. התקופה המקסימלית המותרת של כל מרווח זמן במסלול שלא כולל לפחות חלק מההפסקה של duration >= minBreakDuration. חייב להיות חיובי.

משך הזמן בשניות, עם עד תשע ספרות עשרוניות, שמסתיימים ב-'s'. דוגמה: "3.5s".

DurationDistanceMatrix

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

ייצוג ב-JSON
{
  "rows": [
    {
      object (Row)
    }
  ],
  "vehicleStartTag": string
}
שדות
rows[]

object (Row)

מציין את השורות של מטריצות משך הזמן והמרחק. הוא חייב להכיל את אותו מספר רכיבים כמו ShipmentModel.duration_distance_matrix_src_tags.

vehicleStartTag

string

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

כל התחלה של כלי רכב חייבת להתאים למטריצה אחת בלבד, כלומר, אחד מהשדות startTags שלה חייב להתאים ל-vehicleStartTag של מטריצה (ולמטריצה הזו בלבד).

לכל המטריצות צריך להיות vehicleStartTag שונה.

שורה

מציין שורה במטריצה של משך הזמן והמרחק.

ייצוג JSON
{
  "durations": [
    string
  ],
  "meters": [
    number
  ]
}
שדות
durations[]

string (Duration format)

הערכים של משך הזמן בשורה נתונה. הוא חייב להכיל את אותו מספר רכיבים כמו ShipmentModel.duration_distance_matrix_dst_tags.

משך הזמן בשניות, עם עד תשע ספרות עשרוניות, שמסתיימים ב-'s'. דוגמה: "3.5s".

meters[]

number

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

TransitionAttributes

מציין מאפיינים של מעברים בין שני ביקורים רצופים במסלול. כמה TransitionAttributes עשויים לחול על אותו מעבר: במקרה כזה, כל העלויות הנוספות מצטברות, והאילוץ או המגבלה המחמירים ביותר חלים (לפי הסמנטיקה הטבעית "AND").

ייצוג ב-JSON
{
  "srcTag": string,
  "excludedSrcTag": string,
  "dstTag": string,
  "excludedDstTag": string,
  "cost": number,
  "costPerKilometer": number,
  "distanceLimit": {
    object (DistanceLimit)
  },
  "delay": string
}
שדות
srcTag

string

תגים שמגדירים את קבוצת המעברים (src->dst) שעליהם המאפיינים האלה חלים.

ביקור במקור או התחלת רכב תואמים אם ה-VisitRequest.tags או ה-Vehicle.start_tags שלהם מכילים srcTag או לא מכילים excludedSrcTag (תלוי איזה משני השדות האלה לא ריק).

excludedSrcTag

string

srcTag. בדיוק אחד מהשדות srcTag ו-excludedSrcTag חייב להיות לא ריק.

dstTag

string

ביקור ביעד או סיום רכב תואמים אם ה-VisitRequest.tags או Vehicle.end_tags שלו מכילים dstTag או לא מכילים excludedDstTag (תלוי איזה משני השדות האלה לא ריק).

excludedDstTag

string

dstTag. בדיוק אחד מהערכים dstTag ו-excludedDstTag לא יכול להיות ריק.

cost

number

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

costPerKilometer

number

המערכת מציינת עלות לקילומטר שחלה על המרחק שנסע במהלך המעבר הזה. הוא מצטבר לכל Vehicle.cost_per_kilometer שצוין ברכב.

distanceLimit

object (DistanceLimit)

מציין מגבלה על המרחק שנסע במהלך המעבר הזה.

החל מיוני 2021, יש תמיכה רק במגבלות רכות.

delay

string (Duration format)

הערך הזה מציין את העיכוב שנוצר במהלך המעבר.

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

משך זמן בשניות עם עד תשע ספרות עשרוניות, שמסתיים ב-'s'. דוגמה: "3.5s".

ShipmentTypeIncompatibility

מציין אי-תאימות בין משלוחים בהתאם ל-shipmentType שלהם. הצגת משלוחים לא תואמים באותו מסלול מוגבלת על סמך מצב אי-התאימות.

ייצוג ב-JSON
{
  "types": [
    string
  ],
  "incompatibilityMode": enum (IncompatibilityMode)
}
שדות
types[]

string

רשימה של סוגים לא תואמים. שתי משלוחים עם shipment_types שונה מאלה שרשומים הם 'לא תואמים'.

incompatibilityMode

enum (IncompatibilityMode)

המצב שחלה על חוסר התאימות.

IncompatibilityMode

מצבים שמגדירים את האופן שבו משלוחים לא תואמים מוגבלים לאותו מסלול.

טיפוסים בני מנייה (enum)
INCOMPATIBILITY_MODE_UNSPECIFIED מצב אי-תאימות לא מוגדר. אין להשתמש בערך הזה אף פעם.
NOT_PERFORMED_BY_SAME_VEHICLE במצב הזה, אף פעם לא ניתן לשתף את אותו רכב בין שתי משלוחים עם סוגים לא תואמים.
NOT_IN_SAME_VEHICLE_SIMULTANEOUSLY

לשני משלוחים שאינם תואמים למצב חוסר התאימות של NOT_IN_SAME_VEHICLE_SIMULTANEOUSLY:

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

ShipmentTypeRequirement

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

ייצוג ב-JSON
{
  "requiredShipmentTypeAlternatives": [
    string
  ],
  "dependentShipmentTypes": [
    string
  ],
  "requirementMode": enum (RequirementMode)
}
שדות
requiredShipmentTypeAlternatives[]

string

רשימה של סוגי משלוחים חלופיים הנדרשים על ידי dependentShipmentTypes.

dependentShipmentTypes[]

string

בכל משלוחים עם סוג בשדה dependentShipmentTypes, צריך לבקר לפחות במשלוח אחד מסוג requiredShipmentTypeAlternatives באותו מסלול.

הערה: אסור להשתמש בשרשראות של דרישות כך ש-shipmentType תלוי בעצמו.

requirementMode

enum (RequirementMode)

המצב הוחל על הדרישה.

RequirementMode

מצבים שמגדירים את המראה של משלוחים תלויים במסלול.

טיפוסים בני מנייה (enum)
REQUIREMENT_MODE_UNSPECIFIED מצב הדרישה לא צוין. אין להשתמש בערך הזה אף פעם.
PERFORMED_BY_SAME_VEHICLE במצב הזה, כל המשלוחים 'התלויים' חייבים להשתמש באותו כלי רכב לפחות לאחד מהמשלוחים 'החובה' שלהם.
IN_SAME_VEHICLE_AT_PICKUP_TIME

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

לכן, לאיסוף משלוח 'תלוי' צריך להיות:

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

PrecedenceRule

כלל עדיפות בין שני אירועים (כל אירוע הוא איסוף או מסירה של משלוח): האירוע 'שני' צריך להתחיל לפחות offsetDuration אחרי שהאירוע 'ראשון' התחיל.

כמה סדרי עדיפויות יכולים להתייחס לאותו אירוע (או לאירועים קשורים), למשל: 'איסוף ב' מתבצע אחרי מסירת פריט א' ו'איסוף של ב' מתבצע אחרי איסוף של ב'.

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

ייצוג JSON
{
  "firstIsDelivery": boolean,
  "secondIsDelivery": boolean,
  "offsetDuration": string,
  "firstIndex": integer,
  "secondIndex": integer
}
שדות
firstIsDelivery

boolean

מציין אם האירוע 'הראשון' הוא מסירה.

secondIsDelivery

boolean

מציין אם האירוע 'שני' הוא מסירה.

offsetDuration

string (Duration format)

ההיסט בין האירוע 'ראשון' לבין האירוע 'שני'. הערך יכול להיות שלילי.

משך זמן בשניות עם עד תשע ספרות עשרוניות, שמסתיים ב-'s'. דוגמה: "3.5s".

firstIndex

integer

אינדקס המשלוח של האירוע 'הראשון'. צריך לציין את השדה הזה.

secondIndex

integer

אינדקס המשלוח של האירוע 'שני'. חובה לציין את השדה הזה.