Vehicle break

In general, there are two break types: optional and required.

Optional break

This example demonstrates how to use optional vehicle break with time window and omitted location.

Problem

{
  "plan": {
    "jobs": [
      {
        "id": "job1",
        "deliveries": [
          {
            "places": [
              {
                "location": {
                  "lat": 52.52599,
                  "lng": 13.45413
                },
                "duration": 300.0,
                "times": [
                  [
                    "2019-07-04T09:00:00Z",
                    "2019-07-04T12:00:00Z"
                  ]
                ]
              }
            ],
            "demand": [
              1
            ]
          }
        ]
      },
      {
        "id": "job2",
        "deliveries": [
          {
            "places": [
              {
                "location": {
                  "lat": 52.5225,
                  "lng": 13.4095
                },
                "duration": 240.0,
                "times": [
                  [
                    "2019-07-04T12:00:00Z",
                    "2019-07-04T14:00:00Z"
                  ]
                ]
              }
            ],
            "demand": [
              1
            ]
          }
        ]
      },
      {
        "id": "job3",
        "deliveries": [
          {
            "places": [
              {
                "location": {
                  "lat": 52.5165,
                  "lng": 13.3808
                },
                "duration": 300.0,
                "times": [
                  [
                    "2019-07-04T16:00:00Z",
                    "2019-07-04T18:00:00Z"
                  ]
                ]
              }
            ],
            "demand": [
              1
            ]
          }
        ]
      }
    ]
  },
  "fleet": {
    "vehicles": [
      {
        "typeId": "vehicle",
        "vehicleIds": [
          "vehicle_1"
        ],
        "profile": {
          "matrix": "normal_car"
        },
        "costs": {
          "fixed": 22.0,
          "distance": 0.0002,
          "time": 0.004806
        },
        "shifts": [
          {
            "start": {
              "earliest": "2019-07-04T09:00:00Z",
              "location": {
                "lat": 52.5316,
                "lng": 13.3884
              }
            },
            "end": {
              "latest": "2019-07-04T18:00:00Z",
              "location": {
                "lat": 52.5316,
                "lng": 13.3884
              }
            },
            "breaks": [
              {
                "time": [
                  "2019-07-04T12:00:00Z",
                  "2019-07-04T14:00:00Z"
                ],
                "places": [
                  {
                    "duration": 3600.0
                  }
                ]
              }
            ]
          }
        ],
        "capacity": [
          10
        ]
      }
    ],
    "profiles": [
      {
        "name": "normal_car"
      }
    ]
  }
}

Solution

{
  "statistic": {
    "cost": 101.964322,
    "distance": 13251,
    "duration": 16087,
    "times": {
      "driving": 2367,
      "serving": 840,
      "waiting": 9280,
      "break": 3600
    }
  },
  "tours": [
    {
      "vehicleId": "vehicle_1",
      "typeId": "vehicle",
      "shiftIndex": 0,
      "stops": [
        {
          "location": {
            "lat": 52.5316,
            "lng": 13.3884
          },
          "time": {
            "arrival": "2019-07-04T09:00:00Z",
            "departure": "2019-07-04T11:44:12Z"
          },
          "distance": 0,
          "load": [
            3
          ],
          "activities": [
            {
              "jobId": "departure",
              "type": "departure"
            }
          ]
        },
        {
          "location": {
            "lat": 52.52599,
            "lng": 13.45413
          },
          "time": {
            "arrival": "2019-07-04T12:00:00Z",
            "departure": "2019-07-04T13:05:00Z"
          },
          "distance": 5112,
          "load": [
            2
          ],
          "activities": [
            {
              "jobId": "job1",
              "type": "delivery",
              "location": {
                "lat": 52.52599,
                "lng": 13.45413
              },
              "time": {
                "start": "2019-07-04T12:00:00Z",
                "end": "2019-07-04T12:05:00Z"
              }
            },
            {
              "jobId": "break",
              "type": "break",
              "location": {
                "lat": 52.52599,
                "lng": 13.45413
              },
              "time": {
                "start": "2019-07-04T12:05:00Z",
                "end": "2019-07-04T13:05:00Z"
              }
            }
          ]
        },
        {
          "location": {
            "lat": 52.5225,
            "lng": 13.4095
          },
          "time": {
            "arrival": "2019-07-04T13:15:09Z",
            "departure": "2019-07-04T13:19:09Z"
          },
          "distance": 8952,
          "load": [
            1
          ],
          "activities": [
            {
              "jobId": "job2",
              "type": "delivery"
            }
          ]
        },
        {
          "location": {
            "lat": 52.5165,
            "lng": 13.3808
          },
          "time": {
            "arrival": "2019-07-04T13:25:20Z",
            "departure": "2019-07-04T16:05:00Z"
          },
          "distance": 11106,
          "load": [
            0
          ],
          "activities": [
            {
              "jobId": "job3",
              "type": "delivery"
            }
          ]
        },
        {
          "location": {
            "lat": 52.5316,
            "lng": 13.3884
          },
          "time": {
            "arrival": "2019-07-04T16:12:19Z",
            "departure": "2019-07-04T16:12:19Z"
          },
          "distance": 13251,
          "load": [
            0
          ],
          "activities": [
            {
              "jobId": "arrival",
              "type": "arrival"
            }
          ]
        }
      ],
      "statistic": {
        "cost": 101.964322,
        "distance": 13251,
        "duration": 16087,
        "times": {
          "driving": 2367,
          "serving": 840,
          "waiting": 9280,
          "break": 3600
        }
      }
    }
  ],
  "unassigned": []
}

Required break (experimental)

This example demonstrates how to use required vehicle break which has to be scheduled at specific time during travel between two stops.

Problem

{
  "plan": {
    "jobs": [
      {
        "id": "job1",
        "deliveries": [
          {
            "places": [
              {
                "location": {
                  "lat": 51.06251,
                  "lng": 13.72133
                },
                "duration": 300
              }
            ],
            "demand": [
              1
            ]
          }
        ]
      }
    ]
  },
  "fleet": {
    "vehicles": [
      {
        "typeId": "vehicle",
        "vehicleIds": [
          "vehicle_1"
        ],
        "profile": {
          "matrix": "normal_car"
        },
        "costs": {
          "fixed": 22,
          "distance": 0.0002,
          "time": 0.005
        },
        "shifts": [
          {
            "start": {
              "earliest": "2019-07-04T09:00:00Z",
              "latest": "2019-07-04T09:00:00Z",
              "location": {
                "lat": 52.5316,
                "lng": 13.3884
              }
            },
            "breaks": [
              {
                "time": {
                  "earliest": 7200,
                  "latest": 7200
                },
                "duration": 1800
              }
            ]
          }
        ],
        "capacity": [
          10
        ]
      }
    ],
    "profiles": [
      {
        "name": "normal_car"
      }
    ]
  }
}

Solution

{
  "statistic": {
    "cost": 148.0972,
    "distance": 165136,
    "duration": 18614,
    "times": {
      "driving": 16514,
      "serving": 300,
      "waiting": 0,
      "break": 1800,
      "commuting": 0,
      "parking": 0
    }
  },
  "tours": [
    {
      "vehicleId": "vehicle_1",
      "typeId": "vehicle",
      "shiftIndex": 0,
      "stops": [
        {
          "location": {
            "lat": 52.5316,
            "lng": 13.3884
          },
          "time": {
            "arrival": "2019-07-04T09:00:00Z",
            "departure": "2019-07-04T09:00:00Z"
          },
          "distance": 0,
          "load": [
            1
          ],
          "activities": [
            {
              "jobId": "departure",
              "type": "departure"
            }
          ]
        },
        {
          "time": {
            "arrival": "2019-07-04T11:00:00Z",
            "departure": "2019-07-04T11:30:00Z"
          },
          "load": [
            1
          ],
          "activities": [
            {
              "jobId": "break",
              "type": "break"
            }
          ]
        },
        {
          "location": {
            "lat": 51.06251,
            "lng": 13.72133
          },
          "time": {
            "arrival": "2019-07-04T14:05:14Z",
            "departure": "2019-07-04T14:10:14Z"
          },
          "distance": 165136,
          "load": [
            0
          ],
          "activities": [
            {
              "jobId": "job1",
              "type": "delivery"
            }
          ]
        }
      ],
      "statistic": {
        "cost": 148.0972,
        "distance": 165136,
        "duration": 18614,
        "times": {
          "driving": 16514,
          "serving": 300,
          "waiting": 0,
          "break": 1800,
          "commuting": 0,
          "parking": 0
        }
      }
    }
  ]
}

Please note, that departure rescheduling is disabled by setting shift.start.earliest equal to shift.start.latest. At the moment, this is a hard requirement when such break type is used.