Route Optimization API V2

Introduction

Nextbillion.ai's Route Optimization API is a powerful tool that helps businesses optimize their delivery routes to maximize efficiency, save time, and reduce costs. It is designed to solve both Single and/or Multi Vehicle Routing Problem (VRP), which is a classic optimization problem in operations research that involves finding the optimal set of routes for a fleet of vehicles to visit a set of locations while satisfying various constraints such as time windows, capacity, and vehicle availability.

The Route Optimization API consists of two main components - the input data and the optimization engine. The input data includes information about the jobs (stops/places to visit), vehicles (delivery trucks, vans, etc.), and shipments (pickup and delivery tasks), while the optimization engine uses this data to find the most efficient set of routes for the vehicles to follow.

With the ability to handle complex constraints and variables such as capacity, time windows, and vehicle availability, our API can be customized to meet specific needs of your business.

There are two components to API

  1. Optimization Post - Use this method to submit input for your VRP.

  2. Optimization GET - Retrieve the status of a submitted VRP using a unique reference ID.

What changed in V2?

V2 includes following new features and changes:

  1. The request URL changes to https: //api.nextbillion.io/optimization/v2 instead of https: //api.nextbillion.io/optimise-mvrp.

  2. New solutions and unassigned objects in request for re-optimization cases

  3. locations object changes:

    1. A new parameter approaches is included

    2. The schema of location parameter is updated to an array of location objects in [latitude,longitude] format. It used to be pipe delimited in V1.

  4. options object includes

    1. constraint object for describing soft constraints

    2. objective object to define optimization objective

    3. routing object to define routing considerations relating to truck and traffic

    4. mode parameter, which is moved into the routing object.

  5. Each job can have either a pickup or a delivery, not both.

  6. setup time is not supported for jobs and shipments

  7. vehicle.break allows only a single break for a vehicle

  8. vehicle.start_index is a required parameter

  9. minimise_num_depots objective is no longer supported.

  10. relations object for configuring relationships between jobs and shipments

  11. cost_matrix array to collect the user-defined traveling costs between locations.

Conventions

  1. All keys and parameters should be in lower case only.

  2. All the timestamps are UNIX in seconds and other time-related parameters units are in seconds.

  3. All distance-related parameter units should be in meters.

  4. A time_window object is a pair of timestamps in the form [start, end]

Object Overview

Location Object

Locations object - locations - is used to describe locations that will be used for route optimization. A maximum of 2k locations can be added to this object.

Index Location
0 51.388997,-0.119022
1 51.391915,-0.103666
2 51.369777,-0.10438
3 51.365014,-0.105654
4 51.351818,-0.014773

With respect to the example above, if in the "vehicles" property, the start_index parameter is set to 2, then 51.369777,-0.10438 would be considered as the starting coordinates for that vehicle.

Job Object

jobs object describes a particular job or a task that needs to be completed as part of the overall optimization process. It contains various properties of a job such as the job id, the index of the location where the job needs to be performed, the service duration, multidimensional quantities for pickup and delivery, available time windows, mandatory skills required, the priority of the job, and a description of the job.

Properties of a jobs object provide important information to the optimization algorithm, such as time constraints and resource requirements for each job, which helps generate an optimized route plan. It is important to note here that all delivery-related amounts for jobs are loaded at vehicle start, while all pickup-related amounts for jobs are brought back to the last stop of the vehicle. Therefore, the vehicles should have appropriate capacity to handle job pickup and deliveries accordingly.

Vehicle Object

The Vehicle object describes the characteristics and constraints of a vehicle that will be used in a multi-vehicle routing problem. Some points to consider about vehicles object:

  1. The users can also set a start or an end location of their choice as long as it is present in the locations object. The vehicle’s start and end locations can be different from job locations.

  2. In order to request a round trip, you can specify both the start_index and end_index with the same location index.

  3. capacity parameter describes the maximum multidimensional quantities a vehicle can carry.

Relations Object

relations object is used to configure relationships between jobs and shipments that should be honored in the optimized solution. With this object users can customize the algorithm to emulate real-world constraints like control the sequence of certain jobs/shipments in the solution or ensure certain jobs/shipments are covered on the same route. It allows you to specify various types of relations and their corresponding constraints for the steps. However when using the relations object, please be mindful of the following considerations:

  1. time_windows constraints in jobs and shipments might be violated for the steps mentioned in the relations object.

  2. Soft constraints parameters like max_vehicle_overtime and max_visit_lateness will not be available in input requests when the relations object is used.

  3. If certain relations require multiple steps (e.g., jobs) to be on the same route, the vehicle assigned to that route must have a capacity that can accommodate all the steps. If there are no vehicles satisfying such capacity, the optimization service would return an error.

  4. If a job requires specific skills and relation specifies a vehicle for that job, an error message is returned if the vehicle's skill set does not include the required skill.

  5. If a relations input requires a delivery step to occur before a pickup step for a shipment, an error message is returned, as it violates the shipment's logical order.

  6. For shipments, both the pickup and delivery steps should exist within the same relations. An error message is reported if a relations contains only one shipment step.

Sample Relations Object

1{
2  "relations": [
3    {
4      "type": "in_direct_sequence",
5      "steps": [
6        {
7          "type": "start"
8        },
9        {
10          "type": "pickup",
11          "id": 25
12        },
13        {
14          "type": "job",
15          "id": 3
16        },
17        {
18          "type": "delivery",
19          "id": 25
20        },
21        {
22          "type": "end"
23        }
24      ],
25      "vehicle": 1
26    }
27  ]
28}

Custom Cost Matrix

This feature enables the optimization algorithm to consider a user-defined cost of traveling between different locations. Users can set the travel_cost parameter of objective property to customized to ensure that the algorithm considers the custom cost values for each traveling between locations.

To utilize the "cost_matrix" object, you need to provide a 2D array with 'n' rows and 'n' columns where n represents the total number of locations. Each element of the array represents the cost of traveling from one location to another. The optimization algorithm would prefer the routes with lower relative costs over the routes with higher relative costs. Therefore, the custom cost matrix can be used to influence the optimized route that the algorithm returns. For example, if you have three locations (A, B, C), the cost_matrix would be a 3x3 array:

1`cost_matrix`: [ 	
2				[0, 10, 5], 
3				[10, 0, 8], 
4				[5, 8, 0] 
5			   ]

In this example, the first row represents the cost of traveling from location A to location A,A to B & A to C, the second row represents the cost of traveling to different locations starting from point B to A and so on. Subsequently, for the given example, the cost of traveling from location A to B is 10, from A to C is 5, from B to A is 10, from B to C is 8, and so on.

Few points to consider regarding the use of cost_matrix :

  1. The cost values should always be non-negative integers.

  2. The cost values do not have any unit. Users can consider the cost of traveling from one location to another as abstract but relative weights.

  3. Please ensure to match the index between locations and cost_matrix objects. This means that the costs associated with coordinates at index i in locations object should be added in a row at index i in the cost_matrix object as well.

  4. Using custom costs for a subset of total locations is not allowed. Either it should be used for all locations or not used at all. To ignore a particular location and prevent it from being included in the optimization, you can assign a very large value to the corresponding row and column in the cost_matrix. This ensures that the optimizer avoids that location in the routing solution.

  5. When the travel_cost is set to customized, the optimization algorithm takes the customized cost matrix into account when calculating the overall cost of a route.

  6. max_travel_cost feature allows you to set a maximum travel cost for a route. When a customized cost matrix is used in the optimization request, the total cost of a route is calculated based on the values provided in the customized cost matrix. The max_travel_cost feature ensures that the calculated cost of a route does not exceed a specified value. By combining the customization of the cost_matrix and the max_travel_cost feature, you can optimize routes based on your desired cost factors while also ensuring that the routes remain within specific cost constraints.

Sample Cost Matrix Object

1"cost_matrix": [
2    [
3      0,
4      4,
5      22,
6      9999
7    ],
8    [
9      4,
10      0,
11      12,
12      33
13    ],
14    [
15      22,
16      12,
17      0,
18      45
19    ],
20    [
21      9999,
22      33,
23      45,
24      0
25    ]
26  ]

Optimization POST Method

Request URL: POST https://api.nextbillion.io/optimization/v2?{key}

Use this method to configure the constraints and properties of the optimization problem that you need to solve. Use the fundamental objects - vehicles, jobs, locations and shipments to emulate the scenario that your business needs to optimize. You can choose to use either one of jobs and shipments or use both of them.

Define the objective of your optimization, soft-constraints and routing preferences in the options object. You can also use advanced features like re-optimization and order sequencing using the solutions and relations object respectively.

Once an Optimization POST request is successfully submitted, the API will return a unique task ID in the acknowledgement response. Use this unique ID to retrieve the actual solution using the Optimization GET Method.

Request Parameter

Loading...

Request Body

Loading...

Response Schema

Loading...

Example

Let us build a basic route optimization request using a sample scenario which has:

  1. 2 vehicles with properties like capacity, time_window, start_index, end_index and skills set.

  2. 6 jobs and 1 shipments with their id, locations, pickup/delivery amounts, time_windows and service time set.

Request

1curl --location --request POST 'https://api.nextbillion.io/optimization/v2?key=<your_api_key>' \
2--header 'Content-Type: application/json' \
3--data-raw '   {
4    "description": "Los Angeles Sample Optimization",
5    "locations": {
6        "id": 2,
7        "location": ["34.06675919,-118.30620984", "34.04268850,-118.28191077", "34.03434239,-118.28358834", "34.04238041,-118.23817754", "34.08431954,-118.25597762", "34.06892275,-118.29156827", "34.01103011,-118.19238067", "34.08659806,-118.17526366", "34.06624918,-118.11066669", "34.05221370,-118.28427087"]
8    },
9    "jobs": [
10        {
11            "id": 8,
12            "location_index": 0,
13            "service": 300,
14            "pickup": [
15                1
16            ],
17            "time_windows": [
18                [
19                    1688112000,
20                    1688119200
21                ]
22            ]
23        },
24        {
25            "id": 9,
26            "location_index": 1,
27            "service": 300,
28            "pickup": [
29                1
30            ],
31            "time_windows": [
32                [
33                    1688112000,
34                    1688119200
35                ]
36            ]
37        }, 
38        {
39            "id": 100,
40            "location_index": 3,
41            "service": 300,
42            "pickup": [
43                1
44            ],
45            "time_windows": [
46                [
47                    1688119200,
48                    1688122800
49                ]
50            ]
51        },
52        {
53            "id": 18,
54            "location_index": 6,
55            "service": 300,
56            "delivery": [
57                1
58            ],
59            "time_windows": [
60                [
61                    1688126400,
62                    1688130000
63                ]
64            ]
65        },
66        {
67            "id": 28,
68            "location_index": 7,
69            "service": 300,
70            "delivery": [
71                1
72            ],
73            "time_windows": [
74                [
75                    1688126400,
76                    1688137200
77                ]
78            ]
79        },
80        {
81            "id": 38,
82            "location_index": 4,
83            "service": 300,
84            "delivery": [
85                1
86            ],
87            "time_windows": [
88                [
89                    1688126400,
90                    1688137200
91                ]
92            ]
93        }
94    ],
95    "vehicles": [
96        {
97            "id": 1,
98            "start_index": 8,
99            "end_index": 8,
100            "capacity": [
101                46
102            ],
103            "time_window": [
104                1688110200,
105                1688140800
106            ],
107            "skills": [2, 3]
108        }, {
109            "id": 2,
110            "start_index": 9,
111            "end_index": 9,
112            "capacity": [
113                46
114            ],
115            "time_window": [
116                1688110200,
117                1688146200
118            ]
119        }
120    ],
121    "shipments": [
122            {
123                "pickup": {
124                    "id": 1,
125                    "service": 300,
126                    "location_index": 2,
127                    "time_windows": [[1688122800, 1688126400]]
128                },
129                "delivery": {
130                    "id": 1,
131                    "service": 300,
132                    "location_index": 5,
133                    "time_windows": [[1688126400, 1688130000]]
134                },
135                "amount": [5],
136                "skills": [2],
137                "priority": 100
138            }
139    ]
140    }'

The above problem statement would look like the following when visualized on a map. We can see the locations of the 2 vehicles, 6 jobs and a shipment task. We will cover the solution and how it looks on a map in the next section.

Response

1{
2"id": "3b14afd6c576690eb1df5c6871090383",
3"message": "Optimization job created",
4"status": "Ok"
5}
6

Optimization GET Method

Request URL: GET https://api.nextbillion.io/optimization/v2/result?{id}{key}

Use this method to retrieve the optimized solution for the optimization tasks created using the Optimization POST Method.

A point worth highlighting here is that the optimizer uses traffic conditions at the time of making the request to prepare a solution. Slight changes in traffic conditions can cause the optimizer to prefer different routes and possibly different sequences in which to fulfill the jobs or shipments. Therefore, different optimization requests made with similar task or constraint configuration are expected to return different optimized solutions.

Request Parameters

Loading...

Response Schema

Loading...

Example

Let’s retrieve the same job that was created in the example above in the Optimization POST Method section.

Request

curl --location --request GET 'https://api.nextbillion.io/optimization/v2/result?id=3b14afd6c576690eb1df5c6871090383&key=<your_api_key>'

Response

1{
2  "description": "Los Angeles Sample Optimization",
3  "result": {
4    "code": 0,
5    "summary": {
6      "cost": 5936,
7      "routes": 2,
8      "unassigned": 0,
9      "service": 2400,
10      "duration": 5936,
11      "waiting_time": 1863,
12      "priority": 200,
13      "delivery": [
14        8
15      ],
16      "pickup": [
17        8
18      ],
19      "distance": 85249.3
20    },
21    "routes": [
22      {
23        "vehicle": 1,
24        "cost": 4772,
25        "steps": [
26          {
27            "type": "start",
28            "arrival": 1688122026,
29            "duration": 0,
30            "service": 0,
31            "waiting_time": 0,
32            "location": [
33              34.06624918,
34              -118.11066669
35            ],
36            "location_index": 8,
37            "load": [
38              3
39            ]
40          },
41          {
42            "type": "job",
43            "arrival": 1688122800,
44            "duration": 774,
45            "service": 300,
46            "waiting_time": 0,
47            "location": [
48              34.04238041,
49              -118.23817754
50            ],
51            "location_index": 3,
52            "id": 100,
53            "load": [
54              4
55            ]
56          },
57          {
58            "type": "pickup",
59            "arrival": 1688123701,
60            "duration": 1375,
61            "service": 300,
62            "waiting_time": 0,
63            "location": [
64              34.03434239,
65              -118.28358834
66            ],
67            "location_index": 2,
68            "id": 1,
69            "load": [
70              9
71            ]
72          },
73          {
74            "type": "delivery",
75            "arrival": 1688124537,
76            "duration": 1911,
77            "service": 300,
78            "waiting_time": 1863,
79            "location": [
80              34.06892275,
81              -118.29156827
82            ],
83            "location_index": 5,
84            "id": 1,
85            "load": [
86              4
87            ]
88          },
89          {
90            "type": "job",
91            "arrival": 1688127186,
92            "duration": 2397,
93            "service": 300,
94            "waiting_time": 0,
95            "location": [
96              34.08431954,
97              -118.25597762
98            ],
99            "location_index": 4,
100            "id": 38,
101            "load": [
102              3
103            ]
104          },
105          {
106            "type": "job",
107            "arrival": 1688128357,
108            "duration": 3268,
109            "service": 300,
110            "waiting_time": 0,
111            "location": [
112              34.08659806,
113              -118.17526366
114            ],
115            "location_index": 7,
116            "id": 28,
117            "load": [
118              2
119            ]
120          },
121          {
122            "type": "job",
123            "arrival": 1688129471,
124            "duration": 4082,
125            "service": 300,
126            "waiting_time": 0,
127            "location": [
128              34.01103011,
129              -118.19238067
130            ],
131            "location_index": 6,
132            "id": 18,
133            "load": [
134              1
135            ]
136          },
137          {
138            "type": "end",
139            "arrival": 1688130461,
140            "duration": 4772,
141            "service": 0,
142            "waiting_time": 0,
143            "location": [
144              34.06624918,
145              -118.11066669
146            ],
147            "location_index": 8,
148            "load": [
149              1
150            ]
151          }
152        ],
153        "service": 1800,
154        "duration": 4772,
155        "waiting_time": 1863,
156        "priority": 200,
157        "delivery": [
158          8
159        ],
160        "pickup": [
161          6
162        ],
163        "distance": 75560.2,
164        "geometry": "aq|nEnn{oUF??aB?uC?s@AeA?w@?OA{@m@@Y?K?W?kA?a@@I?Y?a@?M?w@?I?A?K?I?_@?Y?a@@O@M@YBK?QMkAA_@?M?c@A]?S?M?K?O?U?iB?eA?e@@M?M?U?MAK@S?O?K?kCBm@KICIIEICIAK?IBIBIDEFCFCJEl@?j@?ZAL@HDHDDFBHDLBf@BH?H?J?J?F@f@@`@Bj@@D?DR~B@nCFlNBzMDlJ?~@BlHBxE?bB?f@@tC@|A?n@?J@fA?pA?V?Z@x@@dA?l@?`@@bA@`E?`@BnL@V@pB?~@@t@?F?t@?tA?lA@rA?rB@fD?jABnD@xB?r@?b@?T@j@?x@@v@?fB@`@?jB@f@?N@lE@pA@|FBdF?vA?FAjAC~@Ez@IlAQxBIfACv@Ap@?l@@Z@L?FB\\Ff@Hf@Jf@Lf@Pf@JXFN|ChHr@~AHPJV`BvDFJLZ|ArDDFb@dADJt@jBNZHPn@xAP`@xB|Eb@dAtAdDzBdFjAfCp@~ArAbDbAzBbAdCP^n@|AVv@JVt@lCHZLb@JXJVFPHNLXLVHNHJFLHLJLHLJLf@n@X\\TVPPLLJLNNZ^j@|@j@lADJFPBFFPJXFVF\\BLBJHn@@PBL@T@`@@XBV?N@P?PAZ?b@Af@A\\Et@Cb@OtBC\\APKtAGl@GhAGp@E~@Cd@@ZAl@@R?\\@h@Dt@Fx@Ft@@NBR?BBJ?@BLFZJf@FZDTPj@Lb@JXJ\\Nd@Tn@Rj@@BVz@HRL\\d@zAj@bBDJ`B`FPf@Z|@f@vAbAxCNf@Vv@jAnDjAhD~AdEv@vBn@fBl@dBZv@Tj@Nb@DJDJPl@^jALd@Nl@Hb@Hb@BLNdAHn@Hr@F|@D`@?DBZB\\B`ABpAAn@AnBChDC|A?l@AfAC~BAvAC~AAdA?RAnAAh@?f@KpLCvAKjH@`BFhBDdAJ|DNrBB`@Ff@Dp@JfADv@H`ADv@Hn@Db@D\\Dd@F\\F`@Fb@DXRz@v@pCDLBHLb@Ld@J^`@fBBJ@FDT@DFj@Dd@Bl@Bn@?r@Ax@Cv@Et@Gv@It@QdAKb@AHENAHK^Qt@]nAsA|EQl@Qd@K\\Qf@Od@Qd@CJENgBpFMd@Ob@[nACLE\\CVANAPAZ@R@b@B^BXFVFVBDDH\\d@RRRNRLTJTHVDJ@R?H?LALAPCTGTMXOtAcApDeCXSZUVOTITEVCjAELAfDMdAAhAA~@Gz@Bv@DJ@b@Bh@D^Dj@F^FVBf@Jb@Hb@Hb@JNBZHl@LLD`AXD@NDLDLDB@VHp@VFBFBlBpAPNPLr@h@jAt@r@d@|@j@`BnAb@`@VPPLB@HDFDl@\\AR?n@?F@J?X@~@DzB@z@Bj@@r@@dA@R?N@L?r@@p@?\\@f@@\\Bp@BbBBbB@X@L@JFZBFBLXvA`@lBX|Ah@lCRdAfAhFBPFTFd@BRBP@d@@rA?J@pA?B?N?L?J@rA@nABxGA`@AVAPERERCPELCLEJIRIPw@`BoBtD_AnBe@~@i@`AUd@Wd@INe@z@MTIR[n@a@z@MTMTKRS^INORe@h@{@bAKNQTMRINUx@p@AXAb@?d@?l@?D?V?jABX?d@?j@@f@?j@Br@@vADxDHz@B^?zELbBFt@Bz@@t@@X@n@@d@@|DJ`ABZ@t@@d@@n@Bd@@v@BV@@?p@B@IDg@@G@W@W@Q?O@[?O@W@e@LiFNmFBeBB]FeBDyA@u@Bm@@i@?g@@e@jBE`BA|AAdBAbA?vCAvD@`B?dB?CwCb@?j@?l@Cp@Ab@AN?DAP@NFLFHDBBJJFHHPN\\Ph@FNd@hAn@tAh@jBL`@Nd@FPZbAVv@HTHXL\\DLHVV~@`@lA~@nCZfADJrAlEDNHTLb@~@zCL\\`AbDZdAPr@BHHd@Lr@Jr@Hr@Fr@@H@T@\\?X@F?xB?f@ArAEz@C\\C\\Kz@Mx@Ox@Qv@Sv@Ut@Up@[z@GLeGbNMZo@vAO^MTi@nAaAzBINMXCDk@nAg@jAKRO\\a@|@_AvBeA~BQf@gBzD_AtBSb@Q`@OZO^KRaAdCUl@e@pAUp@GROd@Md@M`@K^GTGVOj@CJKd@Sx@I`@SdAQv@Ot@S|@Ml@Oj@Kb@K`@St@KXGRITIVMZKXEJIRMZKTGNGNy@dBYn@S`@Ud@MVYn@o@tAO^MV]v@a@|@[v@Q\\g@hACFIPs@zAg@`AMVu@xAILS\\e@t@o@`AINc@r@c@p@]j@[h@MRi@`Aw@tAQ`@Q\\Sb@Qb@Ul@M\\Qd@GRGNK`@Oj@CHCHCLEPKf@CLCNCJAJAJ?DCL?FAJCr@?J?j@@^M~A@T?V@^?b@@t@H`D@bABdB@v@LlD@P?HB^BRHtA@HLdBFl@@LBRL~@Hp@Hl@DXv@lGJz@Ff@D\\Fb@BXDZ@N?|AA^CdBCVCPENGLIHIHKFMBO?U@E?G?_@@?c@?{@?S?S?k@?U?e@?O?S@Q?M@KD[nBA`@Ab@?j@?X?LAX@TA`@?N?`@AZ?j@?`@@j@?L?Z?@GBGDSBG^gA\\cAzBhARJGRELKNCBCBI?GCKESGCAYOOIk@]_@fACFERCFAF[?M?k@?a@Ak@?[?a@@O?a@?U@YAM@Y?k@?c@?a@@oB@mBBW?_@@[@s@BoA?U?Mb@I\\CHALANAN?L?b@?T?\\@bC?bB?N?zC?H@bA?P?n@?^?\\?bB@zB?n@?bE?Z?`@@Z?X?V?v@I?g@?m@AU?cL@gB@Y?k@?e@?O?e@?i@?i@?g@?Y?w@?_@?cA@g@?eB?O?s@?W?M?m@?m@?m@?e@?[@cE?[@]A]?yE?i@?q@?W?m@?q@?gA?g@?Y?K?aA?O?Q?s@AQ@M?I?Q@G?{@?aB?G?MLY?q@@Y?SAUCO?MA]@K?]?[?O?K?W?YIk@@W?[?sA?c@?o@?G?Y?_@?e@?w@?Q?Q?cB@oB?W?e@?e@@m@?_@?C?W?uA?U?W?M?iA@[?i@?WAK@S?Q?M?YAW?e@?a@?O?Q?a@@g@A{@?a@?i@?M@Y?WAwA?e@?_A@]?I?U?yA?oA?y@?M?c@?mA?a@?G?_@?K?W@cA?_@?K?kA?M?Y?q@?S?o@?Y@O?iB?e@?i@AE?W?mC@oA?Y?wB?aA?kB?O?Q?_A?mA?{@?{@@O?Y?u@?U?S?}@@g@?q@?sA@U?[?s@Ag@@AyB?UAe@A]AQAQAOAGCMAIEOI[Oi@K]CKCOCMAQAM?M?EAK@]?g@@O?u@@cBDwDBg@?CBo@IiANiBBYJcALaARuA\\cCPiATcBPoA@KJo@Fa@LaAf@mDVgBLs@Js@FSRsABKN{@TeAHe@RaAJc@VuABOz@mENs@P}@P_ARgANq@Nw@Ji@Jg@Ps@Nm@No@Nk@Rw@\\gATq@HUVu@|@{B|@wBb@kAPi@`@kARs@\\q@P[LYBIFQHIz@aBDIf@aAn@qAd@{@UOWOQM[QSKi@Yk@Yu@]iAm@SKUMUMSKSKQKKGOIm@[WMUIe@Yi@WMIMGe@WSKSK_@SMIu@_@aAg@a@Sv@iCl@kBXy@b@kAf@_B@GBG@E@I?Im@EUCQEMCSGs@U[K[MSGQIe@OICy@[qAe@YMa@Oa@MYEKGIOYMIEMOGGMISKQIOIWKsAo@YSQIKIIIW[GGSUMOMKCEGGMIKIIEEACCKCKAIAKA}@GKAIAGCKEECGKCECC}Aw@KEKCIAGAICm@[QAAAA?A?KGcCsAsFsCPi@Ro@?G?CACACECWOVNDB@B@B?B?FSn@Qh@rFrCbCrAM^Sh@GLo@nBi@dB[`AIRCFGFGFYAo@CaA?QAyBEeBA]A_@AO?{@Ce@A_@CC?K?G?ODKCE?c@Gy@GUC]E]EaAKSE_@EeBOq@GM?MAQCOAMAUA[M[KUEc@EWGIOECA?k@[g@Ys@_@KEUOUI_AiAY]QUm@m@i@k@WWQQy@{@{@w@OOwAcBUWs@w@cB_Bc@]UUaAu@s@e@cAs@}@m@kEsCs@w@u@o@sAcAYUa@]Ya@[_@UU]WOKs@q@GEEEOQUSMMMMa@a@GIKIIKIKU]GQGSEYAEASAK?K?M?O@K?I@I@K@I@MBIBKDM@CBIFMDKFKDEBEBEBEBCBCBCfAoA`AkA^g@dCgCNOn@m@Z[DIDETUVY^a@`BeBf@k@PQ|@_A`@a@Z[POTWp@s@`@c@j@m@\\_@`CcCj@}@~@aA\\_@zA{A|@y@v@}@lDcDJKbAaAHIt@q@n@o@h@k@z@_AjAuAp@{@h@u@r@iA`@m@lAwBlBkDt@{AfBkDdAqBx@aBlA}B`@w@z@uAf@{@pEaHv@oAHMXi@`@q@Xi@Zq@Pc@Pa@HSHUHWHQDSFQHYNo@BOTeAF]R_A@GDMNw@H_@@Cd@kCTmADOXoADKDQLa@BKBIHSNc@HQJWBKVm@\\w@N]BIFGFKLUPWf@y@DG`@k@DGX_@NSbAeAVU^_@RQt@m@t@k@l@_@^ULGNGFCPIPIj@Sj@Qj@Ol@Kl@Il@G^CXAX?|@@hABxBHd@@Z@h@BT?d@@z@@t@CX?ZCn@Gf@GHARE^I`@MbA[FAv@CzCaAvBu@FAbA]\\MVMVORQ^YZYXWb@[^U\\Q^Ol@QlBi@h@KREPAzAB|@?h@@P?`A@Am@?i@?g@@O?e@Ak@?u@A}@?aEAU?aFAMAcE?{@?q@AaA?}CC_G?sAF[@YD[FYHY@ELWFOTa@FMP[c@iAK[ACWq@?QCIQe@EOGOIQGQa@aAGQMGGQSg@mBkFa@gA]}@Oc@[{@_@aAoAcD_@_A[eAGMGIIMUUGE}AiAY]]]a@a@_@c@u@q@w@s@cA_AmBmAs@c@iBiAIGkAu@WOy@e@g@Ym@]YQ]Sk@[q@e@]UUSe@Yi@Y_B_Ae@YoAs@w@a@OIKGYQa@U]S[SKQa@_@OIKIOIa@YMIKGKGOKOISMQIQGKEYGKEOCOAKCo@Im@I_@EUCcAKUCg@IQCQEUG_@MSIMIMKUOGESQ][c@]g@e@kDcDc@a@e@c@]YWUi@k@m@q@aB}AGIa@]w@s@}@w@e@e@_@c@[e@[i@IMKSEMKWKWGUCIGQIYIYCICKQy@Gu@Gk@C[Cs@AiAAk@@o@?o@@i@@[@M@YBs@Be@@EHaAPiBV_CJy@L_AFi@Hq@Fw@B_@@a@?k@?UAWAUAWCSASEUESCUI[GWCSCGCGGQSu@CIEMK[Yy@Qe@u@uBQc@Yu@IYj@YDCZOVOx@c@M]K[s@{B_@PUy@Ma@ZSNb@Vx@r@zBJZL\\\\jABDJZ^nAd@vAHVDN@JAHtD@J?bCAf@?j@?nAA~@?H?lA?^?jA?L@L?T?l@?n@?zBCvB?rA?|B?\\@N@H@D?@@H@D@DBJFFDB@NJHFJHFHFJJNJRNVT\\JLPNBBLJJJHFPLHDLFbAl@LHPJNHrBhAVJD@J@J@Z@D@F?V?t@?n@BpADbADZ@rAFN?~@D|@DpBHtCHT?bAAxDKRAj@Ab@AD?V?rAChBElBE`EGV?z@?HARAZAHALEPGQMKEGGGEIGc@g@IICEISEKIUIUIUESEMCKCMEMGk@Iq@?IIw@E[Em@DGBGBEBCFEDCFCB?HAD?NBTPLLf@^j@b@t@h@`@ZfBnAPLPLHDLFLDLBLBRDV@B?N@b@@r@@`@?pB@f@?N?L?N?N@^CHAHCRIPKFENKJILKHMNODGXk@FUHi@@Q?O?Q?a@?c@?E?M?QAU?yA?K?qAAQ?_A?g@?[?}@?aA?m@?W?WBQBQDQHWNOLKHGNIJGHEXSPI^ULGL@BAHEFCDCPKPI^SLIHMNGBFTn@Pj@HXDR@N?NCJCJEHGFGDKBI@K?ICIEKKIOMW]y@Se@ISKWQ_@EKO_@M_@Sm@KYK]AIQs@Ou@Mu@ESCOGg@C[Ea@CcC@kB?c@Be@JmBX{EJuBB[@UBQ@GDSFSHOLMJKNGJGPCJAV@\\?R?P?`@?z@Ap@Ax@C`AGj@Gb@EHCbA_@nA[REZIr@SxC_AFCdBg@HCn@Ql@MNCNCn@Ip@EVAXAp@?p@?n@@D@j@Df@DH@n@Ln@Ln@Pl@Tn@Tj@Xl@Xf@\\n@b@t@h@|@t@`CrB`Ax@n@d@NLJHzAlA\\XdAz@dA~@XRJH\\Xn@h@~@v@^VRNl@`@VNPJl@ZRJNFPHHB`@Lf@LbAVTFH@L@JBJ@J@XDn@DP@^B|@@fFArEAn@?h@?H?bEAnCAbD?R?|BA|@AL?V?d@?rBAN?f@?J?T?NAF@FAJ@J?T?nE?v@@p@BR@XBJ@J@J?ZFXFXHb@Jn@Pt@RbA^p@Tj@Pd@Pp@Td@NVJD@~@ZNFRHv@Vn@R~@ZXJb@LXHRFNDLBJBLBl@JzAPN@P@V@Z?J@H?d@?R?~@?f@?T?j@Ar@?j@@Z?Z@f@BX@V@TBT@RBx@JLB`BTl@N^F`ARfARpAXJBh@Jx@Pv@Lr@Ht@Fh@BF?zA?H?N?t@?tB?X?H?Z?^?fAAhA?n@@v@CPAFALAD?XC\\GTEDAd@KNEHCPIRIt@WNGNEd@QXKTINGRGPGVEZGRCPAZCb@Cv@Ap@?pFGJ?f@?\\?lAA`B?N?L?l@AT?lA?X?Z?V?l@?T?p@A^?nA@bA@hB@rAHhAF`@Pj@NXDr@JB@NDLDNJJLHLHNBLDRBb@DXDRDNFJDFBBLHRLRHZN\\HIZQt@Mj@EPEPK`@Sz@Qp@Qv@Sx@YhAMl@mBxH]|A[rAWbASz@Op@s@vCo@nCy@hDSz@GVGVOn@[pAc@jBk@|BOl@Qz@a@`B[nAUbA_@|AQr@uB|IU~@Kb@m@hCg@tBQr@GXKd@m@hCl@iCJe@FYPs@f@uBl@iCJc@T_AtB}IPs@^}ATcAZoA`@aBP{@Nm@j@}Bb@kBZqANo@FWFWR{@x@iDn@oCr@wCNq@R{@VcAZsA\\}AlByHLm@XiARy@Pw@Pq@R{@Ja@DQDQLk@Pu@H[FWJi@H]Le@No@Lm@DOBQDUFUPu@Ja@Pu@DSe@SMGiAc@OEMAM?OBMDKHIHINO\\O^KPCDGDMHODQBM@i@?aBFcAGo@Eg@Au@EMAu@?_AAs@?mBAkB@aA@WAkA@M?u@?[?i@?sA?c@?oFCQAwDCeA?o@AY?m@@SBYBYDq@JUBMBSFUJMF_@NUHu@VUFGBQFu@Rw@Rq@Lk@HiBJS@U@M?K@U?S?_@@mABo@@{@Ay@Cy@Ey@Gy@My@O_ASoFgAq@MYGQCa@Kc@E]G}@ISCQAi@EMAs@Cm@Aw@Ae@?uA?mA@c@?W?WA[?k@CG?G?g@Ea@Eg@I[EAAEA]IUEa@MaA[c@Oe@Ow@WICsBs@k@[c@I]KWKy@YUKeA]m@Ua@Qk@Qm@OYGa@ISCEAYEMAIASCIAa@CiAEiAAcA@qB@S?S?O?I?I?I?EAA?U@e@?aC@U?Q?oA?e@@u@?]?U?O?w@?}@@u@?sA?g@?eA?{A@[@K?c@?_F@qD?wA@[Ay@AMASAm@GWCQCKCq@Kq@QMCa@Mq@Wg@UCAm@Ym@_@m@a@EEsB_B[WEEc@]e@a@{@u@uBaBeBsAcA}@eDmCaAw@o@i@q@g@KG_@UKI_@Sm@Yo@Wo@Uq@SICg@Ms@Ks@Ik@Gi@Eq@AcA@{@@q@Dk@FkCl@_@HgAXeA\\a@N_@JqC|@[HMDiBHO@y@@a@?q@Gg@Ge@IWEUK[Ic@Kk@MYIs@U[OQMKKIKGKIQIQGWIi@Ie@OcAWsAMg@K]Si@Q]Ua@S_@[_@]g@GGYYk@k@SSQSW[W[SYKOKMIOOUMSIOoAcBm@sAaA}BcAcCy@kBcB}DKUu@_BEKk@uAgBaEc@cA}@uB}AqDWm@]w@Wm@Q_@Se@]y@IQKUQc@c@eAg@iACIQ_@g@iAi@oAcB}Dy@oBUi@EGIQYs@KWM]Qk@Om@Ka@Kg@EQAGIe@G_@E[Gm@AUCQASAUA[Cc@A}@?kAAiDCiC?eCCaF?{@AyAAcD?W?I@]AmAAoEAuAAk@AcB?y@?i@?iAAw@?W?s@AsDAcA?e@?OAy@AwIA}CCcE?]CwH?gACsI?e@CaB?_A?sAA}B?I?MAuBAm@?wA?yB?SCaC?i@?i@CcH?{@AkA?qA?]Aa@?e@AsBAmB?sA?_AA{AAsA?kBAiA?u@AcB?cAC{H?_@?U?UHu@H_A@_A@E?KD[BKDGFGHEJCP?b@?`AARAFAJEHGHKL[HMFIJEPGJ@N?L?z@@t@?h@?PIJ?XCLANA`@AX?^?H?J?@?H?v@?L?`@?X?H?`@AjA?V?J?X?l@A@z@?N?v@@dA?r@?tC?`BG?"
165      },
166      {
167        "vehicle": 2,
168        "cost": 1164,
169        "steps": [
170          {
171            "type": "start",
172            "arrival": 1688111565,
173            "duration": 0,
174            "service": 0,
175            "waiting_time": 0,
176            "location": [
177              34.0522137,
178              -118.28427087
179            ],
180            "location_index": 9,
181            "load": [
182              0
183            ]
184          },
185          {
186            "type": "job",
187            "arrival": 1688112000,
188            "duration": 435,
189            "service": 300,
190            "waiting_time": 0,
191            "location": [
192              34.06675919,
193              -118.30620984
194            ],
195            "location_index": 0,
196            "id": 8,
197            "load": [
198              1
199            ]
200          },
201          {
202            "type": "job",
203            "arrival": 1688112863,
204            "duration": 998,
205            "service": 300,
206            "waiting_time": 0,
207            "location": [
208              34.0426885,
209              -118.28191077
210            ],
211            "location_index": 1,
212            "id": 9,
213            "load": [
214              2
215            ]
216          },
217          {
218            "type": "end",
219            "arrival": 1688113329,
220            "duration": 1164,
221            "service": 0,
222            "waiting_time": 0,
223            "location": [
224              34.0522137,
225              -118.28427087
226            ],
227            "location_index": 9,
228            "load": [
229              2
230            ]
231          }
232        ],
233        "service": 600,
234        "duration": 1164,
235        "waiting_time": 0,
236        "priority": 0,
237        "delivery": [
238          0
239        ],
240        "pickup": [
241          2
242        ],
243        "distance": 9689.1,
244        "geometry": "kyynEfk}pUW?M?I?_A@a@?W?gA?eA@mDB[?S?I?Q?K?W?[@q@?u@@OAU?y@?YAeA?k@Ce@?}A?At@?N?^?RAp@?X?`A?P?v@?\\@h@?lA?h@?l@?T?d@@\\?RAZ@d@?F?f@?P?`@?b@?p@?b@@fA?Z?^?rA?p@AZ?F?PAjA?t@Ax@Ax@?N?B@p@AxB?z@?jB@pA?j@?~@?T?b@@tA?`B?`@?X?fA?f@?~@?pB?vA?fA@v@?tA?xA?h@?lD@l@?r@?vA?h@?b@@rA?dC?Z@|DA`E?f@@xFiAAm@?w@?S?mEBeI@k@?IAG?EAE?CASAI?m@?oCDI?e@?c@?{@AcA@k@?sA@eDA{G@zGAdD@rAAj@?bAAz@@b@?d@?H?nCEl@?H?R@B@D?D@F?H@j@?dIAlECR?v@?l@?hA@AyF?g@@aEA}D?[?eCAsA?c@?i@?wA?s@Am@?mD?i@?yA?uAAw@?gA?wA?qB?_A?g@?gA?Y?a@?aBAuA?c@?U?_A?k@AqA?kB?{@@yBAq@?C?O@y@d@?^?X?F?n@?b@?rA?Z?V?j@AXHV?J?N?Z?\\?J?\\AL@N?TBR@X?p@AX?LMF?`B?z@?F?PAH?L?PAr@@P?N?`A?J?X?f@?fA?p@?l@?V?p@?h@?xE?\\?\\@ZAbE?ZAd@?l@?l@?l@?L?V?r@?N?dB?f@?bAA^?v@?X?f@?h@??q@?WAM?k@?cB?oD?cA?aA?a@?c@AsAA_G?W?C?O@M?M@S?M?K@I@K@GBSTaBD_@^cCD]BSLy@BONk@HWJ]HU^cAPi@Z{@HWp@iBL@B@@@AACAMAq@hBIV[z@Qh@_@bAITK\\IVOj@CNm@@_B@S?g@@e@?i@BW@}@BoA@M?u@?u@?]@S?G?C?YCMA]Ac@Ei@CM?i@AiFBm@?wA?e@@O?sC@qA@W?O?W?]?OA[@S?e@@E?"
245      }
246    ]
247  },
248  "status": "Ok",
249  "message": ""
250}
251

Following is a visual representation of the optimized solution on a map. We can see that the solution suggested by optimizer has 2 routes to cover all the jobs and shipments. Vehicle 1 starts from its start points and covers the location of all jobs within the prescribed time windows for each job. It also takes care of the shipment between completing the jobs as the skills required for shipment are possessed by only this vehicle in the given scenario. Whereas, vehicle 2 is assigned to only 2 jobs which are located near its starting point. We also get the summary of the overall solution as well as for each of the routes. We can see the overall waiting time is around 30 mins for vehicle 1 which was caused when it was waiting for the delivery time_window of the shipment to start. We also get the route-wise as well as overall cost of the optimized solution.

Multi-Dimensional Parameters

Capacity

The Capacity parameter in Vehicle Object is used to describe multidimensional quantities of capacity. In this context, multi-dimension refers to the fact that a single vehicle can carry loads defined in different units. For example, a vehicle may have a capacity of 10 cubic meters for volume, 1000 kg for weight, and 6 pallets for a number of items. These are three different dimensions of capacity, and each has its own value. By specifying Capacity as an array of integers, we can provide values for each dimension of capacity that a vehicle possesses. This information is then used by the optimization algorithm to ensure that the total capacity required by all shipments assigned to a vehicle does not exceed its capacity in any of the dimensions.

Example: Let's say a construction company has a fleet of trucks that are used to transport multiple things, such as bricks, cement, and even construction workers. Each truck has a different capacity for weight, volume, and number of persons it can carry.

In this case, the capacity parameter can be used to describe the multidimensional quantities for each truck. For example, a truck may have a capacity of 100 kg weight, 10 cubic meters of volume, and can carry 5 construction workers. The capacity parameter can be defined as [100, 10, 5] to represent these values respectively.

By leveraging the capacity in multiple dimensions, the solver can optimize job/shipment assignment to appropriate vehicles ensuring better customer service and efficient transportation.

Amount

Amount parameter in Shipment Object is used to describe multidimensional quantities of a shipment. The term "multi-dimensional" refers to the fact that a single shipment can have amounts defined in different units. Continuing with our example of the construction company above, let’s say a truck needs to pick up 50 kg of bricks, and 2 cubic meters of cement from a construction material supplier’s location. When defining the shipment we define this input as

1“amount”: [50,2,0]

0 for the construction worker dimension. Next, if we have another stop to pick up 3 construction worker, then we can define the amount as

1“amount”: [0,0,3]

If the other parameters, like distance, time_windows, location of other trucks etc. are favorable then these 2 pickups can be assigned to the same vehicle with “capacity”: [100,10,5] like in this example.

Amount parameter is useful for optimizing delivery routes and determining the most efficient way to transport goods based on multiple dimensions of quantity.

Skills

Skills parameter in the Vehicles Object describes the skills that a driver or vehicle possesses in different units. The term "multi-dimension" refers to the fact that a single driver or vehicle may have different skills or abilities, each of which could be measured in different units or quantities.

For example, let's say we have a fleet of delivery vehicles. One of these vehicles may have the following skills:

  1. Skill ID ‘101’: Capacity to carry 10 large boxes

  2. Skill ID ‘102’: Ability to transport goods at a temperature of -10 degrees Celsius

  3. Skill ID ‘103’: Ability to transport hazardous materials in a specific type of container

In this case, the Skills parameter would be set as an array of integers, with each element corresponding to a particular skill or ability. For instance, the skills parameter for the vehicle described above might be set as follows:

1"skills": [101, 102, 103]

Here, the first element (101) corresponds to the vehicle's capacity to carry 10 large boxes, the second element (102) corresponds to its ability to transport goods at a temperature of -10 degrees Celsius, and the third element (103) corresponds to its ability to transport hazardous materials in a specific type of container.

By including skills attribute in the optimization API, users can optimize their delivery routes based on specific skills and abilities of their drivers and vehicles, helping to ensure that each delivery is made efficiently and safely.

Skills Restrictions

Use skills to describe a problem where not all tasks can be served by all vehicles. Job skills are mandatory, i.e. a job can only be served by a vehicle that has all its required skills. In other words: job j is eligible for vehicle v if j.skills is included in v.skills. This definition implies in particular that:

  1. a task without skills can be served by any vehicle;

  2. a vehicle without skills can only serve tasks with no particular need (i.e. without skills as well).

  3. a job with multiple skills will be assigned to vehicles matching all the skills. The job will not be assigned to vehicles with partially matching skills.

In order to ease modeling problems with no skills required, not providing the skills key defaults to providing an empty array.

API Query Limits

  1. Nextbillion.ai allows a maximum rate limit of 6000 queries per minute or 100 queries/second for continuous requests. Note: We can increase the quota if needed on request. Contact [email protected] for more details.

  2. A maximum of 2000 locations can be added to the locations object

  3. A maximum of 2000 tasks can be added in an optimization problem. Number of tasks is calculated as number of jobs + 2 * (number of shipments).

  4. Maximum value that can be provided for truck_weight is 100,000 kg.

  5. Maximum dimensions for truck_size are 5000 cm for length, 5000 cm for width, 1000 cm for height.

API Error Codes

Response CodeDescriptionAdditional Notes
200Normal success case.

Normal success case.

400Input validation failed.

There is a missing or an invalid parameter or a parameter with an invalid value type is added to the request.

401APIKEY not supplied or invalid.

This error occurs when the wrong API key is passed in the request or the key is missing altogether.

403APIKEY is valid but does not have access to requested resources.

You might be querying for a geographical region which is not valid for your account or requesting a service which is not enabled for you.

404Requested host/path not found.

This error occurs when a malformed hostname is used.

422Could not process the request.

A feasible solution could not be generated for the given set of locations or parameter configuration.

429Too many requests.

QPM reached or API request count quota reached.

500Internal Service error.

There was an internal issue with NextBillion.ai services. You can reach out to [email protected] for an explanation.

Route Optimization V1
DIDN'T FIND WHAT YOU LOOKING FOR?