Vicinity clustering with job continuation

This examples demonstrates a continue type of visit: jobs are visited one by one with returning to the stop point in the end.

Problem

{
  "plan": {
    "jobs": [
      {
        "id": "job1",
        "deliveries": [
          {
            "places": [
              {
                "location": {
                  "lat": 52.5253538,
                  "lng": 13.4525549
                },
                "duration": 300
              }
            ],
            "demand": [
              1
            ]
          }
        ]
      },
      {
        "id": "job2",
        "deliveries": [
          {
            "places": [
              {
                "location": {
                  "lat": 52.5254256,
                  "lng": 13.4527159
                },
                "duration": 300
              }
            ],
            "demand": [
              1
            ]
          }
        ]
      },
      {
        "id": "job3",
        "deliveries": [
          {
            "places": [
              {
                "location": {
                  "lat": 52.5255366,
                  "lng": 13.4530162
                },
                "duration": 300
              }
            ],
            "demand": [
              1
            ]
          }
        ]
      },
      {
        "id": "job4",
        "deliveries": [
          {
            "places": [
              {
                "location": {
                  "lat": 52.5253342,
                  "lng": 13.4533489
                },
                "duration": 300
              }
            ],
            "demand": [
              1
            ]
          }
        ]
      },
      {
        "id": "job5",
        "deliveries": [
          {
            "places": [
              {
                "location": {
                  "lat": 52.5239243,
                  "lng": 13.4545827
                },
                "duration": 300
              }
            ],
            "demand": [
              1
            ]
          }
        ]
      },
      {
        "id": "job6",
        "deliveries": [
          {
            "places": [
              {
                "location": {
                  "lat": 52.5223315,
                  "lng": 13.4555697
                },
                "duration": 300
              }
            ],
            "demand": [
              1
            ]
          }
        ]
      },
      {
        "id": "job7",
        "deliveries": [
          {
            "places": [
              {
                "location": {
                  "lat": 52.5240157,
                  "lng": 13.4572220
                },
                "duration": 300
              }
            ],
            "demand": [
              1
            ]
          }
        ]
      },
      {
        "id": "job8",
        "deliveries": [
          {
            "places": [
              {
                "location": {
                  "lat": 52.5243028,
                  "lng": 13.45952868
                },
                "duration": 300
              }
            ],
            "demand": [
              1
            ]
          }
        ]
      },
      {
        "id": "job9",
        "deliveries": [
          {
            "places": [
              {
                "location": {
                  "lat": 52.5241593,
                  "lng": 13.4589815
                },
                "duration": 300
              }
            ],
            "demand": [
              1
            ]
          }
        ]
      },
      {
        "id": "job10",
        "deliveries": [
          {
            "places": [
              {
                "location": {
                  "lat": 52.5239896,
                  "lng": 13.4600115
                },
                "duration": 300
              }
            ],
            "demand": [
              1
            ]
          }
        ]
      },
      {
        "id": "job11",
        "deliveries": [
          {
            "places": [
              {
                "location": {
                  "lat": 52.5250209,
                  "lng": 13.4567821
                },
                "duration": 300
              }
            ],
            "demand": [
              1
            ]
          }
        ]
      },
      {
        "id": "job12",
        "deliveries": [
          {
            "places": [
              {
                "location": {
                  "lat": 52.5223184,
                  "lng": 13.4551942
                },
                "duration": 300
              }
            ],
            "demand": [
              1
            ]
          }
        ]
      }
    ],
    "clustering": {
      "type": "vicinity",
      "profile": {
        "matrix": "car",
        "scale": 10
      },
      "threshold": {
        "duration": 120,
        "distance": 100
      },
      "visiting": "continue",
      "serving": {
        "type": "fixed",
        "value": 180,
        "parking": 120
      }
    }
  },
  "fleet": {
    "vehicles": [
      {
        "typeId": "vehicle",
        "vehicleIds": [
          "vehicle_1"
        ],
        "profile": {
          "matrix": "car"
        },
        "costs": {
          "fixed": 25,
          "distance": 0.0001,
          "time": 0.005
        },
        "shifts": [
          {
            "start": {
              "earliest": "2020-05-01T09:00:00.00Z",
              "location": {
                "lat": 52.5262872,
                "lng": 13.4532952
              }
            }
          }
        ],
        "capacity": [
          20
        ]
      }
    ],
    "profiles": [
      {
        "name": "car",
        "type": "car"
      }
    ]
  }
}

Solution

{
  "statistic": {
    "cost": 41.648399999999995,
    "distance": 984,
    "duration": 3310,
    "times": {
      "driving": 100,
      "serving": 2520,
      "waiting": 0,
      "break": 0,
      "commuting": 330,
      "parking": 360
    }
  },
  "tours": [
    {
      "vehicleId": "vehicle_1",
      "typeId": "vehicle",
      "shiftIndex": 0,
      "stops": [
        {
          "location": {
            "lat": 52.5262872,
            "lng": 13.4532952
          },
          "time": {
            "arrival": "2020-05-01T09:00:00Z",
            "departure": "2020-05-01T09:00:00Z"
          },
          "distance": 0,
          "load": [
            12
          ],
          "activities": [
            {
              "jobId": "departure",
              "type": "departure"
            }
          ]
        },
        {
          "location": {
            "lat": 52.5253342,
            "lng": 13.4533489
          },
          "time": {
            "arrival": "2020-05-01T09:00:11Z",
            "departure": "2020-05-01T09:16:01Z"
          },
          "distance": 106,
          "load": [
            8
          ],
          "parking": {
            "start": "2020-05-01T09:00:11Z",
            "end": "2020-05-01T09:02:11Z"
          },
          "activities": [
            {
              "jobId": "job4",
              "type": "delivery",
              "location": {
                "lat": 52.5253342,
                "lng": 13.4533489
              },
              "time": {
                "start": "2020-05-01T09:02:11Z",
                "end": "2020-05-01T09:05:11Z"
              },
              "commute": {}
            },
            {
              "jobId": "job3",
              "type": "delivery",
              "location": {
                "lat": 52.5255366,
                "lng": 13.4530162
              },
              "time": {
                "start": "2020-05-01T09:05:41Z",
                "end": "2020-05-01T09:08:41Z"
              },
              "commute": {
                "forward": {
                  "location": {
                    "lat": 52.5253342,
                    "lng": 13.4533489
                  },
                  "distance": 32.0,
                  "time": {
                    "start": "2020-05-01T09:05:11Z",
                    "end": "2020-05-01T09:05:41Z"
                  }
                }
              }
            },
            {
              "jobId": "job2",
              "type": "delivery",
              "location": {
                "lat": 52.5254256,
                "lng": 13.4527159
              },
              "time": {
                "start": "2020-05-01T09:09:01Z",
                "end": "2020-05-01T09:12:01Z"
              },
              "commute": {
                "forward": {
                  "location": {
                    "lat": 52.5255366,
                    "lng": 13.4530162
                  },
                  "distance": 24.0,
                  "time": {
                    "start": "2020-05-01T09:08:41Z",
                    "end": "2020-05-01T09:09:01Z"
                  }
                }
              }
            },
            {
              "jobId": "job1",
              "type": "delivery",
              "location": {
                "lat": 52.5253538,
                "lng": 13.4525549
              },
              "time": {
                "start": "2020-05-01T09:12:11Z",
                "end": "2020-05-01T09:15:11Z"
              },
              "commute": {
                "forward": {
                  "location": {
                    "lat": 52.5254256,
                    "lng": 13.4527159
                  },
                  "distance": 14.0,
                  "time": {
                    "start": "2020-05-01T09:12:01Z",
                    "end": "2020-05-01T09:12:11Z"
                  }
                },
                "backward": {
                  "location": {
                    "lat": 52.5253342,
                    "lng": 13.4533489
                  },
                  "distance": 54.0,
                  "time": {
                    "start": "2020-05-01T09:15:11Z",
                    "end": "2020-05-01T09:16:01Z"
                  }
                }
              }
            }
          ]
        },
        {
          "location": {
            "lat": 52.5239243,
            "lng": 13.4545827
          },
          "time": {
            "arrival": "2020-05-01T09:16:19Z",
            "departure": "2020-05-01T09:21:19Z"
          },
          "distance": 284,
          "load": [
            7
          ],
          "activities": [
            {
              "jobId": "job5",
              "type": "delivery"
            }
          ]
        },
        {
          "location": {
            "lat": 52.5223315,
            "lng": 13.4555697
          },
          "time": {
            "arrival": "2020-05-01T09:21:38Z",
            "departure": "2020-05-01T09:30:38Z"
          },
          "distance": 473,
          "load": [
            5
          ],
          "parking": {
            "start": "2020-05-01T09:21:38Z",
            "end": "2020-05-01T09:23:38Z"
          },
          "activities": [
            {
              "jobId": "job6",
              "type": "delivery",
              "location": {
                "lat": 52.5223315,
                "lng": 13.4555697
              },
              "time": {
                "start": "2020-05-01T09:23:38Z",
                "end": "2020-05-01T09:26:38Z"
              },
              "commute": {}
            },
            {
              "jobId": "job12",
              "type": "delivery",
              "location": {
                "lat": 52.5223184,
                "lng": 13.4551942
              },
              "time": {
                "start": "2020-05-01T09:27:08Z",
                "end": "2020-05-01T09:30:08Z"
              },
              "commute": {
                "forward": {
                  "location": {
                    "lat": 52.5223315,
                    "lng": 13.4555697
                  },
                  "distance": 25.0,
                  "time": {
                    "start": "2020-05-01T09:26:38Z",
                    "end": "2020-05-01T09:27:08Z"
                  }
                },
                "backward": {
                  "location": {
                    "lat": 52.5223315,
                    "lng": 13.4555697
                  },
                  "distance": 25.0,
                  "time": {
                    "start": "2020-05-01T09:30:08Z",
                    "end": "2020-05-01T09:30:38Z"
                  }
                }
              }
            }
          ]
        },
        {
          "location": {
            "lat": 52.5240157,
            "lng": 13.457222
          },
          "time": {
            "arrival": "2020-05-01T09:31:00Z",
            "departure": "2020-05-01T09:36:00Z"
          },
          "distance": 691,
          "load": [
            4
          ],
          "activities": [
            {
              "jobId": "job7",
              "type": "delivery"
            }
          ]
        },
        {
          "location": {
            "lat": 52.5250209,
            "lng": 13.4567821
          },
          "time": {
            "arrival": "2020-05-01T09:36:12Z",
            "departure": "2020-05-01T09:41:12Z"
          },
          "distance": 807,
          "load": [
            3
          ],
          "activities": [
            {
              "jobId": "job11",
              "type": "delivery"
            }
          ]
        },
        {
          "location": {
            "lat": 52.5241593,
            "lng": 13.4589815
          },
          "time": {
            "arrival": "2020-05-01T09:41:30Z",
            "departure": "2020-05-01T09:55:10Z"
          },
          "distance": 984,
          "load": [
            0
          ],
          "parking": {
            "start": "2020-05-01T09:41:30Z",
            "end": "2020-05-01T09:43:30Z"
          },
          "activities": [
            {
              "jobId": "job9",
              "type": "delivery",
              "location": {
                "lat": 52.5241593,
                "lng": 13.4589815
              },
              "time": {
                "start": "2020-05-01T09:43:30Z",
                "end": "2020-05-01T09:46:30Z"
              },
              "commute": {}
            },
            {
              "jobId": "job8",
              "type": "delivery",
              "location": {
                "lat": 52.5243028,
                "lng": 13.45952868
              },
              "time": {
                "start": "2020-05-01T09:47:10Z",
                "end": "2020-05-01T09:50:10Z"
              },
              "commute": {
                "forward": {
                  "location": {
                    "lat": 52.5241593,
                    "lng": 13.4589815
                  },
                  "distance": 40.0,
                  "time": {
                    "start": "2020-05-01T09:46:30Z",
                    "end": "2020-05-01T09:47:10Z"
                  }
                }
              }
            },
            {
              "jobId": "job10",
              "type": "delivery",
              "location": {
                "lat": 52.5239896,
                "lng": 13.4600115
              },
              "time": {
                "start": "2020-05-01T09:51:00Z",
                "end": "2020-05-01T09:54:00Z"
              },
              "commute": {
                "forward": {
                  "location": {
                    "lat": 52.5243028,
                    "lng": 13.45952868
                  },
                  "distance": 48.0,
                  "time": {
                    "start": "2020-05-01T09:50:10Z",
                    "end": "2020-05-01T09:51:00Z"
                  }
                },
                "backward": {
                  "location": {
                    "lat": 52.5241593,
                    "lng": 13.4589815
                  },
                  "distance": 72.0,
                  "time": {
                    "start": "2020-05-01T09:54:00Z",
                    "end": "2020-05-01T09:55:10Z"
                  }
                }
              }
            }
          ]
        }
      ],
      "statistic": {
        "cost": 41.648399999999995,
        "distance": 984,
        "duration": 3310,
        "times": {
          "driving": 100,
          "serving": 2520,
          "waiting": 0,
          "break": 0,
          "commuting": 330,
          "parking": 360
        }
      }
    }
  ]
}


As parking time is specified in clustering settings, each stop with clustered job has an extra parking property:

          "parking": {
            "start": "2020-05-01T09:00:11Z",
            "end": "2020-05-01T09:02:11Z"
          },

Here, two minutes are planned for parking car at the stop location.

Activities in such stops have commute property which contains information about time, location, distance of commute trip. The property is split into forward and backward parts:

            {
              "jobId": "job1",
              "type": "delivery",
              "location": {
                "lat": 52.5253538,
                "lng": 13.4525549
              },
              "time": {
                "start": "2020-05-01T09:12:11Z",
                "end": "2020-05-01T09:15:11Z"
              },
              "commute": {
                "forward": {
                  "location": {
                    "lat": 52.5254256,
                    "lng": 13.4527159
                  },
                  "distance": 14.0,
                  "time": {
                    "start": "2020-05-01T09:12:01Z",
                    "end": "2020-05-01T09:12:11Z"
                  }
                },
                "backward": {
                  "location": {
                    "lat": 52.5253342,
                    "lng": 13.4533489
                  },
                  "distance": 54.0,
                  "time": {
                    "start": "2020-05-01T09:15:11Z",
                    "end": "2020-05-01T09:16:01Z"
                  }
                }
              }

Here forward specifies information how to reach activity and backward - how to get back to the stop after the job is served. Original time on activity specifies actual service time.