Skip to main content

Add Orders to a Route

|

This example demonstrates how to add a list of orders into an existing route's order list at optimal positions determined by the algorithm. The orders will be inserted between existing route orders without rearranging them. If the route is reoptimized, the orders will be rearranged in the best order of visit, and you may not see them inserted at the original optimal positions.

The added orders will also be included in the optimization's order list.

When you run the example application:

  • The existing route will be updated with new orders.
  • The orders will be inserted at the best possible positions without altering the current order sequence.
  • If reoptimization is enabled, the entire route will be rearranged for optimal efficiency.

Retrieve Customers

To create an order we can use an existing customer to assign the order to, or we can create a new one. In this example we will use two customers already existing in the database.

  1. Create a ProgressListener and vrp::Service.
  2. Retrieve the customers using the getCustomer() method from the vrp::Service.
    ProgressListener listener;
gem::vrp::Service serv;

// Retrieve customer 1
gem::vrp::Customer customer1;
gem::LargeInteger customerId1 = 0; // Set your customer ID
int res = serv.getCustomer(&listener, customer1, customerId1);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);

// Retrieve customer 2
gem::vrp::Customer customer2;
gem::LargeInteger customerId2 = 0; // Set your customer ID
res = serv.getCustomer(&listener, customer2, customerId2);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);

Create Orders

  1. Create two vrp::Order objects associated with the customers retrieved earlier.
  2. Set necessary attributes such as the number of packages, service time, and order type.
  3. Use the addOrder() method from vrp::Service to add the orders.

Create orders for the retrieved customers.

    gem::vrp::RouteOrderList ordersToAdd;
gem::vrp::RouteOrder orderToAdd1(customer1);
orderToAdd1.setCoordinates(gem::Coordinates(45.770944, 2.067794));
orderToAdd1.setNumberOfPackages(6);
orderToAdd1.setWeight(0.5);
orderToAdd1.setServiceTime(360);
orderToAdd1.setTimeWindow(std::make_pair(gem::Time(2021, 5, 18, 11), gem::Time(2021, 5, 18, 15)));
orderToAdd1.setType(gem::vrp::EOrderType::OT_PickUp);
res = serv.addOrder(&listener, orderToAdd1, false);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);
ordersToAdd.push_back(orderToAdd1);

gem::vrp::RouteOrder orderToAdd2(customer2);
orderToAdd2.setCoordinates(gem::Coordinates(47.681092, 3.547602));
orderToAdd2.setNumberOfPackages(3);
orderToAdd2.setWeight(0.3);
orderToAdd2.setTimeWindow(std::make_pair(gem::Time(2021, 5, 18, 9, 45), gem::Time(2021, 5, 18, 14, 30)));
orderToAdd2.setServiceTime(180);
orderToAdd2.setType(gem::vrp::EOrderType::OT_Delivery);
res = serv.addOrder(&listener, orderToAdd2, false);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 5000);
ordersToAdd.push_back(orderToAdd2);

Retrieve the existing Route

To add orders to an route, you have to retrieve that route by id.

  1. Retrieve the route using the getRoute() method from the vrp::Service.
    gem::vrp::Route route;
gem::LargeInteger routeId = 0; // Set your route ID
res = serv.getRoute(&listener, route, routeId);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 10000);

Add Orders to the Route

Once the orders are created, they need to be added to the route.

  1. Create a std::shared_ptr<gem::vrp::Request> to hold the request.
  2. Call the addOrders() method from vrp::Route.
  3. Wait for the operation to complete.
    bool reoptimize = true;
bool addAtOptimalPosition = true;
std::shared_ptr<gem::vrp::Request> request = std::make_shared<gem::vrp::Request>();
res = route.addOrders(&listener, ordersToAdd, addAtOptimalPosition, request, reoptimize);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 10000);

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

// Once the operation is complete, check if the update was successful.
if (listener.IsFinished() && listener.GetError() == gem::KNoError && res == gem::KNoError)
std::cout << "Orders added successfully" << std::endl;
else
std::cout << "Failed to add orders" << std::endl;