VRPy: A Python package for solving a range of vehicle routing problems with a column generation approach

The Vehicle Routing Problem (VRP) is amongst the most well known combinatorial optimization problems. The most classical version of the VRP, the Capacitated VRP (CVRP) (Laporte, 2007), can be described as follows. A fleet of vehicles with uniform capacity must serve customers with known demand for a single commodity. The vehicles start and end their routes at a common depot and each customer must be served by exactly one vehicle. The objective is to assign a sequence of customers to each vehicle of the fleet (a route), minimizing the total distance traveled, such that all customers are served and the total demand served by each vehicle does not exceed its capacity. Note that the VRP generalises the well-known traveling salesman problem (TSP) and is therefore computationally intractable.


Introduction
The Vehicle Routing Problem (VRP) is amongst the most well known combinatorial optimization problems. The most classical version of the VRP, the Capacitated VRP (CVRP) (Laporte, 2007), can be described as follows. A fleet of vehicles with uniform capacity must serve customers with known demand for a single commodity. The vehicles start and end their routes at a common depot and each customer must be served by exactly one vehicle. The objective is to assign a sequence of customers to each vehicle of the fleet (a route), minimizing the total distance traveled, such that all customers are served and the total demand served by each vehicle does not exceed its capacity. Note that the VRP generalises the well-known traveling salesman problem (TSP) and is therefore computationally intractable.
Mathematicians have started tackling VRPs since 1959 (Dantzig & Ramser, 1959). Ever since, algorithms and computational power have not stopped improving. State of the art techniques include column generation approaches (Bramel & Simchi-Levi, 1997;Costa et al., 2019) on which vrpy relies; more details are given hereafter.
vrpy is of interest to the operational research community and others (e.g., logisticians, supply chain analysts) who wish to solve vehicle routing problems, and therefore has many obvious applications in industry.
For each of these variants, it is possible to i/ set initial routes for the search (if one already has a solution at hand and wishes to improve it) ii/ lock routes (if part of the solution is imposed and must not be optimized) iii/ drop nodes (ignore a customer at the cost of a penalty).

State of the field
Although the VRP is a classical optimization problem, to our knowledge there is only one dedicated package in the Python ecosystem that is able to solve such a range of VRP variants: the excellent OR-Tools (Google) routing library (Perron & Furnon, 2019), released for the first time in 2014. To be precise, the core algorithms are implemented in C++, but the library provides a wrapper in Python. Popular and efficient, it is a reference for vrpy, both in terms of features and performance. The current version of vrpy is able to handle the same variants as OR-Tools (mentioned in the previous section).
Performance-wise, vrpy ambitions to be competitive with OR-Tools eventually, at least in terms of solution quality. For the moment, benchmarks (available in the repository) for the CVRP on the set of Augerat instances (Augerat, 1995) show promising results: in the performance profile in Figure 1 below, one can see that nearly the same number of instances are solved within 10 seconds with the same relative error with respect to the best known solution (42% for vrpy, 44% for OR-Tools).

Figure 1: CVRP Performance profile
We do not claim to outperform OR-Tools, but aim to have results of the same order of magnitude as the package evolves, as there is still much room for improvement (see Section Future Work below). On the other hand, we are confident that the user friendly and intuitive API will help students, researchers and more generally the operational research community solve instances of vehicle routing problems of small to medium size, perhaps more easily than with the existing software.
py-ga-VRPTW is another library that is available but as mentioned by its authors, it is more of an experimental project and its performances are rather poor. In particular, we were not able to find feasible solutions for Solomon's instances (Solomon, 1987) and therefore cannot compare the two libraries. Also note that py-ga-VRPTW is designed to solve the VRPTW only, that is, the VRP with time windows.

Mathematical background
vrpy solves vehicle routing problems with a column generation approach. The term column generation refers to the fact that iteratively, routes (or columns) are generated with a pricing problem, and fed to a master problem which selects the best routes among a pool such that each vertex is serviced exactly once. Results from the master problem are then used to search for new potential routes likely to improve the solution's cost, and so forth. This procedure is illustrated in Figure 2 below:

Figure 2: Column Generation
The master problem is a set partitioning linear formulation and is solved with the open source solver Clp from COIN-OR (Forrest et al., 2020), while the subproblem is a shortest elementary path problem with resource constraints. It is solved with the help of the cspy library (Torres Sanchez, 2020) which is specifically designed for such problems.
This column generation procedure is very generic, as for each of the featuring VRP variants, the master problem is identical and partitions the customers into subsets (routes). It is the subproblem (or pricing problem) that differs from one variant to another. More specifically, each variant has its unique set of resources which must remain in a given interval. For example, for the CVRP, a resource representing the vehicle's load is carried along the path and must not exceed the vehicle capacity; for the CVRP with time windows, two extra resources must be considered: the first one for time, and the second one for time window feasibility. The reader may refer to (Costa et al., 2019) for more details on each of these variants and how they are delt with within the framework of column generation.
Note that vrpy does not necessarily return an optimal solution. Indeed, once the pricing problems fails to find a route with negative marginal cost, the master problem is solved as a MIP. This price-and-branch strategy does not guarantee optimality. Note however that it can be shown (Bramel & Simchi-Levi, 1997) that asymptotically, the relative error goes to zero as the number of customers increases. To guarantee that an optimal solution is returned, the column generation procedure should be embedded in a branch-and-bound scheme (branchand-price), which is beyond the scope of the current release, but part of the future work considered.

Advanced Features
For more advanced users, there are different pricing strategies (approaches for solving subproblems), namely sparsification strategies (Dell'Amico et al., 2006;Santini et al., 2018), as well as pre-pricing heuristics available that can lead to faster solutions. The heuristics implemented include a greedy randomized heuristic (for the CVRP and the CVRP with resource constraints) (Santini et al., 2018). Also, a diving heuristic (Sadykov et al., 2019) can be called to explore part of the branch-and-price tree, instead of solving the restricted master problem as a MIP.
Additionally, we have an experimental feature that uses Hyper-Heuristics for the dynamic selection of pricing strategies. The approach ranks the best pricing strategies as the algorithm is running and chooses according to selection functions based on (Ferreira et al., 2017;Sabar et al., 2015). The selection criteria has been modified to include a combination of runtime, objective improvement, and currently active columns in the restricted master problem. Adaptive parameter settings found in (Drake et al., 2012) is used to balance exploration and exploitation under stagnation. The main advantage is that selection is done as the program runs, and is therefore more flexible compared to a predefined pricing strategy.

Future Work
There are many ways vrpy could be improved. To boost the run times, specific heuristics for each variant could be implemented, e.g., Solomon's insertion algorithm (Solomon, 1987) for the VRPTW. Second, the pricing problem is solved with cspy, which is quite recent (2019) and is still being fine tuned. Also, currently, stabilization issues are delt with a basic interior point based strategy which could be enhanced (Pessoa et al., 2018). Last but not least, there are many cutting strategies in the literature (Costa et al., 2019) that have not been implemented and which have proven to significantly reduce run times for such problems.