/**
*
*/
package vroom.common.modeling.util;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import vroom.common.modeling.dataModel.INodeVisit;
import vroom.common.modeling.dataModel.IRoute;
/**
* <code>DefaultRouteCostDelegate</code> is an implementation of
* {@link IRouteCostDelegate} based on a {@link CostCalculationDelegate}
*
* <p>
* Creation date: Feb 16, 2011 - 11:27:31 AM
*
* @author Victor Pillac, <a href="http://uniandes.edu.co">Universidad de Los
* Andes</a>-<a href="http://copa.uniandes.edu.co">Copa</a> <a
* href="http://www.emn.fr">Ecole des Mines de Nantes</a>-<a
* href="http://www.irccyn.ec-nantes.fr/irccyn/d/en/equipes/Slp">SLP</a>
*
* @version 1.0
*
*/
public class DefaultRouteCostDelegate implements IRouteCostDelegate {
private final CostCalculationDelegate mCostDelegate;
public DefaultRouteCostDelegate(CostCalculationDelegate costDelegate) {
mCostDelegate = costDelegate;
}
@Override
public double evaluateRoute(IRoute<?> route) {
double cost = 0;
ListIterator<? extends INodeVisit> it = route.iterator();
if (it.hasNext()) {
INodeVisit pred = it.next();
INodeVisit succ;
while (it.hasNext()) {
succ = it.next();
cost += mCostDelegate.getCost(pred, succ, route.getVehicle());
pred = succ;
}
}
route.updateCost(-route.getCost() + cost);
return cost;
}
@Override
public double getInsertionCost(IRoute<?> route, INodeVisit predecessor,
INodeVisit node, INodeVisit successor) {
double delta = 0;
// Head cost
if (predecessor != null)
delta += mCostDelegate.getCost(predecessor, node,
route.getVehicle());
// Tail cost
if (successor != null)
delta += mCostDelegate.getCost(node, successor, route.getVehicle());
// Removed arc
if (predecessor != null && successor != null)
delta -= mCostDelegate.getCost(predecessor, successor,
route.getVehicle());
return delta;
}
@Override
public double getInsertionCost(IRoute<?> route, INodeVisit predecessor,
IRoute<?> insertedRoute, INodeVisit successor) {
if (insertedRoute.length() == 0)
return 0;
double delta = 0;
// Head cost
if (predecessor != null)
delta += mCostDelegate.getCost(predecessor,
insertedRoute.getFirstNode(), route.getVehicle());
// Tail cost
if (successor != null)
delta += mCostDelegate.getCost(insertedRoute.getLastNode(),
successor, route.getVehicle());
// Removed arc
if (predecessor != null && successor != null)
delta -= mCostDelegate.getCost(predecessor, successor,
route.getVehicle());
// Inserted route cost
delta += insertedRoute.getCost();
return delta;
}
@Override
public double getInsertionCost(IRoute<?> route, INodeVisit predecessor,
List<? extends INodeVisit> insertedRoute, INodeVisit successor) {
if (insertedRoute.isEmpty())
return 0;
double delta = 0;
Iterator<? extends INodeVisit> it = insertedRoute.iterator();
// Head cost
INodeVisit pred = it.next();
if (predecessor != null)
delta += mCostDelegate.getCost(predecessor, pred,
route.getVehicle());
// Inserted route cost
INodeVisit succ = pred;
while (it.hasNext()) {
succ = it.next();
delta += mCostDelegate.getCost(pred, succ, route.getVehicle());
pred = succ;
}
// Tail cost
if (successor != null)
delta += mCostDelegate.getCost(succ, successor, route.getVehicle());
// Removed arc gain
if (predecessor != null && successor != null)
delta -= mCostDelegate.getCost(predecessor, successor,
route.getVehicle());
return delta;
}
/*
* (non-Javadoc)
*
* @see
* vroom.common.modeling.util.IRouteCostDelegate#nodeInserted(vroom.common
* .modelling.dataModel.IRoute, vroom.common.modeling.dataModel.INodeVisit,
* vroom.common.modeling.dataModel.INodeVisit,
* vroom.common.modeling.dataModel.INodeVisit)
*/
@Override
public void nodeInserted(IRoute<?> route, INodeVisit predecessor,
INodeVisit node, INodeVisit successor) {
route.updateCost(getInsertionCost(route, predecessor, node, successor));
}
/*
* (non-Javadoc)
*
* @see
* vroom.common.modeling.util.IRouteCostDelegate#routeInserted(vroom.common
* .modelling.dataModel.IRoute, vroom.common.modeling.dataModel.INodeVisit,
* vroom.common.modeling.dataModel.IRoute,
* vroom.common.modeling.dataModel.INodeVisit)
*/
@Override
public void routeInserted(IRoute<?> route, INodeVisit predecessor,
IRoute<?> insertedRoute, INodeVisit successor) {
route.updateCost(getInsertionCost(route, predecessor, insertedRoute,
successor));
}
/*
* (non-Javadoc)
*
* @see
* vroom.common.modeling.util.IRouteCostDelegate#routeInserted(vroom.common
* .modelling.dataModel.IRoute, vroom.common.modeling.dataModel.INodeVisit,
* java.util.List, vroom.common.modeling.dataModel.INodeVisit)
*/
@Override
public void routeInserted(IRoute<?> route, INodeVisit predecessor,
List<? extends INodeVisit> insertedRoute, INodeVisit successor) {
route.updateCost(getInsertionCost(route, predecessor, insertedRoute,
successor));
}
/*
* (non-Javadoc)
*
* @see
* vroom.common.modeling.util.IRouteCostDelegate#nodeRemoved(vroom.common
* .modelling.dataModel.IRoute, vroom.common.modeling.dataModel.INodeVisit,
* vroom.common.modeling.dataModel.INodeVisit,
* vroom.common.modeling.dataModel.INodeVisit)
*/
@Override
public void nodeRemoved(IRoute<?> route, INodeVisit predecessor,
INodeVisit node, INodeVisit successor) {
route.updateCost(-getInsertionCost(route, predecessor, node, successor));
}
/*
* (non-Javadoc)
*
* @see
* vroom.common.modeling.util.IRouteCostDelegate#subrouteRemoved(vroom.
* common.modelling.dataModel.IRoute,
* vroom.common.modeling.dataModel.INodeVisit,
* vroom.common.modeling.dataModel.IRoute,
* vroom.common.modeling.dataModel.INodeVisit)
*/
@Override
public void subrouteRemoved(IRoute<?> route, INodeVisit predecessor,
IRoute<?> removedRoute, INodeVisit successor) {
route.updateCost(-getInsertionCost(route, predecessor, removedRoute,
successor));
}
/*
* (non-Javadoc)
*
* @see
* vroom.common.modeling.util.IRouteCostDelegate#subrouteRemoved(vroom.
* common.modelling.dataModel.IRoute,
* vroom.common.modeling.dataModel.INodeVisit, java.util.List,
* vroom.common.modeling.dataModel.INodeVisit)
*/
@Override
public void subrouteRemoved(IRoute<?> route, INodeVisit predecessor,
List<? extends INodeVisit> removedRoute, INodeVisit successor) {
route.updateCost(-getInsertionCost(route, predecessor, removedRoute,
successor));
}
/*
* (non-Javadoc)
*
* @see
* vroom.common.modeling.util.IRouteCostDelegate#subrouteReversed(vroom
* .common.modelling.dataModel.IRoute,
* vroom.common.modeling.dataModel.INodeVisit,
* vroom.common.modeling.dataModel.INodeVisit)
*/
@Override
public void subrouteReversed(IRoute<?> route, INodeVisit predecessor,
INodeVisit first, INodeVisit last, INodeVisit successor) {
double delta = 0;
if (predecessor != null) {
delta -= mCostDelegate.getCost(predecessor, first,
route.getVehicle());
delta += mCostDelegate.getCost(predecessor, last,
route.getVehicle());
}
if (successor != null) {
delta -= mCostDelegate.getCost(last, successor, route.getVehicle());
delta += mCostDelegate
.getCost(first, successor, route.getVehicle());
}
route.updateCost(delta);
}
@Override
public void nodeReplaced(IRoute<?> route, INodeVisit predecessor,
INodeVisit previousNode, INodeVisit node, INodeVisit successor) {
double delta = 0;
if (predecessor != null) {
delta -= mCostDelegate.getCost(predecessor, previousNode,
route.getVehicle());
delta += mCostDelegate.getCost(predecessor, node,
route.getVehicle());
}
if (successor != null) {
delta -= mCostDelegate.getCost(previousNode, successor,
route.getVehicle());
delta += mCostDelegate.getCost(node, successor, route.getVehicle());
}
route.updateCost(delta);
}
@Override
public void nodesSwapped(IRoute<?> route, INodeVisit pred1,
INodeVisit node1, INodeVisit succ1, INodeVisit pred2,
INodeVisit node2, INodeVisit succ2) {
double delta = 0;
if (node2 == succ1) {
if (pred1 != null) {
delta -= mCostDelegate
.getCost(pred1, node1, route.getVehicle());
delta += mCostDelegate
.getCost(pred1, node2, route.getVehicle());
}
if (succ2 != null) {
delta -= mCostDelegate
.getCost(node2, succ2, route.getVehicle());
delta += mCostDelegate
.getCost(node1, succ2, route.getVehicle());
}
delta -= mCostDelegate.getCost(node1, node2, route.getVehicle());
delta += mCostDelegate.getCost(node2, node1, route.getVehicle());
} else {
delta -= getInsertionCost(route, pred1, node1, succ1);
delta += getInsertionCost(route, pred2, node1, succ2);
delta -= getInsertionCost(route, pred2, node2, succ2);
delta += getInsertionCost(route, pred1, node2, succ1);
}
route.updateCost(delta);
}
}