Skip to main content

Optimizations

|

The Optimization class is a core component of the Fleet Management SDK. An optimization represents a set of orders, vehicles, constraints, and other parameters that define a routing problem. Whenever an optimization operation - such as creating, updating, or reoptimizing - is performed, it returns a Request object. This object allows you to track the status and progress of the operation asynchronously. It includes details such as the request ID, creation time, associated entity, status, and any error messages. Once the request is completed, the resulting solution can be retrieved. For more information about request handling, see the end of this page.

The API allows users to:

  • Create new optimizations with orders, vehicles, and constraints.
  • Retrieve existing optimizations by ID or list all optimizations.
  • Update optimization parameters such as constraints or vehicles.
  • Delete optimizations when no longer needed.
  • Reoptimize existing optimizations to find better solutions.
  • Add or remove orders from an existing optimization.
  • Retrieve solutions for an optimization.

Optimization Structure

Each optimization object consists of the following attributes:

NameTypeDescriptionSetterGetter
IdLargeIntegerUnique identifier for the optimization, used for updates.
ConfigurationParametersConfigurationParametersConfiguration parameters for the optimization.
OrdersOrderListList of orders to be delivered or picked up during the optimization.
VehiclesVehicleListList of vehicles available for optimization.
VehiclesConstraintsVehicleConstraintsListConstraints that apply to the vehicles in the optimization.
If there are multiple vehicles, you can either set a single set of constraints that applies to all vehicles or apply different constraints for each vehicle.
DeparturesDepartureListList of departure points where the vehicles start their routes.
DestinationsDestinationListList of destinations where the vehicles finish their routes.
MatrixBuildTypeEMatrixBuildType

Defines the method used to construct the distance and time matrices for the optimization.
Possible values:
MBT_Set (0): Matrices are set by the user.
MBT_Real (1): Real road distance or time traveled by the vehicle.

DistanceMatricesstd::map<EVehicleType, FloatListList>Distance matrices for the optimization (used when matrixBuildType is MBT_Set).
A different distance matrix is ​​used for each vehicle type from optimization.
TimeMatricesstd::map<EVehicleType, IntListList>Time matrices for the optimization (used when matrixBuildType is MBT_Set).
A different time matrix is ​​used for each vehicle type from optimization.
CreationTimeTimeTime when the optimization was created (in Epoch format).

Managing Optimizations

Creating an Optimization

An optimization must be created before it can be solved. It defines the routing problem by including orders, vehicles, and constraints. To solve the optimization, the system initiates the process and returns a Request object. This object allows you to track the status of the optimization until the solution is ready.

Note

Adding an optimization returns a Request object, which allows you to track the status of the optimization process. Once the request status is finished, the solution can be retrieved using getSolution(). A route is the trip that a vehicle travels to visit the orders, so the number of routes returned is maximum the number of vehicles set in the optimization(see Routes). If in the optimization only one vehicle is used, then the solution will contain only one route.

How it works

  1. Create a vrp::OrderList and add the orders to it. Each order needs to have a customer set; you can either add a new customer and then set it to the order, or you can use a previously created customer (see Get Customer)
  2. Create a vrp::ConfigurationParameters and set the desired parameters.
  3. Create one vrp::VehicleConstraints for each vehicle and set them to a vrp::VehicleConstraintsList.
  4. Create a vrp::Optimization, set the desired fields and the objects created at 1.), 2.) and 3.) to it.
  5. Create a ProgressListener, vrp::Service, and a vrp::Request that will be used for traking the request status.
  6. Call the addOptimization() method from vrp::Service using the list from 5.), the vrp::Optimization from 4.) and the progress listener.
  7. After adding an optimization, check whether the associated request has reached the finished status. Once completed, you can retrieve the optimization results by calling the getSolution() method, which returns a vrp::RouteList containing the generated routes.

Example

// Initialize Service and Listener
ProgressListener listener;
gem::vrp::Service service;

// Initialize Customers
gem::vrp::Customer c0;
c0.setCoordinates(gem::Coordinates(48.234270, -2.133208));
c0.setAlias("c0");
c0.setPhoneNumber("+12312312");
c0.setEmail("c0@yahoo.com");
int ret = service.addCustomer(&listener, c0);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);

gem::vrp::Customer c1;
c1.setCoordinates(gem::Coordinates(45.854137, 2.853998));
c1.setAlias("c1");
c1.setEmail("c1@yahoo.com");
c1.setPhoneNumber("+12312312");
ret = service.addCustomer(&listener, c1);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);

gem::vrp::Customer c2(gem::Coordinates(46.199373, 0.069986));
c2.setAlias("c2");
c2.setPhoneNumber("+12312312");
c2.setEmail("c2@yahoo.com");
ret = service.addCustomer(&listener, c2);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);

// Initialize Orders
gem::vrp::OrderList orders;
gem::vrp::Order order0(c0);
order0.setNumberOfPackages(5);
order0.setWeight(15.7);
order0.setCube(0.2);
order0.setServiceTime(600);
order0.setTimeWindow(std::make_pair(gem::Time(1596783600000), gem::Time(1596870000000))); // August 7, 2020 7:00:00 AM - August 8, 20207:00:00 AM
order0.setType(gem::vrp::EOrderType::OT_PickUp);
ret = service.addOrder(&listener, order0, false);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);
orders.push_back(order0);

gem::vrp::Order order1(c1);
order1.setNumberOfPackages(4);
order1.setWeight(15.5);
order1.setCube(0.9);
order1.setTimeWindow(std::make_pair(gem::Time(1596783600000), gem::Time(1596870000000))); // August 7, 2020 7:00:00 AM - August 8, 20207:00:00 AM
order1.setType(gem::vrp::EOrderType::OT_PickUp);
ret = service.addOrder(&listener, order1, false);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);
orders.push_back(order1);

gem::vrp::Order order2(c2);
order2.setNumberOfPackages(8);
order2.setWeight(5.5);
order2.setCube(0.3);
order2.setServiceTime(600);
order2.setTimeWindow(std::make_pair(gem::Time(1596798000000), gem::Time(1596839600000))); // August 7, 2020 11:00:00 AM - 10:33:20 PM
order2.setType(gem::vrp::EOrderType::OT_Delivery);
ret = service.addOrder(&listener, order2, false);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);
orders.push_back(order2);

gem::vrp::Order order3(c3);
order3.setTimeWindow(std::make_pair(gem::Time(1596803600000), gem::Time(1596870000000))); // August 7, 2020 12:33:20 PM - August 8, 20207:00:00 AM
order3.setType(gem::vrp::EOrderType::OT_Delivery);
ret = service.addOrder(&listener, order3, false);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);
orders.push_back(order3);

// Initialize Configuration parameters
gem::vrp::ConfigurationParameters configParams;
configParams.setName("France optimization");
configParams.setIgnoreTimeWindow(false); // will not consider the time window for the order
configParams.setOptimizationCriterion(gem::vrp::EOptimizationCriterion::OC_Distance);
configParams.setOptimizationQuality(gem::vrp::EOptimizationQuality::OQ_Optimized);
configParams.setMaxWaitTime(18000); // A vehicle can wait maximum 5 hours between a order and the next one, in order to visit the nextone within its time window
configParams.setRouteType(gem::vrp::ERouteType::RT_CustomEnd);
configParams.setRestrictions(gem::vrp::ERoadRestrictions::RR_None);
configParams.setDistanceUnit(gem::vrp::EDistanceUnit::DU_Kilometers);

// Initialize Vehicles
gem::vrp::VehicleList vehicles;
gem::vrp::Vehicle vehicle1;
vehicle1.setName("Vehicle 1");
vehicle1.setType(gem::vrp::EVehicleType::VT_Car);
vehicle1.setStatus(gem::vrp::EVehicleStatus::VS_Available);
vehicle1.setManufacturer("Kia");
vehicle1.setModel("Ceed");
vehicle1.setFuelType(gem::vrp::EFuelType::FT_GasolinePremium);
vehicle1.setConsumption(6.5);
vehicle1.setLicensePlate("BV01ASD");
vehicle1.setMaxWeight(300);
vehicle1.setMaxCube(15);
vehicle1.setStartTime(420); // August 7, 2020 7:00:00 AM
vehicle1.setEndTime(420); // August 8, 2020 7:00:00 AM
int res = service.addVehicle(&listener, vehicle1);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);
vehicles.push_back(vehicle1);

// Initialize Vehicle constraints
gem::vrp::VehicleConstraintsList vehConstraintsList;
gem::vrp::VehicleConstraints vehConstr;
vehConstr.setMaxNumberOfPackages(100);
vehConstr.setMaxRevenue(2000);
vehConstr.setStartDate(gem::Time(2020, 8, 7)); // August 7, 2020
vehConstr.setEndDate(gem::Time(2020, 8, 8)); // August 8, 2020
vehConstr.setMinNumberOfOrders(1);
vehConstr.setMaxNumberOfOrders(50);
vehConstr.setMinDistance(1);
vehConstr.setMaxDistance(19000);
vehConstraintsList.push_back(vehConstr);
gem::vrp::Departure departure;
departure.setAlias("Depot 1");
departure.setCoordinates(gem::Coordinates(48.618893, -1.353635));
gem::vrp::Destination destination;
destination.setAlias("Destination");
destination.setCoordinates(gem::Coordinates(47.617484, 1.152466));

gem::vrp::Optimization optimization;
optimization.setConfigurationParameters(configParams);
optimization.setVehicles(vehicles);
optimization.setDepartures({departure});
optimization.setDestinations({destination});
optimization.setOrders(orders);
optimization.setVehiclesConstraints(vehConstraintsList);
optimization.setMatrixBuildType(gem::vrp::EMatrixBuildType::MBT_Real);

// Create an Optimization object and set its properties
gem::vrp::Optimization optimization;
optimization.setConfigurationParameters(configParams);
optimization.setOrders(orders);
optimization.setVehicles(vehicles);
optimization.setVehiclesConstraints(vehConstraintsList);
optimization.setDepartures(departures);
optimization.setDestinations(destinations);
optimization.setMatrixBuildType(gem::vrp::EMatrixBuildType::MBT_Real);

// Call the addOptimization method
std::shared_ptr<gem::vrp::Request> request = std::make_shared<gem::vrp::Request>();
int res = service.addOptimization(&listener, optimization, request);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 10000);

// Wait for completion
WAIT_UNTIL([&]() {
serv.getRequest(&listener, request, request->id);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 7000);
return request->status == gem::vrp::ERequestStatus::eFinished;
}, 40000);

// Check operation success
if (listener.IsFinished() && listener.GetError() == gem::KNoError && res == gem::KNoError) {
std::cout << "Optimization added successfully. ID: " << optimization.getId() << std::endl;
} else {
std::cout << "Optimization could not be added." << std::endl;
}

Retrieving the Solution for an Optimization

Returns the solution for an optimization. The result is a list of routes.

How it works

  1. Create a ProgressListener, a vrp::Service and a vrp::RouteList.
  2. Call the getSolutionForOptimization() method from the vrp::Service using the list from 1.), the ID of the optimization and the ProgressListener.
  3. Once the operation completes, the list from 1.) will be populated.

Example

ProgressListener listener;
gem::vrp::Service service;

// Retrieve the optimization for which you want to obtain the solution.
gem::vrp::Optimization optimization;
gem::LargeInteger optimizationId = 0; // Set your optimization id
int res = serv.getOptimization(&listener, optimization, optimizationId);
if (res == gem::KNoError)
{
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 20000);
if(listener.IsFinished() && listener.GetError() == gem::KNoError)
{
// Retrieve the solution for the optimization
gem::vrp::RouteList routes;
res = optimization.getSolution(&listener, routes);
if (res == gem::KNoError)
{
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);
if (listener.IsFinished() && listener.GetError() == gem::KNoError)
std::cout << "Solution returned successfully" << std::endl;
else
std::cout << "Failed to get solution for optimization: Operation timed out or server returned an error." << std::endl;
}
else
std::cout << "Failed to send getSolution request." << std::endl;
}
else
std::cout << "Failed to retrive optimization: Operation timed out or server returned an error." << std::endl;
}
else
std::cout << "Failed to send getOptimization request." << std::endl;

Retrieving Optimizations

There are two ways to retrieve optimization data:

a) Get an Optimization by ID

Get a certain optimization

How it works

  1. Create a ProgressListener, a vrp::Service and a vrp::Optimization.
  2. Call the getOptimization() method from the vrp::Service using the vrp::Optimization from 1.), the ID of the optimization that you want to retrieve and the ProgressListener.
  3. Once the operation completes, the vrp::Optimization from 1.) will be populated.
ProgressListener listener;
gem::vrp::Service service;

gem::vrp::Optimization optimization;
LargeInteger optimizationId = 0; // Set your optimization id

// Retrieve a specific optimization by id
int res = service.getOptimization(listener, optimization, optimizationId);
if (res == gem::KNoError)
{
// Wait for completion
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 10000);
// Check operation success
if (listener.IsFinished() && listener.GetError() == gem::KNoError)
std::cout << "Optimization retrieved successfully. ID: " << optimization.getId() << std::endl;
else
std::cout << "Failed to retrive optimization: Operation timed out or server returned an error." << std::endl;
}
else
std::cout << "Failed to send getOptimization request." << std::endl;

b) Get All Optimizations (with optional filtering)

Returns all optimizations of the API user (which contain the search term).

How it works

  1. Create a ProgressListener, a vrp::Service and a vrp::OptimizationList.
  2. Call the getOptimizations() method from the vrp::Service using the list from 1.) and the ProgressListener.
  3. Once the operation completes, the list from 1.) will be populated.
// Retrieve all optimizations
ProgressListener listener;
gem::vrp::Service service;

gem::vrp::OptimizationList optimizations;
gem::String searchTerm = "Optimization";
// Retrieve all routes
int res = service.getOptimizations(listener, optimizations, searchTerm);
if (res == gem::KNoError)
{
// Wait for completion
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);

// Check operation success
if (listener.IsFinished() && listener.GetError() == gem::KNoError && res == gem::KNoError)
std::cout << "optimizations retrieved successfully." << std::endl;
else
std::cout << "Failed to retrive optimizations: Operation timed out or server returned an error." << std::endl;
}
else
std::cout << "Failed to send getOptimizations request." << std::endl;

Updating an Optimization

Makes changes to an optimization and triggers a reoptimization. The updated solution can be retrieved using getSolution() once the request status is Finished.

Note

Orders within an optimization cannot be updated directly using UpdateOptimization(). However, all other fields in the optimization can be modified using this method.

To modify orders, refer to the following examples:

Once the optimization is updated, it will be reoptimized. The reoptimized solution can be retrieved using getSolution() once the request status is Finished.

How it works

  1. Create a ProgressListener and a vrp::Service.
  2. Retrieve the optimization you want to update (see Get Optimization) in a vrp::Optimization.
  3. Change the desired fields of the vrp::Optimization.
  4. Create a vrp::RouteList, and a vrp::Request that will be use for traking the status of the operation.
  5. Call the updateOptimization() method from the vrp::Service using the list from 4.), the vrp::Optimization from 2.), the optimization will be reoptimized.
  6. Check if the associated request has reached the finished status. Once completed, you can retrieve the optimization results by calling the getSolution() method, which returns a vrp::RouteList containing the reoptimized routes.

Example

// Retrieve an existing optimization by id
ProgressListener listener;
gem::vrp::Service service;

gem::vrp::Optimization optimization;
LargeInteger optimizationId = 0; // Set your optimization id
int res = service.getOptimization(listener, optimization, optimizationId);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 20000);

// Change configuration parameters
gem::vrp::ConfigurationParameters configParams = optimization.getConfigurationParameters();
configParams.setName(configParams.getName() + " updated");
configParams.setRouteType(gem::vrp::ERouteType::RT_EndAnywhere);
configParams.setIgnoreTimeWindow(true);
configParams.setDistanceUnit(gem::vrp::EDistanceUnit::DU_Miles);

// Update optimization properties
optimization.setConfigurationParameters(configParams);

std::shared_ptr<gem::vrp::Request> request = std::make_shared<gem::vrp::Request>();
res = service.updateOptimization(&listener, optimization, request);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 10000);

WAIT_UNTIL([&]() {
service.getRequest(&listener, request, request->id);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 7000);
return request->status == gem::vrp::ERequestStatus::eFinished;
}, 40000);
gem::vrp::RouteList routes;
res = optimization.getSolution(&listener, routes);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 10000);
if (listener.IsFinished() && listener.GetError() == gem::KNoError && res == gem::KNoError)
std::cout << "Optimization updated successfully" << std::endl;
else
std::cout << "Optimization couldn't be updated" << std::endl;

Deleting an Optimization

Delete the optimizations for the user. Optimizations can be deleted individually or in bulk.

Note

When an optimization is deleted, the routes assigned to that optimization are also deleted.

How it works

  1. Create a ProgressListener and vrp::Service.
  2. Call the deleteOptimization() method from the vrp::Service using the optimization's id and ProgressListener and wait for the operation to be done.

Example

ProgressListener listener;
gem::vrp::Service service;

// Remove multiple optimizations by IDs
LargeIntList optimizationsToDelete = {101, 202, 303};
int res = service.deleteOptimization(listener, optimizationsToDelete);

if (res == gem::KNoError)
{
// Wait for completion
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);

// Check operation success
if (listener.IsFinished() && listener.GetError() == gem::KNoError && res == gem::KNoError)
std::cout << "Optimizations deleted successfully." << std::endl;
else
std::cout << "Failed to delete optimization: Operation timed out or server returned an error." << std::endl;
}
else
std::cout << "Failed to send deleteOptimization request." << std::endl;

Reoptimizing an Optimization

Creates a new and better solution (if exists) for the optimization. The latest fuel prices are used for the new solution (see Get Fuel Prices).

How it works

  1. Create a ProgressListener, a vrp::Service a vrp::RouteList and a vrp::Request.
  2. Call the reoptimizeOptimization() method from the vrp::Service using the vrp::RouteList from 1.), the ID of the optimization that you will be reoptimized and the ProgressListener.
  3. Check if the associated request has reached the finished status. Once completed, you can retrieve the optimization results by calling the getSolution() method, which returns a vrp::RouteList containing the reoptimized routes.

Example

ProgressListener listener;
gem::vrp::Service service;
gem::vrp::Optimization optimization;
gem::LargeInteger optimizationId = 0; // Set your optimization id

// Retrive a specific optimization by id
int res = service.getOptimization(&listener, optimization, optimizationId);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 20000);

// Reoptimize an existing optimization
std::shared_ptr<gem::vrp::Request> request = std::make_shared<gem::vrp::Request>();
res = optimization.reoptimize(&listener, request);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 20000);

WAIT_UNTIL([&]() {
service.getRequest(&listener, request, request->id);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 7000);
return request->status == gem::vrp::ERequestStatus::eFinished;
}, 40000);

// Take the new solution
gem::vrp::RouteList routes;
res = optimization.getSolution(&listener, routes);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 10000);
if (listener.IsFinished() && listener.GetError() == gem::KNoError && res == gem::KNoError)
std::cout << "Optimization reoptimized successfully" << std::endl;
else
std::cout << "Optimization couldn't be reoptimized" << std::endl;

Adding Orders to an Optimization

Add orders to the optimization. The orders will be added at the end of the existing optimization's orders list. If the optimization is also reoptimized, the added orders will be assigned to the optimization's routes.

How it works

  1. Create a vrp::Order with the desired fields for each order that will be added and insert them in a vrp::OrderList.
  2. Create a ProgressListener and vrp::Service.
  3. Retrieve the optimization like in the example GetOptimization() in a vrp::Optimization.
  4. Call the optimization.addOrders() method from vrp::Optimization using the list from 1.), a boolean to specify if the optimization should be reoptimized and the ProgressListener.
  5. Check if the associated request has reached the finished status. Once completed, you can retrieve the optimization results by calling the getSolution() method, which returns a vrp::RouteList containing the generated routes.

Example

ProgressListener listener;
gem::vrp::Service service;
gem::vrp::Optimization optimization;
gem::LargeInteger optimizationId = 0; // Set your optimization id
int ret = service.getOptimization(&listener, optimization, optimizationId);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 20000);

// Initialize customers
gem::vrp::Customer c1;
c1.setCoordinates(gem::Coordinates(47.016075, -0.849623));
c1.setAlias("c1");
c1.setPhoneNumber("+12312312");
c1.setEmail("c1@yahoo.com");
ret = service.addCustomer(&listener, c1);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);

gem::vrp::Customer c2(gem::Coordinates(45.212821, 3.166858));
c2.setAlias("c2");
c2.setPhoneNumber("+12312312");
c2.setEmail("c2@yahoo.com");
ret = service.addCustomer(&listener, c2);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);

// Initialize orders that will be added
gem::vrp::OrderList ordersToAdd;
gem::vrp::Order orderToAdd1(c1);
orderToAdd1.setNumberOfPackages(5);
orderToAdd1.setServiceTime(600);
orderToAdd1.setType(gem::vrp::EOrderType::OT_PickUp);
ret = service.addOrder(&listener, orderToAdd1, false);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);
ordersToAdd.push_back(orderToAdd1);

gem::vrp::Order orderToAdd2(c2);
orderToAdd2.setNumberOfPackages(4);
orderToAdd2.setType(gem::vrp::EOrderType::OT_Delivery);
ret = service.addOrder(&listener, orderToAdd2, false);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);
ordersToAdd.push_back(orderToAdd2);

bool reoptimize = true;// Set reoptimize to true, which means that a new solution will be computed with new orders included.

// Add new orders to an optimization
std::shared_ptr<gem::vrp::Request> request = std::make_shared<gem::vrp::Request>();
ret = optimization.addOrders(&listener, ordersToAdd, request, reoptimize);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 10000);
WAIT_UNTIL([&]() {
service.getRequest(&listener, request, request->id);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 7000);
return request->status == gem::vrp::ERequestStatus::eFinished;
}, 40000);
if (listener.IsFinished() && listener.GetError() == gem::KNoError && ret == gem::KNoError)
std::cout << "Orders added successfully" << std::endl;
else
std::cout << "Orders couldn't be added or the optimization couldn't be reoptimized" << std::endl;

Updating an Order from an Optimization

Update an order from an existing optimization.

Note

These changes will also be seen in the route orders for the routes involved in the optimization. So when you want to update a route order you can use this method.

How it works

  1. Create a ProgressListener and a vrp::Service.
  2. Retrieve the optimization like in the example GetOptimization() in a vrp::Optimization.
  3. Create a vrp::Order and initialize it with the optimization order that you want to update.
  4. Make the desired changes on the vrp::Order from 3.).
  5. Call the optimization.updateOrder() method from the vrp::Optimization from 2.) using the vrp::Order from 3.) and the ProgressListener.
  6. Once the operation completes, the vrp::Optimization from 2.) will contain the new optimization with the order updated.

Example

ProgressListener listener;
gem::vrp::Service service;

gem::vrp::Optimization optimization;
gem::LargeInteger optimizationId = 0; // Set your optimization

// Retrieve a specific optimization by id
int res = service.getOptimization(listener, optimization, optimizationId);
if (res == gem::KNoError)
{
// Wait for completion
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 10000);
// Check operation success
if (listener.IsFinished() && listener.GetError() == gem::KNoError)
{
if (optimization.getOrders().size() > 2)// Check if the optimization has at least two orders to avoid going out of range
{
// Update the order 2 from the optimization
gem::vrp::Order order = optimization.getOrders().at(2);
order.setNumberOfPackages(3);
order.setServiceTime(360);
res = optimization.updateOrder(&listener, order);
if (res == gem::KNoError)
{
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);
if (listener.IsFinished() && listener.GetError() == gem::KNoError)
std::cout << "Order updated successfully" << std::endl;
else
std::cout << "Failed to update order: Operation timed out or server returned an error." << std::endl;
}
else
std::cout << "Failed to send updateOrder request." << std::endl;
}
else
std::cout << "The optimization hasn't at least two orders" << std::endl;
}
else
std::cout << "Failed to retrive optimization: Operation timed out or server returned an error." << std::endl;
}
else
std::cout << "Failed to send getOptimization request." << std::endl;

Deleting an Order from an Optimization

Delete an order from an existing optimization. It will not appear in the Route as well.

Note

A route must contain at least two orders for one to be deleted. If the order you want to delete is the only one in the route, it cannot be deleted.

How it works

  1. Create a ProgressListener and a vrp::Service.
  2. Retrieve the optimization like in the example GetOptimization() in a vrp::Optimization.
  3. Create a vrp::Order and initialize it with the order that you want to delete.
  4. Call the deleteOrder() method from vrp::Optimization from 2.) using the vrp::Order from 3.) and the ProgressListener.
  5. Once the operation completes, the new optimization will be returned in the vrp::Optimization from 2.).

Example

ProgressListener listener;
gem::vrp::Service service;
gem::LargeInteger optimizationId = 0; // Set your optimization id
gem::vrp::Optimization optimization;

// Retrieve a specific optimization by id
int res = service.getOptimization(&listener, optimization, optimizationId);
if (res == gem::KNoError)
{
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 20000);
if (listener.IsFinished() && listener.GetError() == gem::KNoError)
{
if (optimization.getOrders().size() > 4)// Check if the optimization has at least four orders to avoid going out of range
{
//Delete the fourth order of the optimization
gem::vrp::Order order = optimization.getOrders().at(4);
res = optimization.deleteOrder(&listener, order);
if (res == gem::KNoError)
{
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);
if (listener.IsFinished() && listener.GetError() == gem::KNoError)
std::cout << "Order deleted successfully" << std::endl;
else
std::cout << "Failed to deleted order: Operation timed out or server returned an error." << std::endl;
}
else
std::cout << "Failed to send deleteOrder request." << std::endl;
}
else
std::cout << "The optimization hasn't at least four orders" << std::endl;
}
else
std::cout << "Failed to retrive optimization: Operation timed out or server returned an error." << std::endl;
}
else
std::cout << "Failed to send getOptimization request." << std::endl;

Error Handling

The API provides specific error codes to identify potential issues. Below is a summary of common errors and their solutions:

| Error Code | Description | Solution | ||-|-| | KInvalidInput | Missing required fields or invalid data. | Ensure all mandatory fields are filled. You can check the error message in the request to see more details. | | KNotFound | The specified optimization ID does not exist.| Verify that the correct optimization ID is used. | | KInternalAbort | Server-side issue or unexpected error. | Retry the request or check API status. | | KNoRoute | Optimization could not be solved. | Check constraints and parameters. |

Request Handling

Optimization operations such as addOptimization, updateOptimization, and reoptimize return a Request object. This object allows you to track the status of the operation.

Request Structure

NameTypeDescriptionSetterGetter
RequestIdLargeIntegerUnique identifier for the request.
CreationTimeLargeIntegerThe time when the request was created.
EntityIdLargeIntegerThe ID of the entity (e.g., optimization) associated with the request.
StatusERequestStatusThe current status of the request (e.g., Created, In Progress, Finished).
ErrorMessagestd::stringA message describing any errors that occurred during processing.

Example of Tracking a Request

// Retrieve the status of a request
std::shared_ptr<gem::vrp::Request> request = std::make_shared<gem::vrp::Request>();
int res = service.getRequest(listener, request, requestId);

if (res == gem::KNoError)
{
// Wait for completion
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);

// Check operation success
if (listener.IsFinished() && listener.GetError() == gem::KNoError && res == gem::KNoError)
std::cout << "Request status: " << request->status << std::endl;
else
std::cout << "Failed to retrive request: Operation timed out or server returned an error." << std::endl;
}
else
std::cout << "Failed to send getRequest request." << std::endl;