Route Optimization Flexible API

Introduction

Nextbillion.ai's Route Optimization Flexible 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 Flexible 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.
Route Optimization Flexible API
Tutorials
To see all tutorials related to the Route Optimization Flexible API, click this banner

Optimization POST Method

POST

https://api.nextbillion.io/optimization/v2?key={your_api_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 flexible route optimization request using a sample scenario which has:

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

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

Request

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

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.

documentation imagee

Response

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

Optimization GET Method

GET

https://api.nextbillion.io/optimization/v2/result?id={id}&key={your_api_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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
{
  "description": "Los Angeles Sample Optimization",
  "result": {
    "code": 0,
    "summary": {
      "cost": 6774,
      "routes": 2,
      "unassigned": 0,
      "setup": 0,
      "service": 2400,
      "duration": 6774,
      "waiting_time": 1696,
      "priority": 200,
      "delivery": [
        8
      ],
      "pickup": [
        8
      ],
      "distance": 88544
    },
    "routes": [
      {
        "vehicle": 1,
        "cost": 5391,
        "steps": [
          {
            "type": "start",
            "arrival": 1688121973,
            "duration": 0,
            "service": 0,
            "waiting_time": 0,
            "location": [
              34.06624918,
              -118.11066669
            ],
            "location_index": 8,
            "load": [
              3
            ],
            "distance": 0
          },
          {
            "type": "job",
            "arrival": 1688122800,
            "duration": 827,
            "service": 300,
            "waiting_time": 0,
            "location": [
              34.04238041,
              -118.23817754
            ],
            "location_index": 3,
            "id": 100,
            "load": [
              4
            ],
            "distance": 15357
          },
          {
            "type": "pickup",
            "arrival": 1688123729,
            "duration": 1456,
            "service": 300,
            "waiting_time": 0,
            "location": [
              34.03434239,
              -118.28358834
            ],
            "location_index": 2,
            "id": 1,
            "load": [
              9
            ],
            "distance": 23975
          },
          {
            "type": "job",
            "arrival": 1688124704,
            "duration": 2131,
            "service": 300,
            "waiting_time": 1696,
            "location": [
              34.08431954,
              -118.25597762
            ],
            "location_index": 4,
            "id": 38,
            "load": [
              8
            ],
            "distance": 32327
          },
          {
            "type": "delivery",
            "arrival": 1688127297,
            "duration": 2728,
            "service": 300,
            "waiting_time": 0,
            "location": [
              34.06892275,
              -118.29156827
            ],
            "location_index": 5,
            "id": 1,
            "load": [
              3
            ],
            "distance": 38067
          },
          {
            "type": "job",
            "arrival": 1688128555,
            "duration": 3686,
            "service": 300,
            "waiting_time": 0,
            "location": [
              34.01103011,
              -118.19238067
            ],
            "location_index": 6,
            "id": 18,
            "load": [
              2
            ],
            "distance": 52640
          },
          {
            "type": "job",
            "arrival": 1688129778,
            "duration": 4609,
            "service": 300,
            "waiting_time": 0,
            "location": [
              34.08659806,
              -118.17526366
            ],
            "location_index": 7,
            "id": 28,
            "load": [
              1
            ],
            "distance": 67654
          },
          {
            "type": "end",
            "arrival": 1688130860,
            "duration": 5391,
            "service": 0,
            "waiting_time": 0,
            "location": [
              34.06624918,
              -118.11066669
            ],
            "location_index": 8,
            "load": [
              1
            ],
            "distance": 78857
          }
        ],
        "service": 1800,
        "duration": 5391,
        "waiting_time": 1696,
        "priority": 200,
        "delivery": [
          8
        ],
        "pickup": [
          6
        ],
        "distance": 78857,
        "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@`BFhBDdAV~CFf@Fp@Jz@LtANxAH~@V|BX`BJj@Nn@VdANl@r@lCJb@XlARz@Jj@BRBLH|@Db@Dv@Bb@@j@@f@Az@At@?TANAPGt@CZAPGb@CTETG`@SdAYrAKh@Kf@Kn@ENG^Op@ERKf@If@Ib@Mj@Ox@Kf@GZGTGXMv@Mx@Gb@El@Ed@CZA`@C`@ChA?HAJ?^?JAjAA~@?f@?h@?N?n@Ab@?xB?xA@pC?~@@v@?j@?h@@^@R@V@T@ND\\DZFb@F`@FXFXBNHZDJFTHXJZJTFPFLHNFPDHDFDHBFHNLRHLPTJPNRRTLNJJBBFHTTPRNNFFFJDFHHHJHLLPBFFHJRDFHLFNFLFLDLBLFTDN@JBJ@LHx@@PBR?d@?\\GzB?TAlAC`ACj@I~@CXE^CPEd@Gh@Gd@EZALEf@Eb@CTAHAJKtACZEn@KpAEl@I|@_@|AMj@Ih@AJM|@Ib@AHELGPINGHWHI@K?A?E?IAYCK?e@IKIGIEKCG?G?EAG@G@WV]Z_@DEJIJGPGFAHAJ?H?NBJ@J@\\DPBVDXFPBJ@R?N@HAH?d@CRCLCLANCNARAVB@?VBr@Jd@DTDtBVfBPfAL\\Dn@LLFJFJFFHBDDHLZHNJNDBDBHDLDLBXDF@NLd@FH?Z@D?d@@PKL?rAAZAZ@jBEn@@PJF@HBF@D?F?FBB@@@@B@DDHA\\?b@?Z?`@?pA?D?tA?`@@L?LD`@B\\@X@JHz@@HF|@?BFn@DlAPlBDj@BT@L?B@NFXBFLNBBUx@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?`@AAG@M@Il@iB^eA\\P^Rb@V|@^\\cAzBhARJGRELKNCBCBI?GCKESGCAYOOIk@]}@_@c@W_@S]Q_@dAm@hBAHAL@Fa@@O?a@?a@i@MMKMACEGGKGQEQE_@ESMaAAEQcAIo@Kq@UaBYiAKmACWAIKeBG}@Ek@AYEm@?GAWAUG{AAy@OmIKy@Ei@EgAMwFCo@Ac@Aa@?MCc@As@Cc@CYEWIYAEGQEICGQWOQQOOISKUGUEWCW?UBWDYHYNWVIBIHSPSPUPMHk@b@WRYPWNSHYDO@Q?SCWCk@OcBi@e@M_@Mg@Ie@U[Oc@Wc@WWS[UUOSS[Wc@_@][QSQQ[_@gAyAQUQYk@{@_@m@S]Wc@}@aBYi@]m@AEQ[Ue@S]KSGMWg@Wg@_@u@Q_@_@s@[k@EIGQa@u@S]oFgKIUS_@[o@uAmC[m@GMwBgEUg@]o@ACOWSa@i@aAMWi@cA_@m@o@_AUYY]QSW[QQQSaAaAWU_@Y{DwCUSc@]KGWSKIOQQS_@W_Ay@QQWWq@k@KKu@s@e@c@SQqAsAq@q@MMUUMO[]aAy@e@g@QSa@a@QQSS]_@}B{Cy@eA}@iBS_@KQSYe@q@q@cAoBgCSYaAwAUUWQMIQGYKGAEAGAWCOCI?M?E?]Eo@EWBSBODC@QJMHC@QPOTILILwA`Da@|@yAjCYf@e@fAQX]d@_@d@a@l@_@j@QZ]j@MROVU^_@h@S^QXOXOVOVEJEFO\\Q^Qb@KTOZKVUn@Qh@Up@Sp@W|@YhAAFoA|EUz@WPUt@]fAKRKPKJKJGBMFWJIBYDCHCFk@fBENCFMZOd@o@hBCJCJAHAFAFAJe@@S@I?}@BO?I?S@[Bo@DUBWBUDmC^WBQ?Y?mAGsCIcAEyBGm@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[`AIRCFGFGFOVKP~@BR?PHJDXLtAt@JFJA^RnAn@hDdBbAf@z@d@^RZNLFpAr@|@f@\\N|@b@~@j@HFl@\\^RfAd@v@^LFv@`@h@Xh@X`@T`@R`Af@t@^LH^RRJRJd@VLFLHh@Vd@XTHVLl@ZNHJFPJRJRJTLTLRJhAl@t@\\j@XM`@Qn@W|AYlBO|@ATYdAGn@Kl@w@fCUr@EL_@`Ae@jAMVMZ_@|@Wl@Up@KZWp@GXOh@Sr@Oj@K\\I^K`@IXGZK`@EVKj@Kf@SdAGTShAc@xB{@hEKh@UlAg@fCCJGZWrACN[dBIb@W|Ak@fEOhA_@`CG`@c@|CALEP_@hCIn@EVIl@UjBGh@QxAGh@Iv@KdAMhAOnACRKn@QbAUhAQz@q@`BKVCDc@bAw@bBQZOVQVML]Za@`@WXKNCBAHAFAF?H?Zp@?P?tCAP@FAdA@P?T?Z?P?XAbB?l@@f@Ar@@Z?T?rAAp@?f@?|@AR?T?t@?X?N?z@Az@?lA?~@?P?N?jB?`A?vB?X?nA?lCAV?D?h@@d@?hB?N?XAn@?R?p@?X?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@Vs@Pq@La@DOv@iCn@mBl@gB~DoLL_@L[Z}@Xu@`@oAj@wBBS`@}A\\sAZqANm@Pq@H]HY@G`@aBbAaEZoAXiALi@T}@Ru@R{@Nk@@ERw@Ty@Nm@Pm@Ng@Tk@Ri@To@Vm@Zs@Xm@DIFMJMzAmCr@gA`@s@Zk@|@uAFKT]l@aAzA_CtAqBNWNS\\e@RUv@y@^]TSb@_@`@]f@c@TQDEFGFCLMLKFEZWfA{@jA_A~AqADGBCFGFELKNKb@[\\[ROJKLOPOV]TURUp@s@RYZe@R[LSj@m@v@mAXc@Va@NS~AgCb@u@r@oANWVe@NYHQFIFOTa@NYP[R_@R_@LSLWFMDGDIDGDIxAoCTa@FMZm@BE^s@HOXg@HOtByDBGHOVk@HQHSJUNc@J_@BKZiCBWDe@@Q?Q@u@Bu@AeA?c@Ai@@i@?[BmAHiD@SBk@HyB@W@U@UDm@Do@BW@MD]JqAL{AJqABYBYDo@BS@U@OFm@Bm@@I?I@K@QD_@@IBY@KToBH{@Hw@H_AD_@LaBPu@BMBIHm@DSH]Ni@Ng@Ri@Vk@BGR]Xc@Za@\\_@^]ZWLIJGLILIJGNGLGd@Qh@U|@_@p@WJELGPGFCb@Q^ORIbBo@~@Y|@W`AUHCNCJAREDA~@O`AM`AIB?x@GTAJAb@ApBCp@AL?N?h@?`@?fACfA?t@A^@h@@`@@ZBP@T@\\BZD\\BZDZDbANr@Ll@HvAXl@DZ@pA?t@Af@CRArAID?n@CZAL?n@@v@Bb@DhAJ`@DVBv@Dn@@n@?j@EPAHAp@EPCl@Gd@KDAh@QLE^K`@OBALGJGb@Un@QFCFCPGVMLGp@c@v@g@v@g@TQJIDE\\[HIb@_@f@c@\\]`AsAJSb@y@NWLQBAFILGHALAL@HBH@NBF@LHPJHFHF\\Pl@VHDFBTJ^N^Lb@Tb@Ph@TJB`A`@LDD@D@NGb@Br@?hFVl@B\\BfAFp@BN@n@BZ@zAFT@Z}@Ts@DIFQX_ADK`A{CRo@lCeIRq@Rm@b@oAFSJYNc@^gAb@oAHSbAyCt@uB\\aAfAiDN_@Pe@Vq@^iAX@X?J?Z?ZAP?h@Ah@AZAXCHAHCLEPGPIXMr@_@b@S~Au@ZOPINGPKRMHEHGJIFKHKN[JUJQBGHMBGFOFIHKLKTMLGL@RANAHAT?n@?j@AHALANCXEHCNETINKrAo@XMD[LiA@MHiAFy@NoCJ}ADi@B_@B_@LkBDaAPmDf@cI@IB[?E@QRyDIQHmAFgA^yJHkB@[BYBWD[D[Nu@b@mBtAaGf@sBNq@BIP{@R_AP{@@Al@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|@[HMD]HMDQBa@Fq@HaADs@?g@As@E}@KSAmCW{@IKAOC_@EWEM?SCI?mAK_@COA[EO?MAUCE?GAIAG?}@IOAq@Gc@EQCa@EQCOCOCUCa@GWE[ESGSCSGWG]Gq@S}@YWKu@USGYKWKOIWKSIYKOIGC]M_@QyAo@GCoBy@o@YKEe@Qm@Ye@QIEYM[MSKIE_@OEAm@Ym@Wm@WoBw@SGOEOEYIKCk@Mk@KYGUCk@Eq@EkBIwAEa@COAC?Q?[AE?a@@G?_ABu@@C?G@WDR`AL`@FRDNLVLVXj@LTPXj@dAv@xANZHZHVDT@HBR@T@RAX?B?PCVCNKd@Oj@IZUx@WdAOf@I\\Ol@G^Eb@El@?BAd@AFA|@BhA?H@\\@LBXBTLj@Nd@L`@FN~@bCx@xBFLLZ`@bAPVPT?@PR\\`@DFjAzA|ArBl@v@j@r@nBhCzAnBbApAv@`ATXn@v@Z^LLBBB@\\\\HDZVNHHFZVZPPJt@h@l@^VN^Rv@j@LL\\`@PPHLFJFLFLBHPv@Dl@DZHv@?HHp@Fj@DLBLBJDLDRHTHTHTDJHRBDHHb@f@HFFDFFJDPLQFMDI@[@S@I@{@?W?aEFmBDiBDsABW?E?c@@k@@S@yDJcA@U?uCIqBI}@E_AEO?sAG[AcAEqAEo@Cu@?W?G?EA[AKAKAEAWKsBiAOIQKMIcAm@MGIEQMIGKKMKCCQOKMU]OWKSKOGKGIKIIGOKCAGEKGECEAIAAAE?IAOA]A}B?sA?wB?{BBo@?m@?U?M?MAkA?_@?mA?I?_A?oA@k@?g@?cC@K?uDA@IAKEOIWe@wA_@oAK[CE]kAM]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@BACICIEKCIIWCIw@}BQe@GUI]Ss@Oy@GWEYACAIKw@EYC]Gu@Ew@Cu@Ae@Aa@AQAWAYCc@B]b@}G@YHiAHgABg@@g@@s@?i@?U?G?WA[AQ?KC]C[Gm@Ec@EYG[Ia@U}@Qo@Oa@EOSk@Yq@a@aAm@mAMS[i@Ua@U_@m@}@}@uAm@gAc@aA[m@m@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?"
      },
      {
        "vehicle": 2,
        "cost": 1383,
        "steps": [
          {
            "type": "start",
            "arrival": 1688111823,
            "duration": 0,
            "service": 0,
            "waiting_time": 0,
            "location": [
              34.0522137,
              -118.28427087
            ],
            "location_index": 9,
            "load": [
              0
            ],
            "distance": 0
          },
          {
            "type": "job",
            "arrival": 1688112000,
            "duration": 177,
            "service": 300,
            "waiting_time": 0,
            "location": [
              34.0426885,
              -118.28191077
            ],
            "location_index": 1,
            "id": 9,
            "load": [
              1
            ],
            "distance": 1177
          },
          {
            "type": "job",
            "arrival": 1688112986,
            "duration": 863,
            "service": 300,
            "waiting_time": 0,
            "location": [
              34.06675919,
              -118.30620984
            ],
            "location_index": 0,
            "id": 8,
            "load": [
              2
            ],
            "distance": 6005
          },
          {
            "type": "end",
            "arrival": 1688113806,
            "duration": 1383,
            "service": 0,
            "waiting_time": 0,
            "location": [
              34.0522137,
              -118.28427087
            ],
            "location_index": 9,
            "load": [
              2
            ],
            "distance": 9687
          }
        ],
        "service": 600,
        "duration": 1383,
        "waiting_time": 0,
        "priority": 0,
        "delivery": [
          0
        ],
        "pickup": [
          2
        ],
        "distance": 9687,
        "geometry": "kyynEfk}pUD?d@AR?ZAN@\\?V?N?V?pAArCAN?d@AvA?l@?hFCh@@L?h@Bb@D\\@L@XBB?F?R?\\At@?t@?L?nAA|@CVAh@Cd@?f@AR?~AAl@ABONk@HWJ]HU^cAPi@Z{@HWp@iBL@B@@@AACAMAq@hBIV[z@Qh@_@bAITK\\IVOj@CNMx@CRE\\_@bCE^U`BCRAFAJAH?J?LAR?LAL?N?B?V@~F@rA?b@?`@?`A?bA?nD?bB?j@@L?V?p@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?YIAJCTAV?@?t@?N?xB?bC@dB?N@~B?rA?f@@bF?xE?xEAxE@zE@vE@xE?zEoH?w@?mA?gI?g@?}@?C?y@?}A?O?U?K?cA?I?EAIAICGAIAW?c@?c@?u@?K?Q?_@?}B?kD@}D??vF@`C@tB{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@@y@?u@@kA?Q?G@[?q@?sA?_@?[AgA?c@?q@?c@?a@?Q?g@?GAe@@[?SA]?e@?U?m@?i@?mAAi@?]?w@?Q?aA?Y@q@?S?_@?O@u@|A?d@?j@BdA?X@x@?T?N@t@Ap@?ZAV?J?P?H?R?Z?lDCdAAfA?V?`@?~@AH?L?V?"
      }
    ]
  },
  "status": "Ok",
  "message": ""
}

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.

documentation imagee

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.

IndexLocation
051.388997,-0.119022
151.391915,-0.103666
251.369777,-0.10438
351.365014,-0.105654
451.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:

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

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

  • Hard constraint of max_activity_waiting time is effective only with in_same_route type of relation. It is not effective for other relation types.

  • If certain relations require multiple steps (e.g., jobs) to be on the same route, the vehicle assigned to that route must have enough capacity and the required skills to serve all the jobs on the route. The optimization service would return an error, otherwise.

  • 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.

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

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
2
3
4
5
`cost_matrix`: [ 	
				[0, 10, 5], 
				[10, 0, 8], 
				[5, 8, 0] 
			   ]

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 :

  • The cost values should always be non-negative integers.
  • 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.
  • 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.
  • 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.
  • 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.
  • 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
  "cost_matrix": [
    [
      0,
      4,
      22,
      9999
    ],
    [
      4,
      0,
      12,
      33
    ],
    [
      22,
      12,
      0,
      45
    ],
    [
      9999,
      33,
      45,
      0
    ]
  ]
}

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

“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

“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:

  • Skill ID ‘101’: Capacity to carry 10 large boxes
  • Skill ID ‘102’: Ability to transport goods at a temperature of -10 degrees Celsius
  • 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:

"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:

  • a task without skills can be served by any vehicle;

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

  • 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

  • Nextbillion.ai allows a maximum rate limit of 300 queries per minute or 5 queries/second for continuous requests.

    Note: We can increase the quota if needed on request. Contact [email protected] for more details.

  • At any point the maximum number of pending requests that the queue can hold is 25, for a given API key. New requests for the same key can be submitted once some of the pending requests are resolved.

  • A maximum of 2000 locations can be added to the locations object

  • 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).

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

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

  • When using traffic_timestamp or truck related parameters in the routing property of options attribute, please expect a higher request processing time, especially if the number of locations provided in the request is also high.

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.