Skip to main content

Distribution of goods from a single DC to mulitple stores for FMCG customers

This model is often referred to as "Multi-Stop Delivery" and is commonly used in FMCG due to the need for frequent replenishment of goods at stores to meet consumer demand.

Here's how it works in FMCG logistics:

  • Route Planning: A predetermined route is established before the operations, including multiple supplier locations or retail stores.  
  • Consolidation: Goods from various suppliers are collected and consolidated onto a single vehicle.  
  • Delivery: The vehicle delivers the consolidated goods to a central warehouse, distribution center, or directly to retail stores.  

Key Characteristics:

  • Single DC: All orders originate from a single distribution center, streamlining inventory management and order consolidation.
  • Multiple Stores: Orders are delivered to various stores within a defined geographical region.
  • One Trip per Day: Each delivery vehicle is scheduled for a single trip per day, optimizing vehicle utilization and driver schedules.
  • Multiple Stops: The vehicle makes multiple stops at different stores during its trip, maximizing efficiency by consolidating deliveries.

Scenario

The goods are distributed from a single distribution center every morning by a predefined fleet of vehicles. The vehicles have different types with difference available capacity. All orders from the stores are available before the opening of the distribution center and are not changing during operations. Delivery orders have predefined, known delivery address and WGS84 coordinates, as well as known required capacity from the vehicle. The goal is to minimize travel distance and the number br of vehicles required to execute the orders.

tip

This section does not cover configuring the initial project or simulation template, as this is typically performed by the SWAT team. However, a reference for the process is available here.

Daily operations

Once the project and default simulation has been configured, daily operations can be started for route optimization. To achieve that, for each a new simulation needs to be created, then orders should be uploaded, and route optimization process should be executed.

Sequence diagram

Creating a new instance of simulation for a single or multiple days of operations based on template

When a simulation is created with a template, all necessary parameters are cloned from the template, including simulation settings, and vehicles are created for this simulation. The create simulation response will include identifier of the new simulation.

tip

If required, parameters of the simulation can be updated using PATCH request for either simulation object parameters, or vehicles parameters. In this case, the default simulation and the vehicles attached to the default simulation will not be affected.

Create default simulation from template
POST /api/v2/microservices/simulation_template_instance
See JSON payload
Create simulation from template
POST /api/v2/microservices/simulation_template_instance

{
{
"project_id": 1,
"start_time": "2021-01-10T00:00:00+00:00",
"end_time": "2021-01-10T23:59:00+00:00"
}
}

tip

Multiple simulations can be created via single request by using the following example

See JSON payload
Create simulation from template
POST /api/v2/microservices/simulation_template_instance

{
"project_id": 1,
"template_id": 2,
"start_times": ["2021-01-02T00:00:00+08:00", "2021-01-03T00:00:00+08:00"]
}

Upload orders (bookings)

tip

Be aware of the capacities and vehicle characteristics provided in the payload. For example, vehicle model 4W has a capacity defined as 2,000 arbitrary weight units and 7,000,000 cubic centimeters. The consuming application can specify any capacity it requires in the form of arbitrary <string><number> pairs. When bookings are created, the optimizer will use these capacity names to solve the capacitated routing problem.

Now once simulation has been created with all vehicles copied from the template, relevant orders(bookings) can be uploaded. For this use case, upload should be done using

Upload bookings into the simulation
POST /api/v2/microservices/logisticsapi
See JSON payload
Upload orders (bookings) into the simulation
POST /api/v2/microservices/logisticsapi
{
"calculation_uid": "e33e7240-96ba-4c4a-b958-f903eca9b422",
"simulation_id": 1,
"bookings": [
{
"uid": "a87fdfe8-29c6-4483-8fcd-49448362473d",
"pickup_postal_code": "1",
"pickup_location_name": "Pickup name",
"dropoff_postal_code": "2",
"dropoff_location_name": "Dropoff name",
"pickup_location_lat": null,
"pickup_location_lon": null,
"dropoff_location_lat": null,
"dropoff_location_lon": null,
"min_pickup_time": "2021-08-17T08:59:10.073329+00:00",
"max_pickup_time": "2021-08-17T09:14:10.073329+00:00",
"min_dropoff_time": "2021-08-17T08:59:10.073329+00:00",
"max_dropoff_time": "2021-08-17T09:59:10.073329+00:00",
"demand": {
"volume": 1
},
"data": {
"some": "thing",
"number": 1
},
"pickup_service_time": 0,
"dropoff_service_time": 0,
"groups": []
}
],
"upload_strategy": "clear_all",
"optimization_settings": {
"vehicle_cost": null,
"trip_cost": null,
"time_limit_ms": null,
"first_solution_strategies": null,
"max_pickup_slack": null,
"max_dropoff_slack": null,
"mutually_exclusive_groups": null,
"use_local_search_metaheuristic": null,
"allow_upload_after_simulation_start_time": null
},
"vehicles_filter_expression": null,
"vehicle_selection_by_emptiness": false,
"vehicle_selection_in_service": false
}

The request will return a list of orders (bookings) IDs that have been added to the system.

Execute optimization for the simulation

Once bookings have been uploaded, the routes can be generated for that simulation. To achieve this, the following request needs to be issued. The request will trigger the calculation and will return identifier of an internal process that can be used to track calculation progress, as well as a list of booking_id that reflects internal identifier bookings to be used in the calculation.

tip

Optimization process can take a long time depending on the settings, a number of bookings and a number of vehicles. Therefore, optimization request is asynchronous and a consumer needs to poll and wait until the optimization run is completed.

Upload bookings into the simulation
POST /api/v2/microservices/logisticsapi_optimize
See JSON payload
Upload orders (bookings) into the simulation
POST /api/v2/microservices/logisticsapi
{
"calculation_uid": <arbitrary unique identifier for the calculation>,
"simulation_id": <simulation id created previously>,
"bookings": [],
"booking_uids": <bookings identifiers to be used for optimization from upload bookings request>
}

Poll calculation status

Optimization process runs asynchronously and it's state can be polled regularly (every few seconds), and once the run is completed, retrieve the results. processor_id in this case is a process identifier from the previous request.

Upload bookings into the simulation
GET /api/v2/simulationprocessor/<processor_id>

The request will return an object that contains state field which reflects current calculation state. Once the optimization run has been completed, the field will turn into completed state.

tip

Sometimes you might not get answers you are expecting from the optimization runs, this includes offer rejected situations which means the the booking can not be satisfied. This may mean that some constrains aren't met, or cost functions have not been properly configured. SWAT team can help investigate what went wrong.

Retrieve calculation results

There many ways to retrieve calculation outcomes depending on the needs of the consuming application. The most generic way is to retrieve allocations between the nodes and the vehicles.

Retrieve all vehicles used in the simulation

Upload bookings into the simulation
GET /api/v2/vehicle?simulation=<simulation_id>

The request will return a list of all vehicles for that simulation so a consumer can ensure that all required vehicles are present in the optimization results.

Retrieve assigned pick up and drop off points for a vehicle

Retrieve bookings assigned to a vehicle
GET /api/v2/vehicle/<vehicle_id>/assigned_nodes

The request will return a list of assigned drop off and pickup points for that vehicle (aka nodes

) referenced to the original booking as well as scheduled estimated arrival and departure times.

Retrieve assigned route for a vehicle

A geometry of the route assigned to a vehicle can be retrieved by using

Retrieve route geometry for a vehicle
GET /vehicle_route_proxy/<vehicle_id>/<wkt_waypoints>

where vehicle_id is vehicle identifier to retrieve the geometry for, and wkt_waypoints is semi-colon separated list of lat\lon pairs from the list of assigned nodes for a vehicle. Vehicle routing profile assigned at a vehicle creation stage will be used to produce the geometry of the route.