Very poor VRP route generated with shipments when duration specified for both pickup & delivery

We’re having trouble with poor routes being generated when using duration on both the pickup and delivery side of a shipment.

Our routes need both pickups from customers to return to the depot, and deliveries from the depot to customers. All shipments involve the depot and another address (they’re never from customer to customer, for example).

We’ve recently been switching from using “services” to “shipments” to take advantage of How to model multiple delivery routes with a single vehicle? - GraphHopper Directions API

We’re having a problem; when specifying a duration for the “depot side” of a shipment, this causes the route generated to be almost twice as long! And we cannot see why or any good reason for this, but it might be that we’re doing something wrong, and any help would be greatly appreciated.

I have some example requests below to demonstrate this:

  • Request 1 - this includes 180 second duration at the depot addresses, and is what we “want”.
  • Request 2 - this is identical, but whenever at the depot (location id “2889”), the duration of 180 has been removed.

When testing this out:

  1. Request 1 has a distance of 100,276m and transport time of 10,056 second
  2. Request 2 has a distance of 58,133m and transport time of 6,967 second

There are only 9 deliveries, so the 9 x 3 minutes should only be adding 27 mins to the total duration, and nothing to the distance or transport time.

As you can see, the extra duration at the depot has caused the time and distance to be considerably worse, but there is plenty of capacity on the vehicle and no other obvious restrictions that should be causing this. I can’t see a good reason why all the shipments picked up from the depot couldn’t have been loaded in the first place and then delivered in one run. As you can see, if you plot this on a map, the drive is clearly not efficient as all the drops are close to each other but a long way from the depot.

Any help would be greatly appreciated. Thank you and I’m sorry if I’ve done something stupid here.

Request 1 (including durations)

Expand to see the request
{
  "vehicles": [
    {
      "vehicle_id": "2296",
      "type_id": "vehicle_2296",
      "start_address": {
        "location_id": "88",
        "lon": -0.4005509,
        "lat": 50.8184527
      },
      "end_address": {
        "location_id": "181",
        "lon": -0.3973049,
        "lat": 50.8193062
      },
      "return_to_depot": true,
      "earliest_start": 1687510800,
      "latest_end": 1687568400,
      "break": {
        "earliest": 1687516200,
        "latest": 1687521600,
        "duration": 1800
      }
    }
  ],
  "vehicle_types": [
    {
      "type_id": "vehicle_2296",
      "profile": "small_truck",
      "capacity": [
        760
      ]
    }
  ],
  "services": [],
  "shipments": [
    {
      "id": "3075744",
      "name": "DeliveryCollection pk 3075744",
      "pickup": {
        "address": {
          "location_id": "50.8277761\/-0.1712243",
          "lon": -0.1712243,
          "lat": 50.8277761
        },
        "duration": 600
      },
      "delivery": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        },
        "duration": 180
      },
      "priority": 5,
      "size": [
        10
      ]
    },
    {
      "id": "3130563",
      "name": "DeliveryCollection pk 3130563",
      "delivery": {
        "address": {
          "location_id": "50.8240857\/-0.1281374",
          "lon": -0.1281374,
          "lat": 50.8240857
        },
        "duration": 360
      },
      "pickup": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        },
        "duration": 180
      },
      "priority": 5,
      "size": [
        11
      ],
      "allowed_vehicles": [
        "2296"
      ]
    },
    {
      "id": "3142860",
      "name": "DeliveryCollection pk 3142860",
      "delivery": {
        "address": {
          "location_id": "50.82889\/-0.1356492",
          "lon": -0.1356492,
          "lat": 50.82889
        },
        "duration": 600
      },
      "pickup": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        },
        "duration": 180
      },
      "priority": 5,
      "size": [
        33
      ],
      "allowed_vehicles": [
        "2296"
      ]
    },
    {
      "id": "3150324",
      "name": "DeliveryCollection pk 3150324",
      "delivery": {
        "address": {
          "location_id": "50.8256444\/-0.1499807",
          "lon": -0.1499807,
          "lat": 50.8256444
        },
        "duration": 600,
        "time_windows": [
          {
            "earliest": 1687514400,
            "latest": 1687536000
          }
        ]
      },
      "pickup": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        },
        "duration": 180
      },
      "priority": 5,
      "size": [
        50
      ],
      "allowed_vehicles": [
        "2296"
      ]
    },
    {
      "id": "3151425",
      "name": "DeliveryCollection pk 3151425",
      "delivery": {
        "address": {
          "location_id": "50.820165\/-0.130451",
          "lon": -0.130451,
          "lat": 50.820165
        },
        "duration": 600,
        "time_windows": [
          {
            "earliest": 1687510800,
            "latest": 1687543200
          }
        ]
      },
      "pickup": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        },
        "duration": 180
      },
      "priority": 5,
      "size": [
        40
      ],
      "allowed_vehicles": [
        "2296"
      ]
    },
    {
      "id": "3153789",
      "name": "DeliveryCollection pk 3153789",
      "delivery": {
        "address": {
          "location_id": "50.8199791\/-0.1309871",
          "lon": -0.1309871,
          "lat": 50.8199791
        },
        "duration": 600,
        "time_windows": [
          {
            "earliest": 1687521600,
            "latest": 1687536000
          }
        ]
      },
      "pickup": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        },
        "duration": 180
      },
      "priority": 5,
      "size": [
        102
      ],
      "allowed_vehicles": [
        "2296"
      ]
    },
    {
      "id": "3155331",
      "name": "DeliveryCollection pk 3155331",
      "delivery": {
        "address": {
          "location_id": "50.8199982\/-0.1422625",
          "lon": -0.1422625,
          "lat": 50.8199982
        },
        "duration": 900,
        "time_windows": [
          {
            "earliest": 1687503600,
            "latest": 1687513500
          }
        ]
      },
      "pickup": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        },
        "duration": 180
      },
      "priority": 5,
      "size": [
        240
      ],
      "allowed_vehicles": [
        "2296"
      ]
    },
    {
      "id": "3156303",
      "name": "DeliveryCollection pk 3156303",
      "delivery": {
        "address": {
          "location_id": "50.8209135\/-0.1296251",
          "lon": -0.1296251,
          "lat": 50.8209135
        },
        "duration": 360
      },
      "pickup": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        },
        "duration": 180
      },
      "priority": 5,
      "size": [
        3
      ],
      "allowed_vehicles": [
        "2296"
      ]
    },
    {
      "id": "3156489",
      "name": "DeliveryCollection pk 3156489",
      "delivery": {
        "address": {
          "location_id": "50.8379108\/-0.1333302",
          "lon": -0.1333302,
          "lat": 50.8379108
        },
        "duration": 600,
        "time_windows": [
          {
            "earliest": 1687516200,
            "latest": 1687536000
          }
        ]
      },
      "pickup": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        },
        "duration": 180
      },
      "priority": 5,
      "size": [
        63
      ],
      "allowed_vehicles": [
        "2296"
      ]
    }
  ],
  "objectives": [
    {
      "type": "min-max",
      "value": "completion_time"
    },
    {
      "type": "min-max",
      "value": "activities"
    }
  ],
  "configuration": {
    "routing": {
      "calc_points": true,
      "snap_preventions": [
        "motorway",
        "trunk",
        "tunnel",
        "bridge",
        "ferry"
      ],
      "consider_traffic": true,
      "network_data_provider": "tomtom"
    }
  },
  "relations": []
}

Request 2 (depot durations removed)

Expand to see the request
{
  "vehicles": [
    {
      "vehicle_id": "2296",
      "type_id": "vehicle_2296",
      "start_address": {
        "location_id": "88",
        "lon": -0.4005509,
        "lat": 50.8184527
      },
      "end_address": {
        "location_id": "181",
        "lon": -0.3973049,
        "lat": 50.8193062
      },
      "return_to_depot": true,
      "earliest_start": 1687510800,
      "latest_end": 1687568400,
      "break": {
        "earliest": 1687516200,
        "latest": 1687521600,
        "duration": 1800
      }
    }
  ],
  "vehicle_types": [
    {
      "type_id": "vehicle_2296",
      "profile": "small_truck",
      "capacity": [
        760
      ]
    }
  ],
  "services": [],
  "shipments": [
    {
      "id": "3075744",
      "name": "DeliveryCollection pk 3075744",
      "pickup": {
        "address": {
          "location_id": "50.8277761\/-0.1712243",
          "lon": -0.1712243,
          "lat": 50.8277761
        },
        "duration": 600
      },
      "delivery": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        }
      },
      "priority": 5,
      "size": [
        10
      ]
    },
    {
      "id": "3130563",
      "name": "DeliveryCollection pk 3130563",
      "delivery": {
        "address": {
          "location_id": "50.8240857\/-0.1281374",
          "lon": -0.1281374,
          "lat": 50.8240857
        },
        "duration": 360
      },
      "pickup": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        }
      },
      "priority": 5,
      "size": [
        11
      ],
      "allowed_vehicles": [
        "2296"
      ]
    },
    {
      "id": "3142860",
      "name": "DeliveryCollection pk 3142860",
      "delivery": {
        "address": {
          "location_id": "50.82889\/-0.1356492",
          "lon": -0.1356492,
          "lat": 50.82889
        },
        "duration": 600
      },
      "pickup": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        }
      },
      "priority": 5,
      "size": [
        33
      ],
      "allowed_vehicles": [
        "2296"
      ]
    },
    {
      "id": "3150324",
      "name": "DeliveryCollection pk 3150324",
      "delivery": {
        "address": {
          "location_id": "50.8256444\/-0.1499807",
          "lon": -0.1499807,
          "lat": 50.8256444
        },
        "duration": 600,
        "time_windows": [
          {
            "earliest": 1687514400,
            "latest": 1687536000
          }
        ]
      },
      "pickup": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        }
      },
      "priority": 5,
      "size": [
        50
      ],
      "allowed_vehicles": [
        "2296"
      ]
    },
    {
      "id": "3151425",
      "name": "DeliveryCollection pk 3151425",
      "delivery": {
        "address": {
          "location_id": "50.820165\/-0.130451",
          "lon": -0.130451,
          "lat": 50.820165
        },
        "duration": 600,
        "time_windows": [
          {
            "earliest": 1687510800,
            "latest": 1687543200
          }
        ]
      },
      "pickup": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        }
      },
      "priority": 5,
      "size": [
        40
      ],
      "allowed_vehicles": [
        "2296"
      ]
    },
    {
      "id": "3153789",
      "name": "DeliveryCollection pk 3153789",
      "delivery": {
        "address": {
          "location_id": "50.8199791\/-0.1309871",
          "lon": -0.1309871,
          "lat": 50.8199791
        },
        "duration": 600,
        "time_windows": [
          {
            "earliest": 1687521600,
            "latest": 1687536000
          }
        ]
      },
      "pickup": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        }
      },
      "priority": 5,
      "size": [
        102
      ],
      "allowed_vehicles": [
        "2296"
      ]
    },
    {
      "id": "3155331",
      "name": "DeliveryCollection pk 3155331",
      "delivery": {
        "address": {
          "location_id": "50.8199982\/-0.1422625",
          "lon": -0.1422625,
          "lat": 50.8199982
        },
        "duration": 900,
        "time_windows": [
          {
            "earliest": 1687503600,
            "latest": 1687513500
          }
        ]
      },
      "pickup": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        }
      },
      "priority": 5,
      "size": [
        240
      ],
      "allowed_vehicles": [
        "2296"
      ]
    },
    {
      "id": "3156303",
      "name": "DeliveryCollection pk 3156303",
      "delivery": {
        "address": {
          "location_id": "50.8209135\/-0.1296251",
          "lon": -0.1296251,
          "lat": 50.8209135
        },
        "duration": 360
      },
      "pickup": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        }
      },
      "priority": 5,
      "size": [
        3
      ],
      "allowed_vehicles": [
        "2296"
      ]
    },
    {
      "id": "3156489",
      "name": "DeliveryCollection pk 3156489",
      "delivery": {
        "address": {
          "location_id": "50.8379108\/-0.1333302",
          "lon": -0.1333302,
          "lat": 50.8379108
        },
        "duration": 600,
        "time_windows": [
          {
            "earliest": 1687516200,
            "latest": 1687536000
          }
        ]
      },
      "pickup": {
        "address": {
          "location_id": "2889",
          "lon": -0.4007174,
          "lat": 50.8189081
        }
      },
      "priority": 5,
      "size": [
        63
      ],
      "allowed_vehicles": [
        "2296"
      ]
    }
  ],
  "objectives": [
    {
      "type": "min-max",
      "value": "completion_time"
    },
    {
      "type": "min-max",
      "value": "activities"
    }
  ],
  "configuration": {
    "routing": {
      "calc_points": true,
      "snap_preventions": [
        "motorway",
        "trunk",
        "tunnel",
        "bridge",
        "ferry"
      ],
      "consider_traffic": true,
      "network_data_provider": "tomtom"
    }
  },
  "relations": []
}

Hi, what is the purpose of the additional 180s durations?

I think the problem is that when you add these durations the time windows of your deliveries kick in.

E.g. see the shipment 3155331 which has to be delivered directly after pickup for the first request. But in the second request it first collects many more items (as it has time!) and is able to reduce forth and back between depot leading to the smaller time + distance as I understand it.

You can use our API explorer (append ?key=xy or click on the link inside the dashboard). Then after you send a request to our servers click on the “table” button in the response to investigate the exact pickup + delivery order.

Let me know if this helps or if I misunderstood something.

Thanks @karussell

I’m sorry, you’re completely right. I’m not sure how I missed this before. Thank you for your time on this.

The 180s durations are there to ensure that when the vehicle comes back to the depot to collect more packages, it knows roughly how long it takes to reload before it can leave again (as otherwise, it comes back to the depot for 0s before leaving full of the next round of deliveries).

1 Like