cuOpt Self-Hosted Thin Client API Example#
Routing Example#
1from cuopt_sh_client import CuOptServiceSelfHostClient
2import json
3
4data = {"cost_matrix_data": {"data": {"0": [[0,1],[1,0]]}},
5 "task_data": {"task_locations": [0,1]},
6 "fleet_data": {"vehicle_locations": [[0,0],[0,0]]}}
7
8# If cuOpt is not running on localhost:5000, edit ip and port parameters
9cuopt_service_client = CuOptServiceSelfHostClient(
10 ip="localhost",
11 port=5000
12)
13
14optimized_routes = cuopt_service_client.get_optimized_routes(data)
15print(json.dumps(optimized_routes, indent=4))
response would be as follows,
1{ 2"response": { 3 "solver_response": { 4 "status": 0, 5 "num_vehicles": 1, 6 "solution_cost": 2.0, 7 "objective_values": { 8 "cost": 2.0 9 }, 10 "vehicle_data": { 11 "0": { 12 "task_id": [ 13 "Depot", 14 "0", 15 "1", 16 "Depot" 17 ], 18 "arrival_stamp": [ 19 0.0, 20 0.0, 21 0.0, 22 0.0 23 ], 24 "type": [ 25 "Depot", 26 "Delivery", 27 "Delivery", 28 "Depot" 29 ], 30 "route": [ 31 0, 32 0, 33 1, 34 0 35 ] 36 } 37 }, 38 "dropped_tasks": { 39 "task_id": [], 40 "task_index": [] 41 } 42 } 43}, 44"reqId": "ebd378a3-c02a-47f3-b0a1-adec81be7cdd" 45}
The data
argument to get_optimized_routes
may be a dictionary of the format shown in Get Routes Open-API spec.
It may also be the path of a file containing such a dictionary as JSON or written using the Python msgpack module (pickle is deprecated).
A JSON file may optionally be compressed with zlib. More details on the response can be found under responses schema in open-api spec or same can be found in redoc as well.
To enable HTTPS:
In the case of the server using public certificates, simply enable https.
1from cuopt_sh_client import CuOptServiceSelfHostClient 2 3data = {"cost_matrix_data": {"data": {"0": [[0,1],[1,0]]}}, 4 "task_data": {"task_locations": [0,1]}, 5 "fleet_data": {"vehicle_locations": [[0,0],[0,0]]}} 6 7# If cuOpt is not running on localhost:5000, edit ip and port parameters 8cuopt_service_client = CuOptServiceSelfHostClient( 9 ip="localhost", 10 port=5000, 11 use_https=True 12)
In the case of a self-signed certificate, provide the complete path to the certificate.
1from cuopt_sh_client import CuOptServiceSelfHostClient 2 3data = {"cost_matrix_data": {"data": {"0": [[0,1],[1,0]]}}, 4 "task_data": {"task_locations": [0,1]}, 5 "fleet_data": {"vehicle_locations": [[0,0],[0,0]]}} 6 7# If cuOpt is not running on localhost:5000, edit ip and port parameters 8cuopt_service_client = CuOptServiceSelfHostClient( 9 ip="localhost", 10 port=5000, 11 use_https=True, 12 self_signed_cert=/complete/path/to/certificate 13)
You can generate self signed certificate easily as follows,
openssl genrsa -out ca.key 2048 openssl req -new -x509 -days 365 -key ca.key -subj "/C=CN/ST=GD/L=SZ/O=Acme, Inc./CN=Acme Root CA" -out ca.crt openssl req -newkey rsa:2048 -nodes -keyout server.key -subj "/C=CN/ST=GD/L=SZ/O=Acme, Inc./CN=*.example.com" -out server.csr openssl x509 -req -extfile <(printf "subjectAltName=DNS:example.com,DNS:www.example.com") -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
server.crt
andserver.key
are meant for server,ca.crt
is meant for client.
LP Example#
Note
Linear Programming (LP) and Mixed Integer Linear Programming (MILP) is an Early Access feature and is currently open to only select customers.
1from cuopt_sh_client import CuOptServiceSelfHostClient
2import json
3
4data = {
5 "csr_constraint_matrix": {
6 "offsets": [0, 2, 4],
7 "indices": [0, 1, 0, 1],
8 "values": [3.0, 4.0, 2.7, 10.1]
9 },
10 "constraint_bounds": {
11 "upper_bounds": [5.4, 4.9],
12 "lower_bounds": ["ninf", "ninf"]
13 },
14 "objective_data": {
15 "coefficients": [0.2, 0.1],
16 "scalability_factor": 1.0,
17 "offset": 0.0
18 },
19 "variable_bounds": {
20 "upper_bounds": ["inf", "inf"],
21 "lower_bounds": [0.0, 0.0]
22 },
23 "maximize": False,
24 "solver_config": {
25 "tolerances": {
26 "optimality": 0.0001
27 }
28 }
29}
30
31# If cuOpt is not running on localhost:5000, edit ip and port parameters
32cuopt_service_client = CuOptServiceSelfHostClient(
33 ip="localhost",
34 port=5000
35)
36
37solution = cuopt_service_client.get_LP_solve(data, response_type="dict")
38
39
40print("---------- Normal mode --------------- \n", json.dumps(solution, indent=4))
41
42# For batch mode send list of mps/dict/DataModel
43
44solution = cuopt_service_client.get_LP_solve([data, data], response_type="dict")
45
46print("---------- Batch mode ----------------- \n", json.dumps(solution, indent=4))
response would be as follows,
Normal mode response:
1{
2"response": {
3 "solver_response": {
4 "status": 1,
5 "solution": {
6 "primal_solution": [
7 0.0,
8 0.0
9 ],
10 "dual_solution": [
11 0.0,
12 0.0
13 ],
14 "primal_objective": 0.0,
15 "dual_objective": 0.0,
16 "solver_time": 38.0,
17 "vars": {},
18 "lp_statistics": {
19 "primal_residual": 0.0,
20 "dual_residual": 0.0,
21 "gap": 0.0,
22 "reduced_cost": [
23 0.2,
24 0.1
25 ]
26 }
27 }
28 }
29},
30"reqId": "39c52105-736d-4383-a101-707390937141"
31}
Batch mode response:
1{
2"response": {
3 "solver_response": [
4 {
5 "status": 1,
6 "solution": {
7 "primal_solution": [
8 0.0,
9 0.0
10 ],
11 "dual_solution": [
12 0.0,
13 0.0
14 ],
15 "primal_objective": 0.0,
16 "dual_objective": 0.0,
17 "solver_time": 5.0,
18 "vars": {},
19 "lp_statistics": {
20 "primal_residual": 0.0,
21 "dual_residual": 0.0,
22 "gap": 0.0,
23 "reduced_cost": [
24 0.2,
25 0.1
26 ]
27 }
28 }
29 },
30 {
31 "status": 1,
32 "solution": {
33 "primal_solution": [
34 0.0,
35 0.0
36 ],
37 "dual_solution": [
38 0.0,
39 0.0
40 ],
41 "primal_objective": 0.0,
42 "dual_objective": 0.0,
43 "solver_time": 3.0,
44 "vars": {},
45 "lp_statistics": {
46 "primal_residual": 0.0,
47 "dual_residual": 0.0,
48 "gap": 0.0,
49 "reduced_cost": [
50 0.2,
51 0.1
52 ]
53 }
54 }
55 }
56 ],
57 "total_solve_time": 9.0
58},
59"reqId": "f04a6936-830e-4235-b535-68ad51736ac0"
60}
Example with DataModel is available in the LP example notebook
The data
argument to get_LP_solve
may be a dictionary of the format shown in LP Open-API spec. More details on the response can be found under responses schema in open-api spec or same can be found in redoc as well.
MILP Example#
Note
Linear Programming (LP) and Mixed Integer Linear Programming (MILP) are Early Access features and are currently open to only select customers.
The major difference between this example and the prior LP example is that some of the variables are integers, so variable_types
need to be shared.
1from cuopt_sh_client import CuOptServiceSelfHostClient
2import json
3
4data = {
5 "csr_constraint_matrix": {
6 "offsets": [0, 2],
7 "indices": [0, 1],
8 "values": [1.0, 1.0]
9 },
10 "constraint_bounds": {
11 "upper_bounds": [5000.0],
12 "lower_bounds": [0.0]
13 },
14 "objective_data": {
15 "coefficients": [1.2, 1.7],
16 "scalability_factor": 1.0,
17 "offset": 0.0
18 },
19 "variable_bounds": {
20 "upper_bounds": [3000.0, 5000.0],
21 "lower_bounds": [0.0, 0.0]
22 },
23 "maximize": True,
24 "variable_names": ["x", "y"],
25 "variable_types": ["I", "I"],
26 "solver_config":{
27 "time_limit": 30,
28 "tolerances": {
29 "optimality": 0.0001
30 }
31 }
32}
33
34# If cuOpt is not running on localhost:5000, edit ip and port parameters
35cuopt_service_client = CuOptServiceSelfHostClient(
36 ip="localhost",
37 port=5000
38)
39
40solution = cuopt_service_client.get_LP_solve(data, response_type="dict")
41
42print(json.dumps(solution, indent=4))
response would be as follows,
1{
2"response": {
3 "solver_response": {
4 "status": 1,
5 "solution": {
6 "primal_solution": [
7 0.0,
8 0.0
9 ],
10 "dual_solution": [
11 0.0
12 ],
13 "primal_objective": 0.0,
14 "dual_objective": 0.0,
15 "solver_time": 0.0,
16 "vars": {
17 "x": 0.0,
18 "y": 0.0
19 },
20 "lp_statistics": {
21 "primal_residual": 0.0,
22 "dual_residual": 0.0,
23 "gap": 0.0,
24 "reduced_cost": [
25 0.0,
26 0.0
27 ]
28 }
29 }
30 }
31},
32"reqId": "97e61936-e503-423b-b932-709cfac56424"
33}
An example with DataModel is available in the MILP example notebook.
The data
argument to get_LP_solve
may be a dictionary of the format shown in LP Open-API spec. More details on the response can be found under responses schema in open-api spec or same can be found in redoc as well.
The can be of different format as well, please check the documentation.
Aborting a Running Job In Thin Client#
Note
This is only supported in self-hosted
1from cuopt_sh_client import CuOptServiceSelfHostClient
2
3# This is an UUID that is returned by the solver while the solver is trying to find solution so users can come back and check the status or query for results.
4job_uuid = "<UUID_THAT_WE_GOT>"
5
6# If cuOpt is not running on localhost:5000, edit ip and port parameters
7 cuopt_service_client = CuOptServiceSelfHostClient(
8 ip="localhost",
9 port=5000
10 )
11
12 # Delete the job if it is still queued or running
13 response = cuopt_service_client.delete(uuid, running=True, queued=True, cached=False)
14
15 print(response.json())
cuOpt Self-Hosted Thin Client CLI Example#
Create a data.json
file containing this sample data:
Routing Example#
echo '{"cost_matrix_data": {"data": {"0": [[0, 1], [1, 0]]}},
"task_data": {"task_locations": [0, 1]},
"fleet_data": {"vehicle_locations": [[0, 0], [0, 0]]}}' > data.json
Invoke the CLI.
# client's default ip address for cuOpt is localhost:5000 if ip/port are not specified
cuopt_sh data.json -i ip -p port
To enable HTTPS:
In the case of the server using public certificates, simply enable https.
cuopt_sh data.json -s -i ip -p port
In the case of a self-signed certificate, provide the complete path to the certificate.
cuopt_sh data.json -s -c /complete/path/to/certificate -i ip -p port
LP Example#
Note
Linear Programming (LP) and Mixed Integer Linear Programming (MILP) are Early Access features and are currently open to only select customers.
echo '{
"csr_constraint_matrix": {
"offsets": [0, 2, 4],
"indices": [0, 1, 0, 1],
"values": [3.0, 4.0, 2.7, 10.1]
},
"constraint_bounds": {
"upper_bounds": [5.4, 4.9],
"lower_bounds": ["ninf", "ninf"]
},
"objective_data": {
"coefficients": [0.2, 0.1],
"scalability_factor": 1.0,
"offset": 0.0
},
"variable_bounds": {
"upper_bounds": ["inf", "inf"],
"lower_bounds": [0.0, 0.0]
},
"maximize": "False",
"solver_config": {
"tolerances": {
"optimality": 0.0001
}
}
}' > data.json
Invoke the CLI.
cuopt_sh data.json -t LP -i ip -p port
In the case of batch mode, you can send a bunch of mps
files at once, and acquire results. The batch mode works only for mps
in the case of CLI.
Note
Batch mode is not available for MILP problems.
echo "* optimize
* cost = 0.2 * VAR1 + 0.1 * VAR2
* subject to
* 3 * VAR1 + 4 * VAR2 <= 5.4
* 2.7 * VAR1 + 10.1 * VAR2 <= 4.9
NAME good-1
ROWS
N COST
L ROW1
L ROW2
COLUMNS
VAR1 COST 0.2
VAR1 ROW1 3 ROW2 2.7
VAR2 COST 0.1
VAR2 ROW1 4 ROW2 10.1
RHS
RHS1 ROW1 5.4 ROW2 4.9
ENDATA" > sample.mps
cuopt_sh sample.mps sample.mps sample.mps -t LP -i ip -p port
MILP Example#
The only difference between this example and the prior LP example would be the variable types provided in data.
Note
Linear Programming (LP) and Mixed Integer Linear Programming (MILP) are Early Access features and are currently open to only select customers.
echo '{
"csr_constraint_matrix": {
"offsets": [0, 2, 4],
"indices": [0, 1, 0, 1],
"values": [3.0, 4.0, 2.7, 10.1]
},
"constraint_bounds": {
"upper_bounds": [5.4, 4.9],
"lower_bounds": ["ninf", "ninf"]
},
"objective_data": {
"coefficients": [0.2, 0.1],
"scalability_factor": 1.0,
"offset": 0.0
},
"variable_bounds": {
"upper_bounds": ["inf", "inf"],
"lower_bounds": [0.0, 0.0]
},
"variable_names": ["x", "y"],
"variable_types": ["I", "I"],
"maximize": "False",
"solver_config": {
"time_limit": 30,
"tolerances": {
"optimality": 0.0001
}
}
}' > data.json
Invoke the CLI:
cuopt_sh data.json -t LP -i ip -p port
Note
Batch mode is not supported for MILP.
Aborting a Running Job In CLI#
Note
This is only supported in self-hosted
UUID that is returned by the solver while the solver is trying to find solution so users can come back and check the status or query for results.
This aborts a job with UUID if it’s in running state.
cuopt_sh -d -r -q <UUID>