מגבלות על חלון הזמנים של איסוף ומסירה

המערכת OptimizeToursRequest מחילה את האילוצים על הפרטים הבאים:

  • משלוחים, שמשפיעים על אופן ביצוע המשלוחים
  • כלי רכב, שמשפיעים על אופן חישוב מסלולי הרכבים
  • באופן גלובלי, משפיע גם על כלי רכב וגם על משלוחים.

המדריך הזה מתמקד באילוץ משלוח חיוני: חלונות זמן.

חלונות זמן הם סוג של אילוץ שאתם מספקים בהודעה OptimizeToursRequest (REST, gRPC) כדי לציין מגבלות מבוססות-זמן על פעילויות המשלוח. סוג האילוץ הזה משפיע גם על המועד ועל האופן שבו אפשר לבצע את המשלוח, וגם על הקצאת הרכבים להובלה. בעזרת האילוצים האלה, כלי האופטימיזציה נותן עדיפות לכלי הרכב שעומדים במגבלות הזמן של המשלוח בצורה הטובה ביותר.

מגבלות משלוח: חלונות זמן

תוכלו לציין בהודעה Shipment.VisitRequest מתי יתבצע איסוף או משלוח, באופן הבא:

  • שימוש בנכס timeWindows בהודעה (REST, gRPC)
  • מציינים את זמן ההתחלה והסיום בהודעה של TimeWindow (REST, gRPC).

בקשה לדוגמה עם מגבלות של חלון זמן

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

דוגמה לבקשה עם חלונות זמן

{
  "populatePolylines": false,
  "populateTransitionPolylines": false,
  "model": {
    "globalStartTime": "2023-01-13T16:00:00Z",
    "globalEndTime": "2023-01-14T16:00:00Z",
    "shipments": [
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789456,
              "longitude": -122.390192
            },
            "duration": "250s",
            "timeWindows": [
              {
                "startTime": "2023-01-13T18:00:00Z",
                "endTime": "2023-01-13T19:00:00Z"
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 100.0
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789116,
              "longitude": -122.395080
            },
            "duration": "250s",
            "timeWindows": [
              {
                "startTime": "2023-01-13T18:00:00Z",
                "endTime": "2023-01-13T18:30:00Z"
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 20.0
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.795242,
              "longitude": -122.399347
            },
            "duration": "250s",
            "timeWindows": [
              {
                "startTime": "2023-01-13T17:30:00Z",
                "endTime": "2023-01-13T18:00:00Z"
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 50.0
      }
    ],
    "vehicles": [
      {
        "endLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "startLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "costPerHour": 40.0,
        "costPerKilometer": 10.0
      }
    ]
  }
}
    

דוגמה לתגובה עם מגבלות של חלון זמן

בתשובה לדוגמה, שעות ההתחלה והסיום של הרכב הן 17:35:50 ו-18:17:24 בהתאמה. הזמנים האלה משקפים את האופטימיזציה שמצמצמת את הזמן שנדרש להפעלת הרכב שצוין בבקשה costPerHour, תוך עמידה בכל המגבלות של חלון הזמן. השימוש בשעה 17:35:50 כשעת התחלה מבטל את הצורך ברכב להמתין במיקום מסוים עד שחלון הזמן של הביקור מתחיל. הערך הזה מופיע בתגובה כאפס waitDuration ערכים.

הצגת תשובה לבקשה לדוגמה עם חלונות זמן

{
  "routes": [
    {
      "vehicleStartTime": "2023-01-13T17:35:50Z",
      "vehicleEndTime": "2023-01-13T18:17:24Z",
      "visits": [
        {
          "isPickup": true,
          "startTime": "2023-01-13T17:35:50Z",
          "detour": "0s"
        },
        {
          "shipmentIndex": 1,
          "isPickup": true,
          "startTime": "2023-01-13T17:38:20Z",
          "detour": "150s"
        },
        {
          "shipmentIndex": 2,
          "isPickup": true,
          "startTime": "2023-01-13T17:40:50Z",
          "detour": "300s"
        },
        {
          "shipmentIndex": 2,
          "startTime": "2023-01-13T17:50:09Z",
          "detour": "0s"
        },
        {
          "shipmentIndex": 1,
          "startTime": "2023-01-13T18:00:00Z",
          "detour": "796s"
        },
        {
          "startTime": "2023-01-13T18:07:35Z",
          "detour": "1520s"
        }
      ],
      "transitions": [
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T17:35:50Z"
        },
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T17:38:20Z"
        },
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T17:40:50Z"
        },
        {
          "travelDuration": "409s",
          "travelDistanceMeters": 1371,
          "waitDuration": "0s",
          "totalDuration": "409s",
          "startTime": "2023-01-13T17:43:20Z"
        },
        {
          "travelDuration": "341s",
          "travelDistanceMeters": 1312,
          "waitDuration": "0s",
          "totalDuration": "341s",
          "startTime": "2023-01-13T17:54:19Z"
        },
        {
          "travelDuration": "205s",
          "travelDistanceMeters": 636,
          "waitDuration": "0s",
          "totalDuration": "205s",
          "startTime": "2023-01-13T18:04:10Z"
        },
        {
          "travelDuration": "339s",
          "travelDistanceMeters": 1276,
          "waitDuration": "0s",
          "totalDuration": "339s",
          "startTime": "2023-01-13T18:11:45Z"
        }
      ],
      "metrics": {
        "performedShipmentCount": 3,
        "travelDuration": "1294s",
        "waitDuration": "0s",
        "delayDuration": "0s",
        "breakDuration": "0s",
        "visitDuration": "1200s",
        "totalDuration": "2494s",
        "travelDistanceMeters": 4595
      },
      "routeCosts": {
        "model.vehicles.cost_per_hour": 27.711111111111112,
        "model.vehicles.cost_per_kilometer": 45.95
      },
      "routeTotalCost": 73.661111111111111
    }
  ],
  "metrics": {
    "aggregatedRouteMetrics": {
      "performedShipmentCount": 3,
      "travelDuration": "1294s",
      "waitDuration": "0s",
      "delayDuration": "0s",
      "breakDuration": "0s",
      "visitDuration": "1200s",
      "totalDuration": "2494s",
      "travelDistanceMeters": 4595
    },
    "usedVehicleCount": 1,
    "earliestVehicleStartTime": "2023-01-13T17:35:50Z",
    "latestVehicleEndTime": "2023-01-13T18:17:24Z",
    "totalCost": 73.661111111111111,
    "costs": {
      "model.vehicles.cost_per_hour": 27.711111111111112,
      "model.vehicles.cost_per_kilometer": 45.95
    }
  }
}
    

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

  1. shipments[2] נמסר בשעה 17:50
  2. shipments[1] נמסר בשעה 18:00
  3. shipments[0] נמסר בשעה 18:07

הבקשה לדוגמה מציינת אילוצים קשים של חלון זמן, ולכן יש להשלים את ההעברה בתוך החלונות האלה. אם אי אפשר לבצע את הביצוע של VisitRequests במשלוח או בחסכון בעלויות, כלי האופטימיזציה מדלג על המשלוח. אם למשלוח יש penaltyCost, האופטימיזציה מוסיפה אותו לעלויות שמדווחות בתגובה ל-metrics. אחרת, המאפיין skippedMandatoryShipmentCount של ההודעה OptimizeToursResponse (REST, gRPC) יגדל.

אם משנים את חלונות הזמן על ידי החלפת החלון של shipment[1] מספר שעות מאוחר יותר (ל-21:00 מ-18:00), התוצאות יהיו שונות, כפי שמתואר בדוגמאות הבאות.

דוגמה לבקשה עם חלונות זמן שלא ניתן למלא

{
  "populatePolylines": false,
  "populateTransitionPolylines": false,
  "model": {
    "globalStartTime": "2023-01-13T16:00:00Z",
    "globalEndTime": "2023-01-14T16:00:00Z",
    "shipments": [
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789456,
              "longitude": -122.390192
            },
            "duration": "250s",
            "timeWindows": [
              {
                "startTime": "2023-01-13T18:00:00Z",
                "endTime": "2023-01-13T19:00:00Z"
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 100.0
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789116,
              "longitude": -122.395080
            },
            "duration": "250s",
            "timeWindows": [
              {
                "startTime": "2023-01-13T21:00:00Z",
                "endTime": "2023-01-13T21:30:00Z"
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 20.0
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.795242,
              "longitude": -122.399347
            },
            "duration": "250s",
            "timeWindows": [
              {
                "startTime": "2023-01-13T17:30:00Z",
                "endTime": "2023-01-13T18:00:00Z"
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 50.0
      }
    ],
    "vehicles": [
      {
        "endLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "startLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "costPerHour": 40.0,
        "costPerKilometer": 10.0
      }
    ]
  }
}
    

הצגת תגובה לבקשה השנייה לדוגמה עם חלונות זמן, שבהם מדלגים על משלוח

{
  "routes": [
    {
      "vehicleStartTime": "2023-01-13T17:37:49Z",
      "vehicleEndTime": "2023-01-13T18:09:49Z",
      "visits": [
        {
          "isPickup": true,
          "startTime": "2023-01-13T17:37:49Z",
          "detour": "0s"
        },
        {
          "shipmentIndex": 2,
          "isPickup": true,
          "startTime": "2023-01-13T17:40:19Z",
          "detour": "150s"
        },
        {
          "shipmentIndex": 2,
          "startTime": "2023-01-13T17:49:38Z",
          "detour": "0s"
        },
        {
          "startTime": "2023-01-13T18:00:00Z",
          "detour": "946s"
        }
      ],
      "transitions": [
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T17:37:49Z"
        },
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T17:40:19Z"
        },
        {
          "travelDuration": "409s",
          "travelDistanceMeters": 1371,
          "waitDuration": "0s",
          "totalDuration": "409s",
          "startTime": "2023-01-13T17:42:49Z"
        },
        {
          "travelDuration": "372s",
          "travelDistanceMeters": 1348,
          "waitDuration": "0s",
          "totalDuration": "372s",
          "startTime": "2023-01-13T17:53:48Z"
        },
        {
          "travelDuration": "339s",
          "travelDistanceMeters": 1276,
          "waitDuration": "0s",
          "totalDuration": "339s",
          "startTime": "2023-01-13T18:04:10Z"
        }
      ],
      "metrics": {
        "performedShipmentCount": 2,
        "travelDuration": "1120s",
        "waitDuration": "0s",
        "delayDuration": "0s",
        "breakDuration": "0s",
        "visitDuration": "800s",
        "totalDuration": "1920s",
        "travelDistanceMeters": 3995
      },
      "routeCosts": {
        "model.vehicles.cost_per_kilometer": 39.95,
        "model.vehicles.cost_per_hour": 21.333333333333332
      },
      "routeTotalCost": 61.283333333333331
    }
  ],
  "skippedShipments": [
    {
      "index": 1
    }
  ],
  "metrics": {
    "aggregatedRouteMetrics": {
      "performedShipmentCount": 2,
      "travelDuration": "1120s",
      "waitDuration": "0s",
      "delayDuration": "0s",
      "breakDuration": "0s",
      "visitDuration": "800s",
      "totalDuration": "1920s",
      "travelDistanceMeters": 3995
    },
    "usedVehicleCount": 1,
    "earliestVehicleStartTime": "2023-01-13T17:37:49Z",
    "latestVehicleEndTime": "2023-01-13T18:09:49Z",
    "totalCost": 81.283333333333331,
    "costs": {
      "model.shipments.penalty_cost": 20,
      "model.vehicles.cost_per_hour": 21.333333333333332,
      "model.vehicles.cost_per_kilometer": 39.95
    }
  }
}
    

בדוגמה הזו, חלון הזמן המאוחר יותר גרם לדילוג על shipment[1], כי זמן התפעול הנוסף של הרכב שנדרש להשלמת המסירה של המשלוח במסגרת חלון הזמן שצוין חרג מעלויות המשלוח בהתאם לעלויות. עלות הקנס על shipment[1] מופיעה ב-metrics.costs, והאינדקס שלה מופיע ב-skippedShipments.

מגבלות של חלון זמן רך

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

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

ריכוך חלונות הזמן באמצעות softStartTime או softEndTime במקום startTime או endTime בהתאמה, ובאמצעות ההגדרה של costPerHourBeforeSoftStartTime או costPerHourAfterSoftEndTime.

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

  • חלון זמן קשה: מציין את שעות הפעילות של הלקוח, למשל 9:00 עד 17:00.
  • חלון זמן רך: מציין את מסגרת הזמן למשלוח או לאיסוף שתואמת להודעה שנשלחה ללקוח, למשל 9:00 עד 13:00.

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

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

{
  "populatePolylines": false,
  "populateTransitionPolylines": false,
  "model": {
    "globalStartTime": "2023-01-13T16:00:00Z",
    "globalEndTime": "2023-01-14T16:00:00Z",
    "shipments": [
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789456,
              "longitude": -122.390192
            },
            "duration": "250s",
            "timeWindows": [
              {
                "startTime": "2023-01-13T18:00:00Z",
                "softEndTime": "2023-01-13T19:00:00Z",
                "costPerHourAfterSoftEndTime": 2.0
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 100.0
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789116,
              "longitude": -122.395080
            },
            "duration": "250s",
            "timeWindows": [
              {
                "softStartTime": "2023-01-13T21:00:00Z",
                "endTime": "2023-01-13T21:30:00Z",
                "costPerHourBeforeSoftStartTime": 2.0
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 20.0
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.795242,
              "longitude": -122.399347
            },
            "duration": "250s",
            "timeWindows": [
              {
                "startTime": "2023-01-13T17:30:00Z",
                "softEndTime": "2023-01-13T18:00:00Z",
                "costPerHourAfterSoftEndTime": 2.0
              }
            ]
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 50.0
      }
    ],
    "vehicles": [
      {
        "endLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "startLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "costPerHour": 40.0,
        "costPerKilometer": 10.0
      }
    ]
  }
}
    

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

{
  "routes": [
    {
      "vehicleStartTime": "2023-01-13T17:48:35Z",
      "vehicleEndTime": "2023-01-13T18:24:28Z",
      "visits": [
        {
          "isPickup": true,
          "startTime": "2023-01-13T17:48:35Z",
          "detour": "0s"
        },
        {
          "shipmentIndex": 1,
          "isPickup": true,
          "startTime": "2023-01-13T17:51:05Z",
          "detour": "150s"
        },
        {
          "shipmentIndex": 2,
          "isPickup": true,
          "startTime": "2023-01-13T17:53:35Z",
          "detour": "300s"
        },
        {
          "startTime": "2023-01-13T18:00:00Z",
          "detour": "300s"
        },
        {
          "shipmentIndex": 1,
          "startTime": "2023-01-13T18:07:42Z",
          "detour": "493s"
        },
        {
          "shipmentIndex": 2,
          "startTime": "2023-01-13T18:17:27Z",
          "detour": "873s"
        }
      ],
      "transitions": [
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T17:48:35Z"
        },
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T17:51:05Z"
        },
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T17:53:35Z"
        },
        {
          "travelDuration": "235s",
          "travelDistanceMeters": 795,
          "waitDuration": "0s",
          "totalDuration": "235s",
          "startTime": "2023-01-13T17:56:05Z"
        },
        {
          "travelDuration": "212s",
          "travelDistanceMeters": 791,
          "waitDuration": "0s",
          "totalDuration": "212s",
          "startTime": "2023-01-13T18:04:10Z"
        },
        {
          "travelDuration": "335s",
          "travelDistanceMeters": 1204,
          "waitDuration": "0s",
          "totalDuration": "335s",
          "startTime": "2023-01-13T18:11:52Z"
        },
        {
          "travelDuration": "171s",
          "travelDistanceMeters": 665,
          "waitDuration": "0s",
          "totalDuration": "171s",
          "startTime": "2023-01-13T18:21:37Z"
        }
      ],
      "metrics": {
        "performedShipmentCount": 3,
        "travelDuration": "953s",
        "waitDuration": "0s",
        "delayDuration": "0s",
        "breakDuration": "0s",
        "visitDuration": "1200s",
        "totalDuration": "2153s",
        "travelDistanceMeters": 3455
      },
      "routeCosts": {
        "model.shipments.deliveries.time_windows.cost_per_hour_after_soft_end_time": 0.58166666666666667,
        "model.shipments.deliveries.time_windows.cost_per_hour_before_soft_start_time": 5.7433333333333332,
        "model.vehicles.cost_per_hour": 23.922222222222221,
        "model.vehicles.cost_per_kilometer": 34.55
      },
      "routeTotalCost": 64.797222222222217
    }
  ],
  "metrics": {
    "aggregatedRouteMetrics": {
      "performedShipmentCount": 3,
      "travelDuration": "953s",
      "waitDuration": "0s",
      "delayDuration": "0s",
      "breakDuration": "0s",
      "visitDuration": "1200s",
      "totalDuration": "2153s",
      "travelDistanceMeters": 3455
    },
    "usedVehicleCount": 1,
    "earliestVehicleStartTime": "2023-01-13T17:48:35Z",
    "latestVehicleEndTime": "2023-01-13T18:24:28Z",
    "totalCost": 64.797222222222217,
    "costs": {
      "model.vehicles.cost_per_kilometer": 34.55,
      "model.shipments.deliveries.time_windows.cost_per_hour_before_soft_start_time": 5.7433333333333332,
      "model.shipments.deliveries.time_windows.cost_per_hour_after_soft_end_time": 0.58166666666666667,
      "model.vehicles.cost_per_hour": 23.922222222222221
    }
  }
}
    

כאשר דילגתם לגמרי על הדוגמה עם מגבלות של חלון זמן קשה בלבד shipment[1], ריכוך חלון הזמן לאספקה יגרום לכך שהוא יישלח לפני שעת ההתחלה של חלון הזמן. באופן דומה, ריכוך זמני הסיום של משלוחים אחרים אפשר ל-shipment[2] להימסר אחרי סיום חלון הזמן.

במקביל, השתנו העלויות וסך כל המשלוחים:

  • totalCost: הופחת מ-81.283 ל-64.797
  • סה"כ משלוחים שהושלמו: גדל מ-2 ל-3

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

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

  • costPerHourBeforeSoftStartTime מתוך 2.0 ו-
  • משך הזמן בין המסירה בפועל לבין תחילת חלון הזמן: 2.83583 שעות

תוצאה:

model.shipments.deliveries.time_windows.cost_per_hour_before_soft_start_time: 5.6716666666666669.

המדדים האלה מאפשרים לנתח עלויות כדי לראות את האיזון בין אילוצים רכים ומגבלות נוקשות, ולהשתמש בהן כדי לחדד את האילוצים כך שיתאימו יותר לכללים העסקיים הספציפיים שלכם. במקרה כזה, העלות הכוללת נמוכה מ-shipment[1].penalty_cost מתוך 20.0. הכלי לאופטימיזציה זיהה שמשלוח מוקדם יותר משתלם יותר מאשר דילוג על המשלוח.