I am trying to implement the Clark and Wright algorithm to create an initial VRP solution. It seems to work correctly, but for some reason, the quality of the solution I get is not expected. See the description of the algorithm here.
Here is my code to calculate the savings element:
private void computeSavingsElements() {
for(int i = 0; i<vrp.getDimension(); i++) {
for(int j = 0; j < i; j++) {
double savingValue = vrp.distance(i, 0) + vrp.distance(0, j) - lamda * vrp.distance(i, j);
SavingsElement savingElement = new SavingsElement (i,j, savingValue);
savingsElements.add(savingElement);
}
}
Collections.sort(savingsElements);
Collections.reverse(savingsElements);
}
Solution building method:
private void constructSolution() {
List<VRPNode> nodes = this.vrp.getNodesList();
VRPNode depot = this.vrp.getDepot();
double vehicleCapacity = this.vrp.getVehicleCapacity();
VRPSolution solution = new VRPSolution(vehicleCapacity, depot);
for (VRPNode customer:nodes) {
if (customer.getId()!=0) {
VRPRoute route = new VRPRoute(vehicleCapacity, depot);
route.addCustomer(customer);
solution.addRoute(route);
route = null;
}
}
int mergesCounter=0;
for (SavingsElement savingElement : this.savingsElements) {
if (savingElement.getSavingValue() > 0) {
VRPNode i = this.vrp.getNode(savingElement.getNodeId1());
VRPNode j = this.vrp.getNode(savingElement.getNodeId2());
VRPRoute route1 = solution.routeWhereTheCustomerIsTheLastOne(i);
VRPRoute route2 = solution.routeWhereTheCustomerIsTheFirstOne(j);
if ((route1!=null) & (route2!=null)) {
if (route1.getDemand() + route2.getDemand() <= this.vrp.getVehicleCapacity()) {
solution.mergeRoutes(route1, route2);
mergesCounter++;
}
}
}
}
this.solutionConstructed = solution;
}
And for the route merges:
public void mergeRoutes(VRPRoute a, VRPRoute b) {
List<VRPNode> customersFromRouteA = new LinkedList<VRPNode>(a.getCustomersInRoute());
List<VRPNode> customersFromRouteB = new LinkedList<VRPNode>(b.getCustomersInRoute());
solutionRoutes.remove(a);
solutionRoutes.remove(b);
VRPRoute mergedRoute = new VRPRoute(vehicleCapacity,depot);
for (VRPNode customerFromA: customersFromRouteA) {
mergedRoute.addCustomer(customerFromA);
}
for (VRPNode customerFromB: customersFromRouteB) {
mergedRoute.addCustomer(customerFromB);
}
addRoute(mergedRoute);
evaluateSolutionCost();
}
It seems to correctly calculate the savings and combine the route, as it should be. But the cost of the constructed solution is too high. For example, in this case, I get 1220, and it should be 820.
user855520
source
share