1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

extended stateManager to memorize vehicle dependent states

This commit is contained in:
oblonski 2014-07-16 15:00:30 +02:00
parent 952570952a
commit dbdb3372c7
11 changed files with 167 additions and 76 deletions

View file

@ -157,7 +157,7 @@ public class VehicleRoutingAlgorithmBuilder {
* @return
*/
public VehicleRoutingAlgorithm build() {
if(stateManager == null) stateManager = new StateManager(vrp.getTransportCosts());
if(stateManager == null) stateManager = new StateManager(vrp);
if(constraintManager == null) constraintManager = new ConstraintManager(vrp,stateManager,vrp.getConstraints());
//add core updater
stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen());

View file

@ -23,6 +23,7 @@ import jsprit.core.algorithm.ruin.listener.RuinListeners;
import jsprit.core.problem.Capacity;
import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
import jsprit.core.problem.driver.Driver;
import jsprit.core.problem.job.Job;
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import jsprit.core.problem.solution.route.ReverseRouteActivityVisitor;
@ -35,6 +36,7 @@ import jsprit.core.problem.solution.route.activity.TourActivity;
import jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter;
import jsprit.core.problem.solution.route.state.StateFactory;
import jsprit.core.problem.solution.route.state.StateFactory.StateId;
import jsprit.core.problem.vehicle.Vehicle;
import java.util.*;
@ -109,10 +111,16 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
private int nuActivities;
private int nuVehicleTypeKeys;
private Object[][] activity_states;
private Object[][][] vehicle_dependent_activity_states;
private Object[][] route_states;
private Object[][][] vehicle_dependent_route_states;
private VehicleRoutingProblem vrp;
public StateId createStateId(String name){
@ -120,6 +128,8 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
if(stateIndexCounter>=activity_states[0].length){
activity_states = new Object[vrp.getNuActivities()+1][stateIndexCounter+1];
route_states = new Object[vrp.getNuActivities()+1][stateIndexCounter+1];
vehicle_dependent_activity_states = new Object[nuActivities][nuVehicleTypeKeys][stateIndexCounter+1];
vehicle_dependent_route_states = new Object[nuActivities][nuVehicleTypeKeys][stateIndexCounter+1];
}
StateId id = StateFactory.createId(name,stateIndexCounter);
incStateIndexCounter();
@ -164,16 +174,27 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
public StateManager(VehicleRoutingProblem vehicleRoutingProblem){
this.routingCosts = vehicleRoutingProblem.getTransportCosts();
this.vrp = vehicleRoutingProblem;
nuActivities = vrp.getNuActivities() + 1;
nuActivities = Math.max(10,vrp.getNuActivities() + 1);
nuVehicleTypeKeys = Math.max(3,getNuVehicleTypes(vrp) + 1);
activity_states = new Object[nuActivities][initialNuStates];
route_states = new Object[nuActivities][initialNuStates];
vehicle_dependent_activity_states = new Object[nuActivities][nuVehicleTypeKeys][initialNuStates];
vehicle_dependent_route_states = new Object[nuActivities][nuVehicleTypeKeys][initialNuStates];
addDefaultStates();
}
public <T> void addDefaultProblemState(StateId stateId, Class<T> type, T defaultState){
private int getNuVehicleTypes(VehicleRoutingProblem vrp) {
int maxIndex = 0;
for(Vehicle v : vrp.getVehicles()){
maxIndex = Math.max(maxIndex,v.getVehicleTypeIdentifier().getIndex());
}
return maxIndex;
}
public <T> void addDefaultProblemState(StateId stateId, Class<T> type, T defaultState){
defaultProblemStates_.putState(stateId, type, defaultState);
}
public <T> void putProblemState(StateId stateId, Class<T> type, T state){
problemStates_.putState(stateId, type, state);
}
@ -225,6 +246,8 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
public void clear(){
activity_states = new Object[nuActivities][stateIndexCounter];
route_states = new Object[nuActivities][stateIndexCounter];
vehicle_dependent_activity_states = new Object[nuActivities][nuVehicleTypeKeys][initialNuStates];
vehicle_dependent_route_states = new Object[nuActivities][nuVehicleTypeKeys][initialNuStates];
problemStates_.clear();
}
@ -240,6 +263,17 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
return state;
}
/**
* Returns activity state of type 'type'.
*
*/
public <T> T getActivityState(TourActivity act, Vehicle vehicle, Driver driver, StateId stateId, Class<T> type) {
if(act.getIndex()<0) return getDefaultTypedActivityState(act, stateId, type);
T state = type.cast(vehicle_dependent_activity_states[act.getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]);
if(state == null) return getDefaultTypedActivityState(act, stateId, type);
return state;
}
/**
*
* @param act activity for which the state is requested
@ -269,15 +303,18 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
@Override
public <T> T getRouteState(VehicleRoute route, StateId stateId, Class<T> type) {
if(route.isEmpty()) return getDefaultTypedRouteState(stateId,type);
// if(route.getActivities().get(0).getIndex()>=route_states.length){
// nuActivities=route.getActivities().get(0).getIndex()+1;
// this.route_states = resizeArr(route_states,nuActivities);
// }
T state = type.cast(route_states[route.getActivities().get(0).getIndex()][stateId.getIndex()]);
if(state==null) return getDefaultTypedRouteState(stateId,type);
return state;
}
public <T> T getRouteState(VehicleRoute route, Vehicle vehicle, Driver driver, StateId stateId, Class<T> type) {
if(route.isEmpty()) return getDefaultTypedRouteState(stateId,type);
T state = type.cast(vehicle_dependent_route_states[route.getActivities().get(0).getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]);
if(state==null) return getDefaultTypedRouteState(stateId,type);
return state;
}
private <T> T getDefaultTypedRouteState(StateId stateId, Class<T> type) {
if(defaultRouteStates_.containsKey(stateId)){
return type.cast(defaultRouteStates_.get(stateId));
@ -303,20 +340,16 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
*/
@Deprecated
public <T> void putTypedActivityState(TourActivity act, StateId stateId, Class<T> type, T state){
// if(act.getIndex()>=activity_states.length){
// nuActivities=act.getIndex()+1;
// this.activity_states = resizeArr(activity_states,nuActivities);
// }
if(stateId.getIndex()<10) throw new IllegalStateException("either you use a reserved stateId that is applied\n" +
"internally or your stateId has been created without index, e.g. StateFactory.createId(stateName)\n" +
" does not assign indeces thus do not use it anymore, but use\n " +
"stateManager.createStateId(name)\n" +
" instead.\n");
putInternalTypedActivityState(act, stateId, type, state);
putInternalTypedActivityState(act, stateId, state);
}
/**
* Generic method to memorize state 'state' of type 'type' of act and stateId.
* Method to memorize state 'state' of type 'type' of act and stateId.
*
* <p><b>For example: </b><br>
* <code>Capacity loadAtMyActivity = Capacity.Builder.newInstance().addCapacityDimension(0,10).build();<br>
@ -329,17 +362,32 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
* @param type class of state-value
* @param state state-value
*/
@Deprecated
public <T> void putActivityState(TourActivity act, StateId stateId, Class<T> type, T state){
// if(act.getIndex()>=activity_states.length){
// nuActivities=act.getIndex()+1;
// this.activity_states = resizeArr(activity_states,nuActivities);
// }
if(stateId.getIndex()<10) throw new IllegalStateException("either you use a reserved stateId that is applied\n" +
"internally or your stateId has been created without index, e.g. StateFactory.createId(stateName)\n" +
" does not assign indeces thus do not use it anymore, but use\n " +
"stateManager.createStateId(name)\n" +
" instead.\n");
putInternalTypedActivityState(act, stateId, type, state);
putInternalTypedActivityState(act, stateId, state);
}
public <T> void putActivityState(TourActivity act, StateId stateId, T state){
if(stateId.getIndex()<10) throw new IllegalStateException("either you use a reserved stateId that is applied\n" +
"internally or your stateId has been created without index, e.g. StateFactory.createId(stateName)\n" +
" does not assign indeces thus do not use it anymore, but use\n " +
"stateManager.createStateId(name)\n" +
" instead.\n");
putInternalTypedActivityState(act, stateId, state);
}
public <T> void putActivityState(TourActivity act, Vehicle vehicle, Driver driver, StateId stateId, T state){
if(stateId.getIndex()<10) throw new IllegalStateException("either you use a reserved stateId that is applied\n" +
"internally or your stateId has been created without index, e.g. StateFactory.createId(stateName)\n" +
" does not assign indeces thus do not use it anymore, but use\n " +
"stateManager.createStateId(name)\n" +
" instead.\n");
putInternalTypedActivityState(act, vehicle, driver, stateId, state);
}
private Object[][] resizeArr(Object[][] states, int newLength) {
@ -349,10 +397,14 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
return new_states;
}
<T> void putInternalTypedActivityState(TourActivity act, StateId stateId, Class<T> type, T state){
<T> void putInternalTypedActivityState(TourActivity act, StateId stateId, T state){
activity_states[act.getIndex()][stateId.getIndex()]=state;
}
<T> void putInternalTypedActivityState(TourActivity act, Vehicle vehicle, Driver driver, StateId stateId, T state){
vehicle_dependent_activity_states[act.getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()]=state;
}
/**
* Generic method to memorize state 'state' of type 'type' of route and stateId.
*
@ -391,11 +443,21 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
putTypedInternalRouteState(route, stateId, state);
}
public <T> void putRouteState(VehicleRoute route, Vehicle vehicle, Driver driver, StateId stateId, T state){
if(stateId.getIndex()<10) StateFactory.throwReservedIdException(stateId.toString());
putTypedInternalRouteState(route, vehicle, driver, stateId, state);
}
<T> void putTypedInternalRouteState(VehicleRoute route, StateId stateId, T state){
if(route.isEmpty()) return;
route_states[route.getActivities().get(0).getIndex()][stateId.getIndex()] = state;
}
<T> void putTypedInternalRouteState(VehicleRoute route, Vehicle vehicle, Driver driver, StateId stateId, T state){
if(route.isEmpty()) return;
vehicle_dependent_route_states[route.getActivities().get(0).getIndex()][vehicle.getVehicleTypeIdentifier().getIndex()][stateId.getIndex()] = state;
}
/**
* Adds state updater.
*

View file

@ -69,7 +69,7 @@ class UpdateLoads implements ActivityVisitor, StateUpdater, InsertionStartsListe
@Override
public void visit(TourActivity act) {
currentLoad = Capacity.addup(currentLoad, act.getSize());
stateManager.putInternalTypedActivityState(act, StateFactory.LOAD, Capacity.class, currentLoad);
stateManager.putInternalTypedActivityState(act, StateFactory.LOAD, currentLoad);
assert currentLoad.isLessOrEqual(route.getVehicle().getType().getCapacityDimensions()) : "currentLoad at activity must not be > vehicleCapacity";
assert currentLoad.isGreaterOrEqual(Capacity.Builder.newInstance().build()) : "currentLoad at act must not be < 0 in one of the applied dimensions";
}

View file

@ -52,7 +52,7 @@ class UpdateMaxCapacityUtilisationAtActivitiesByLookingBackwardInRoute implement
@Override
public void visit(TourActivity act) {
maxLoad = Capacity.max(maxLoad, stateManager.getActivityState(act, StateFactory.LOAD, Capacity.class));
stateManager.putInternalTypedActivityState(act, StateFactory.PAST_MAXLOAD, Capacity.class, maxLoad);
stateManager.putInternalTypedActivityState(act, StateFactory.PAST_MAXLOAD, maxLoad);
assert maxLoad.isGreaterOrEqual(Capacity.Builder.newInstance().build()) : "maxLoad can never be smaller than 0";
assert maxLoad.isLessOrEqual(route.getVehicle().getType().getCapacityDimensions()) : "maxLoad can never be bigger than vehicleCap";
}

View file

@ -65,7 +65,7 @@ class UpdateMaxCapacityUtilisationAtActivitiesByLookingForwardInRoute implements
@Override
public void visit(TourActivity act) {
maxLoad = Capacity.max(maxLoad, stateManager.getActivityState(act, StateFactory.LOAD, Capacity.class));
stateManager.putInternalTypedActivityState(act, StateFactory.FUTURE_MAXLOAD, Capacity.class, maxLoad);
stateManager.putInternalTypedActivityState(act, StateFactory.FUTURE_MAXLOAD, maxLoad);
assert maxLoad.isLessOrEqual(route.getVehicle().getType().getCapacityDimensions()) : "maxLoad can in every capacity dimension never be bigger than vehicleCap";
assert maxLoad.isGreaterOrEqual(Capacity.Builder.newInstance().build()) : "maxLoad can never be smaller than 0";
}

View file

@ -60,7 +60,7 @@ class UpdatePracticalTimeWindows implements ReverseActivityVisitor, StateUpdater
double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime(activity.getLocationId(), prevAct.getLocationId(), latestArrTimeAtPrevAct, route.getDriver(),route.getVehicle()) - activity.getOperationTime();
double latestArrivalTime = Math.min(activity.getTheoreticalLatestOperationStartTime(), potentialLatestArrivalTimeAtCurrAct);
states.putInternalTypedActivityState(activity, StateFactory.LATEST_OPERATION_START_TIME, Double.class, latestArrivalTime);
states.putInternalTypedActivityState(activity, StateFactory.LATEST_OPERATION_START_TIME, latestArrivalTime);
latestArrTimeAtPrevAct = latestArrivalTime;
prevAct = activity;

View file

@ -94,7 +94,7 @@ public class UpdateVariableCosts implements ActivityVisitor,StateUpdater{
totalOperationCost += transportCost;
totalOperationCost += actCost;
states.putInternalTypedActivityState(act, StateFactory.COSTS, Double.class, totalOperationCost);
states.putInternalTypedActivityState(act, StateFactory.COSTS, totalOperationCost);
prevAct = act;
startTimeAtPrevAct = timeTracker.getActEndTime();