/** This function returns a string containing the move information in readable format */ public String toString() { StringBuffer print = new StringBuffer(); print.append( "--- Move Customer " + customer.getNumber() + "-------------------------------------"); print.append( "\n" + "| DeleteDepot=" + deleteDepotNr + " DeleteRoute=" + deleteRouteNr + " DeletePosition=" + deletePositionIndex); print.append( "\n" + "| InsertDepot=" + insertDepotNr + " InsertRoute=" + insertRouteNr + " InsertPosition=" + insertPositionIndex); print.append("\n" + "--------------------------------------------------"); return print.toString(); }
@Override public int[] attributesInsert() { return new int[] {insertDepotNr, insertRouteNr, customer.getNumber(), 0, 0}; }
@Override public int[] attributesDelete() { return new int[] {deleteDepotNr, deleteRouteNr, customer.getNumber(), 0, 0}; }
/** @return the customer number */ public int getCustomerNr() { return customer.getNumber(); }
/** * 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