Quickstart

Pickup and Delivery Problem (PDP)

Most real-world routing situations can be covered with the /vrp-long endpoint described earlier. There is one case that requires special attention: Same-day Pickup and Delivery. Each order has a pickup location and a drop-off location that are mutually dependent. An item can only be dropped off after it has been picked up by the same driver.

The /pdp-long endpoint will find the optimal routes to do all your orders, so it may often occur that you pick up multiple orders before you drop them off. If you specify capacity constraints, it will ensure that your vehicles won't try to carry more than they can hold.

To get started, make a POST request with your data to the /pdp-long endpoint:

Create PDP Request

POST https://routing-engine.afi.io/pdp-long

The pdp-long endpoint finds an optimal assignment of visits to vehicles where each visit has a pickup and dropoff location (with the binding constraint that pickups must be served before dropoffs).

Headers

Name
Type
Description

access_toke

string

YOUR_ACCESS_TOKEN

Content-Type

string

application/json

JSON
{
  "job_id": "4e8a0a79-cc8a-4238-9178-ec0fbc1427c1"
}

Here's a sample JSON payload:

JSON
{
	"visits": {
		"order_1": {
			"load": 1,
			"pickup": {
				"location": {
					"name": "3780 Arbutus",
					"lat": 49.2474624,
					"lng": -123.1532338
				},
				"start": "08:00",
				"end": "09:00",
				"duration": 10
			},
			"dropoff": {
				"location": {
					"name": "6800 Cambie",
					"lat": 49.227107,
					"lng": -123.1163085
				},
				"start": "08:00",
				"end": "09:00",
				"duration": 10
			}
		},
		"order_2": {
			"load": 1,
			"pickup": {
				"location": {
					"name": "VanDusen Botanical Garden",
					"lat": 49.2395167,
					"lng": -123.1309948
				},
				"start": "09:00",
				"end": "10:00",
				"duration": 10
			},
			"dropoff": {
				"location": {
					"name": "Vancouver General Hospital",
					"lat": 49.2593508,
					"lng": -123.13265
				},
				"start": "09:00",
				"end": "10:00",
				"duration": 10
			}
		}
	},
	"fleet": {
		"vehicle_1": {
			"start_location": {
				"id": "depot_1a",
				"name": "800 Kingsway",
				"lat": 49.2553636,
				"lng": -123.0873365
			},
			"end_location": {
				"id": "depot_1b",
				"name": "Langara Golf Course",
				"lat": 49.2201308,
				"lng": -123.1085687
			},
			"shift_start": "08:00",
			"shift_end": "09:00",
			"capacity": 1
		},
		"vehicle_2": {
			"start_location": {
				"id": "depot_2a",
				"name": "Kerrisdale",
					"lat": 49.2253335,
					"lng": -123.1653907
			},
			"end_location": {
				"id": "depot_2b",
				"name": "City Square Shopping Centre",
					"lat": 49.261436,
					"lng": -123.1190245
			},
			"shift_start": "09:00",
			"shift_end": "10:00",
			"capacity": 1
		}
	},
  "cache": false,
  "callback_url": "http://34.225.252.0/webhooks/pdp_solution"
}

The /pdp-long endpoint will trigger a long-running background task on our servers, while we give you a URL to ping to fetch the results. When you POST to the above URL, it will return immediately with a 202 HTTP code and a job_id:

JSON
{
  "job_id": "4e8a0a79-cc8a-4238-9178-ec0fbc1427c1"
}

With this job_id you can query the status of the route solution with a GET request to the following endpoint:

Retrieve route solution

GET https://routing-engine.afi.io/jobs/4e8a0a79-cc8a-4238-9178-ec0fbc1427c1

JSON
{
	"id": "4e8a0a79-cc8a-4238-9178-ec0fbc1427c1",
	"status": "finished",
	"input": {
		"visits": {
			"order_1": {
				"load": 1,
				"pickup": {
					"location": {
						"name": "3780 Arbutus",
						"lat": 49.2474624,
						"lng": -123.1532338
					},
					"start": "08:00",
					"end": "09:00",
					"duration": 10
				},
				"dropoff": {
					"location": {
						"name": "6800 Cambie",
						"lat": 49.227107,
						"lng": -123.1163085
					},
					"start": "08:00",
					"end": "09:00",
					"duration": 10
				}
			},
			"order_2": {
				"load": 1,
				"pickup": {
					"location": {
						"name": "VanDusen Botanical Garden",
						"lat": 49.2395167,
						"lng": -123.1309948
					},
					"start": "09:00",
					"end": "10:00",
					"duration": 10
				},
				"dropoff": {
					"location": {
						"name": "Vancouver General Hospital",
						"lat": 49.2593508,
						"lng": -123.13265
					},
					"start": "09:00",
					"end": "10:00",
					"duration": 10
				}
			}
		},
		"fleet": {
			"vehicle_1": {
				"start_location": {
					"id": "depot_1a",
					"name": "800 Kingsway",
					"lat": 49.2553636,
					"lng": -123.0873365
				},
				"end_location": {
					"id": "depot_1b",
					"name": "Langara Golf Course",
					"lat": 49.2201308,
					"lng": -123.1085687
				},
				"shift_start": "08:00",
				"shift_end": "09:00",
				"capacity": 1
			},
			"vehicle_2": {
				"start_location": {
					"id": "depot_2a",
					"name": "Kerrisdale",
					"lat": 49.2253335,
					"lng": -123.1653907
				},
				"end_location": {
					"id": "depot_2b",
					"name": "City Square Shopping Centre",
					"lat": 49.261436,
					"lng": -123.1190245
				},
				"shift_start": "09:00",
				"shift_end": "10:00",
				"capacity": 1
			}
		}
	},
	"output": {
		"status": "completed",
		"fitness": 0,
		"total_travel_time": 13.537803201318958,
		"total_idle_time": 0,
		"total_break_time": 0,
		"num_unserved": 0,
		"unserved": [],
		"solution": {
			"vehicle_1": [{
				"location_id": "depot_1a",
				"location_name": "800 Kingsway",
				"arrival_time": "08:00"
			}, {
				"location_id": "order_1",
				"location_name": "3780 Arbutus",
				"arrival_time": "08:07",
				"finish_time": "08:18",
				"type": "pickup",
				"load": 1,
				"duration": 10
			}, {
				"location_id": "order_1",
				"location_name": "6800 Cambie",
				"arrival_time": "08:23",
				"finish_time": "08:33",
				"type": "dropoff",
				"load": 1,
				"duration": 10
			}, {
				"location_id": "depot_1b",
				"location_name": "Langara Golf Course",
				"arrival_time": "08:33"
			}],
			"vehicle_2": [{
				"location_id": "depot_2a",
				"location_name": "Kerrisdale",
				"arrival_time": "09:00"
			}, {
				"location_id": "order_2",
				"location_name": "VanDusen Botanical Garden",
				"arrival_time": "09:04",
				"finish_time": "09:15",
				"type": "pickup",
				"load": 1,
				"duration": 10
			}, {
				"location_id": "order_2",
				"location_name": "Vancouver General Hospital",
				"arrival_time": "09:18",
				"finish_time": "09:28",
				"type": "dropoff",
				"load": 1,
				"duration": 10
			}, {
				"location_id": "depot_2b",
				"location_name": "City Square Shopping Centre",
				"arrival_time": "09:28"
			}]
		}
	},
	"fleet": 2,
	"visits": 4,
	"started_at": "2019-09-12T08:21:11.901Z",
	"finished_at": "2019-09-12T08:21:12.035Z",
	"type": "PDP",
	"network": {
		"depot_1a": {
			"id": "depot_1a",
			"name": "800 Kingsway",
			"lat": 49.2553636,
			"lng": -123.0873365
		},
		"depot_1b": {
			"id": "depot_1b",
			"name": "Langara Golf Course",
			"lat": 49.2201308,
			"lng": -123.1085687
		},
		"depot_2a": {
			"id": "depot_2a",
			"name": "Kerrisdale",
			"lat": 49.2253335,
			"lng": -123.1653907
		},
		"depot_2b": {
			"id": "depot_2b",
			"name": "City Square Shopping Centre",
			"lat": 49.261436,
			"lng": -123.1190245
		},
		"order_1_pickup": {
			"name": "3780 Arbutus",
			"lat": 49.2474624,
			"lng": -123.1532338
		},
		"order_1_dropoff": {
			"name": "6800 Cambie",
			"lat": 49.227107,
			"lng": -123.1163085
		},
		"order_2_pickup": {
			"name": "VanDusen Botanical Garden",
			"lat": 49.2395167,
			"lng": -123.1309948
		},
		"order_2_dropoff": {
			"name": "Vancouver General Hospital",
			"lat": 49.2593508,
			"lng": -123.13265
		}
	},
	"processing_time": "0.003"
}

When the job is finished, the status is set to finished and the solution to the request is now in output. You can view the input, output, running time and error messages (if any) on the dashboard at https://dashboard.afi.io/requests. The dashboard has a link to an interactive map based interface that you can use to explore your route solution in greater detail.

Last updated