private void evaluateTotalCostVariation( MySolution sol, MySwapMove move, Cost initialInsertCost, Cost initialDeleteCost) { Route insertRoute = sol.getRoute(move.getInsertRouteNr()); Route deleteRoute = sol.getRoute(move.getDeleteRouteNr()); sol.addTravelTime( -initialInsertCost.travelTime - initialDeleteCost.travelTime + deleteRoute.getCost().travelTime + insertRoute.getCost().travelTime); sol.addServiceTime( -initialInsertCost.serviceTime - initialDeleteCost.serviceTime + deleteRoute.getCost().serviceTime + insertRoute.getCost().serviceTime); sol.addWaitingTime( -initialInsertCost.waitingTime - initialDeleteCost.waitingTime + deleteRoute.getCost().waitingTime + insertRoute.getCost().waitingTime); sol.getCost().loadViol += -initialInsertCost.loadViol - initialDeleteCost.loadViol + deleteRoute.getCost().loadViol + insertRoute.getCost().loadViol; sol.getCost().twViol += -initialInsertCost.twViol - initialDeleteCost.twViol + deleteRoute.getCost().twViol + insertRoute.getCost().twViol; sol.getCost().waitingTime = Math.abs(sol.getCost().waitingTime) < instance.getPrecision() ? 0 : sol.getCost().waitingTime; sol.getCost().loadViol = Math.abs(sol.getCost().loadViol) < instance.getPrecision() ? 0 : sol.getCost().loadViol; sol.getCost().twViol = Math.abs(sol.getCost().twViol) < instance.getPrecision() ? 0 : sol.getCost().twViol; sol.getCost().calculateTotal(sol.getAlpha(), sol.getBeta(), sol.getGamma()); }
/** * This function delete the customer in the given route on the given position and updates the * cost. It is an optimized version of the evaluate route. Calculates only for the customers * affected by the deletion. Starts from the given position and could finish before reaching the * end of the list if there is no modification in the arrive time at the customers. Does alter the * route. * * @param route * @param position * @return */ private void evaluateDeleteRoute(Route route, Customer customer, int position) { Cost varCost = route.getCost(); double arriveNextCustomer = 0; double waitingTimeNextCustomer = 0; double twViolNextCustomer = 0; // if route has only the customer that will be deleted if (route.getCustomersLength() - 1 == 0) { varCost.initialize(); } else { // case when customer is the last one: customer before - depot if (position == route.getCustomersLength() - 1) { Customer customerBefore = route.getCustomer(position - 1); // arrive time at the depot arriveNextCustomer = Math.max(customerBefore.getStartTw(), customerBefore.getArriveTime()) + customerBefore.getServiceDuration() + instance.getTravelTime(customerBefore.getNumber(), route.getDepotNr()); // time window violation of the depot if any twViolNextCustomer = Math.max(0, arriveNextCustomer - route.getDepot().getEndTw()); // variation of the travel time varCost.travelTime += -instance.getTravelTime(customerBefore.getNumber(), customer.getNumber()) - instance.getTravelTime(customer.getNumber(), route.getDepotNr()) + instance.getTravelTime(customerBefore.getNumber(), route.getDepotNr()); // variation of the capacity varCost.load -= customer.getCapacity(); // route service time varCost.serviceTime -= customer.getServiceDuration(); // variation of the waiting time varCost.waitingTime -= customer.getWaitingTime(); // variation of the time windows violation varCost.twViol += -customer.getTwViol() - route.getDepotTwViol() + twViolNextCustomer; varCost.returnToDepotTime = arriveNextCustomer; varCost.depotTwViol = twViolNextCustomer; } else { double variation = 0; Customer customerAfter = route.getCustomer(position + 1); // delete on the first position if (position == 0) { // time before arrive at customer after arriveNextCustomer = route.getDepot().getStartTw() + instance.getTravelTime(route.getDepotNr(), customerAfter.getNumber()); // variation of the travel time varCost.travelTime += -instance.getTravelTime(route.getDepotNr(), customer.getNumber()) - instance.getTravelTime(customer.getNumber(), customerAfter.getNumber()) + instance.getTravelTime(route.getDepotNr(), customerAfter.getNumber()); // delete in the middle of the list } else { Customer customerBefore = route.getCustomer(position - 1); // time before arrive at customer after arriveNextCustomer = Math.max(customerBefore.getStartTw(), customerBefore.getArriveTime()) + customerBefore.getServiceDuration() + instance.getTravelTime(customerBefore.getNumber(), customerAfter.getNumber()); // variation of the travel time varCost.travelTime += -instance.getTravelTime(customerBefore.getNumber(), customer.getNumber()) - instance.getTravelTime(customer.getNumber(), customerAfter.getNumber()) + instance.getTravelTime(customerBefore.getNumber(), customerAfter.getNumber()); } // end if else beginning or middle // waiting time for the customer after if any waitingTimeNextCustomer = Math.max(0, customerAfter.getStartTw() - arriveNextCustomer); // time window violation of the customer after if any twViolNextCustomer = Math.max(0, arriveNextCustomer - customerAfter.getEndTw()); // variation of the capacity varCost.load -= customer.getCapacity(); // route service time varCost.serviceTime -= customer.getServiceDuration(); // variation of the waiting time varCost.waitingTime += -customer.getWaitingTime() - customerAfter.getWaitingTime() + waitingTimeNextCustomer; // variation of the time windows violation varCost.twViol += -customer.getTwViol() - customerAfter.getTwViol() + twViolNextCustomer; variation = arriveNextCustomer + waitingTimeNextCustomer - customerAfter.getArriveTime() - customerAfter.getWaitingTime(); variation = Math.abs(variation) < instance.getPrecision() ? 0 : variation; customerAfter.setArriveTime(arriveNextCustomer); customerAfter.setWaitingTime(waitingTimeNextCustomer); customerAfter.setTwViol(twViolNextCustomer); // if there is a variation update the nodes after too // the node after the customer is already updated int i = position + 2; while (variation != 0 && i < route.getCustomersLength()) { customerAfter = route.getCustomer(i); // arrive at the customer after arriveNextCustomer = customerAfter.getArriveTime() + variation; waitingTimeNextCustomer = Math.max(0, customerAfter.getStartTw() - arriveNextCustomer); twViolNextCustomer = Math.max(0, arriveNextCustomer - customerAfter.getEndTw()); // variation of the waiting time varCost.waitingTime += -customerAfter.getWaitingTime() + waitingTimeNextCustomer; // variation of the time windows violation varCost.twViol += -customerAfter.getTwViol() + twViolNextCustomer; variation = arriveNextCustomer + waitingTimeNextCustomer - customerAfter.getArriveTime() - customerAfter.getWaitingTime(); variation = Math.abs(variation) < instance.getPrecision() ? 0 : variation; customerAfter.setArriveTime(arriveNextCustomer); customerAfter.setWaitingTime(waitingTimeNextCustomer); customerAfter.setTwViol(twViolNextCustomer); i++; } // end while // update depot violation too if any if (i == route.getCustomersLength() && variation != 0) { // update the return to the depot arriveNextCustomer = route.getReturnToDepotTime() + variation; twViolNextCustomer = Math.max(0, arriveNextCustomer - route.getDepot().getEndTw()); // variation of the time windows violation varCost.twViol += -route.getDepotTwViol() + twViolNextCustomer; varCost.returnToDepotTime = arriveNextCustomer; varCost.depotTwViol = twViolNextCustomer; } // end if return to depot } // end if else of position cases } // end if else route is empty route.removeCustomer(position); // be careful about precision; if there are subtraction varCost.waitingTime = Math.abs(varCost.waitingTime) < instance.getPrecision() ? 0 : varCost.waitingTime; varCost.twViol = Math.abs(varCost.twViol) < instance.getPrecision() ? 0 : varCost.twViol; varCost.setLoadViol(Math.max(0, varCost.load - route.getLoadAdmited())); } // end method evaluate delete route