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

adjustments to introducing pickup and delivery

This commit is contained in:
Stefan Schroeder 2013-08-28 18:24:27 +02:00
parent e6f671cbcc
commit 216df61db4
10 changed files with 90 additions and 56 deletions

View file

@ -4,11 +4,25 @@ import basics.route.TourActivity;
class CalcUtils {
/**
*
* @param startTimeAtPrevAct
* @param tpTime_prevAct_nextAct
* @param nextAct
* @return
*/
static double getStartTimeAtAct(double startTimeAtPrevAct, double tpTime_prevAct_nextAct, TourActivity nextAct){
return Math.max(startTimeAtPrevAct + tpTime_prevAct_nextAct, nextAct.getTheoreticalEarliestOperationStartTime()) + nextAct.getOperationTime();
}
static double getStartTimeAtAct(double nextActArrTime, TourActivity nextAct){
return Math.max(nextActArrTime, nextAct.getTheoreticalEarliestOperationStartTime()) + nextAct.getOperationTime();
/**
* Calculates actEndTime assuming that activity can at earliest start at act.getTheoreticalEarliestOperationStartTime().
*
* @param actArrTime
* @param act
* @return
*/
static double getActivityEndTime(double actArrTime, TourActivity act){
return Math.max(actArrTime, act.getTheoreticalEarliestOperationStartTime()) + act.getOperationTime();
}
}

View file

@ -25,6 +25,8 @@ import basics.route.End;
import basics.route.ServiceActivity;
import basics.route.Start;
import basics.route.TourActivity;
import basics.route.TourActivityFactory;
import basics.route.DefaultTourActivityFactory;
import basics.route.Vehicle;
import basics.route.VehicleImpl.NoVehicle;
import basics.route.VehicleRoute;
@ -49,6 +51,8 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{
private VehicleRoutingTransportCosts transportCosts;
private TourActivityFactory activityFactory;
public void setNeighborhood(Neighborhood neighborhood) {
this.neighborhood = neighborhood;
logger.info("initialise neighborhood " + neighborhood);
@ -59,6 +63,7 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{
this.marginalCalculus = marginalsCalculus;
this.hardRouteLevelConstraint = hardRouteLevelConstraint;
this.transportCosts = routingCosts;
activityFactory = new DefaultTourActivityFactory();
logger.info("initialise " + this);
}
@ -86,7 +91,8 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{
Marginals bestMarginals = null;
Service service = (Service)jobToInsert;
int insertionIndex = InsertionData.NO_INDEX;
TourActivity deliveryAct2Insert = ServiceActivity.newInstance(service);
TourActivity deliveryAct2Insert = activityFactory.createActivity(service);
Start start = Start.newInstance(newVehicle.getLocationId(), newVehicle.getEarliestDeparture(), newVehicle.getLatestArrival());
start.setEndTime(newVehicleDepartureTime);

View file

@ -23,21 +23,21 @@ import java.util.PriorityQueue;
import org.apache.log4j.Logger;
import util.Neighborhood;
import algorithms.RouteStates.ActivityState;
import basics.Job;
import basics.Service;
import basics.costs.VehicleRoutingActivityCosts;
import basics.costs.VehicleRoutingTransportCosts;
import basics.route.DefaultTourActivityFactory;
import basics.route.Driver;
import basics.route.End;
import basics.route.ServiceActivity;
import basics.route.Start;
import basics.route.TourActivities;
import basics.route.TourActivity;
import basics.route.TourActivityFactory;
import basics.route.Vehicle;
import basics.route.VehicleRoute;
import basics.route.VehicleImpl.NoVehicle;
import basics.route.VehicleRoute;
@ -51,6 +51,8 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
private AuxilliaryCostCalculator auxilliaryPathCostCalculator;
private TourActivityFactory tourActivityFactory = new DefaultTourActivityFactory();
private StateManager states;
private int nuOfActsForwardLooking = 0;
@ -70,7 +72,9 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
};
public void setTourActivityFactory(TourActivityFactory tourActivityFactory){
this.tourActivityFactory=tourActivityFactory;
}
public void setNeighborhood(Neighborhood neighborhood) {
this.neighborhood = neighborhood;
@ -142,7 +146,7 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
/**
* some inis
*/
TourActivity serviceAct2Insert = ServiceActivity.newInstance(service);
TourActivity serviceAct2Insert = tourActivityFactory.createActivity(service);
int best_insertion_index = InsertionData.NO_INDEX;
initialiseStartAndEnd(newVehicle, newVehicleDepartureTime);

View file

@ -214,7 +214,7 @@ class CalculatorBuilder {
}
private CalculatorPlusListeners createStandardLocal(VehicleRoutingProblem vrp, StateManager activityStates2){
MarginalsCalculus defaultCalc = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), new HardConstraints.HardTimeWindowConstraint(activityStates2) );
MarginalsCalculus defaultCalc = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), new HardConstraints.HardTimeWindowConstraint(activityStates2, vrp.getTransportCosts()) );
JobInsertionCalculator standardServiceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), defaultCalc, new HardConstraints.HardLoadConstraint(activityStates2));
((CalculatesServiceInsertion) standardServiceInsertion).setNeighborhood(vrp.getNeighborhood());

View file

@ -21,17 +21,15 @@
package algorithms;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.log4j.Logger;
import algorithms.VehicleFleetManager.TypeKey;
import basics.route.TourActivities;
import basics.route.TourActivity;
import basics.route.Vehicle;
import basics.route.VehicleRoute;
import basics.route.VehicleImpl.NoVehicle;
import basics.route.VehicleRoute;
@ -47,13 +45,13 @@ final class FindCheaperVehicleAlgo {
private double weightFixCosts = 1.0;
private RouteStates states;
private StateManager states;
public void setWeightFixCosts(double weightFixCosts) {
this.weightFixCosts = weightFixCosts;
}
public void setStates(RouteStates states) {
public void setStates(StateManager states) {
this.states = states;
}
@ -85,11 +83,11 @@ final class FindCheaperVehicleAlgo {
if(vehicle.getType().getTypeId().equals(vehicleRoute.getVehicle().getType().getTypeId())){
continue;
}
if(states.getRouteState(vehicleRoute).getLoad() <= vehicle.getCapacity()){
if(states.getRouteState(vehicleRoute,StateTypes.LOAD).toDouble() <= vehicle.getCapacity()){
double fixCostSaving = vehicleRoute.getVehicle().getType().getVehicleCostParams().fix - vehicle.getType().getVehicleCostParams().fix;
double departureTime = vehicleRoute.getStart().getEndTime();
double newCost = auxilliaryCostCalculator.costOfPath(path, departureTime, vehicleRoute.getDriver(), vehicle);
double varCostSaving = states.getRouteState(vehicleRoute).getCosts() - newCost;
double varCostSaving = states.getRouteState(vehicleRoute, StateTypes.COSTS).toDouble() - newCost;
double totalCostSaving = varCostSaving + weightFixCosts*fixCostSaving;
if(totalCostSaving > bestSaving){
bestSaving = totalCostSaving;

View file

@ -1,6 +1,7 @@
package algorithms;
import basics.Service;
import basics.costs.VehicleRoutingTransportCosts;
import basics.route.TourActivity;
class HardConstraints {
@ -13,7 +14,7 @@ class HardConstraints {
interface HardActivityLevelConstraint {
public boolean fulfilled(InsertionContext iFacts, TourActivity act, double arrTime);
public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime);
}
@ -41,19 +42,27 @@ class HardConstraints {
private StateManager states;
public HardTimeWindowConstraint(StateManager states) {
private VehicleRoutingTransportCosts routingCosts;
public HardTimeWindowConstraint(StateManager states, VehicleRoutingTransportCosts routingCosts) {
super();
this.states = states;
this.routingCosts = routingCosts;
}
@Override
public boolean fulfilled(InsertionContext iFacts, TourActivity act, double arrTime) {
if(arrTime > states.getActivityState(act, StateTypes.LATEST_OPERATION_START_TIME).toDouble()){
public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
double arrTimeAtNewAct = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
if(arrTimeAtNewAct > states.getActivityState(newAct, StateTypes.LATEST_OPERATION_START_TIME).toDouble()){
return false;
}
double endTimeAtNewAct = CalcUtils.getActivityEndTime(arrTimeAtNewAct, newAct);
double arrTimeAtNextAct = endTimeAtNewAct + routingCosts.getTransportTime(newAct.getLocationId(), nextAct.getLocationId(), endTimeAtNewAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
if(arrTimeAtNextAct > states.getActivityState(nextAct, StateTypes.LATEST_OPERATION_START_TIME).toDouble()){
return false;
}
return true;
}
}
}

View file

@ -4,14 +4,19 @@ import algorithms.InsertionData.NoInsertionFound;
import basics.Job;
import basics.Service;
import basics.route.ServiceActivity;
import basics.route.TourActivityFactory;
import basics.route.DefaultTourActivityFactory;
import basics.route.VehicleRoute;
class Inserter {
private InsertionListeners insertionListeners;
private TourActivityFactory activityFactory;
public Inserter(InsertionListeners insertionListeners) {
this.insertionListeners = insertionListeners;
activityFactory = new DefaultTourActivityFactory();
}
public void insertJob(Job job, InsertionData insertionData, VehicleRoute vehicleRoute){
@ -25,7 +30,7 @@ class Inserter {
}
// if(vehicleRoute.getDepartureTime() != vehicleRoute.g)
if(job instanceof Service) {
vehicleRoute.getTourActivities().addActivity(insertionData.getDeliveryInsertionIndex(), ServiceActivity.newInstance((Service)job));
vehicleRoute.getTourActivities().addActivity(insertionData.getDeliveryInsertionIndex(), activityFactory.createActivity((Service)job));
vehicleRoute.setDepartureTime(insertionData.getVehicleDepartureTime());
}
else throw new IllegalStateException("neither service nor shipment. this is not supported.");

View file

@ -21,16 +21,16 @@ class MarginalsCalculusTriangleInequality implements MarginalsCalculus{
@Override
public Marginals calculate(InsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct) {
if(!hardConstraint.fulfilled(iFacts, prevAct, newAct, nextAct, depTimeAtPrevAct)){
return null;
}
double tp_costs_prevAct_newAct = routingCosts.getTransportCost(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
double tp_time_prevAct_newAct = routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
double newAct_arrTime = depTimeAtPrevAct + tp_time_prevAct_newAct;
if(!hardConstraint.fulfilled(iFacts, newAct, newAct_arrTime)){
return null;
}
double newAct_endTime = CalcUtils.getStartTimeAtAct(newAct_arrTime, newAct);
double newAct_endTime = CalcUtils.getActivityEndTime(newAct_arrTime, newAct);
double act_costs_newAct = activityCosts.getActivityCost(newAct, newAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
@ -38,11 +38,7 @@ class MarginalsCalculusTriangleInequality implements MarginalsCalculus{
double tp_time_newAct_nextAct = routingCosts.getTransportTime(newAct.getLocationId(), nextAct.getLocationId(), newAct_endTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
double nextAct_arrTime = newAct_endTime + tp_time_newAct_nextAct;
if(!hardConstraint.fulfilled(iFacts, nextAct, nextAct_arrTime)){
return null;
}
double act_costs_nextAct = activityCosts.getActivityCost(nextAct, nextAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
double totalCosts = tp_costs_prevAct_newAct + tp_costs_newAct_nextAct + act_costs_newAct + act_costs_nextAct;

View file

@ -1,6 +1,5 @@
package algorithms;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@ -28,29 +27,29 @@ class StateManagerImpl implements StateManager{
private Map<TourActivity,States> activityStates = new HashMap<TourActivity, StateManager.States>();
public Map<VehicleRoute, States> getRouteStates() {
return Collections.unmodifiableMap(vehicleRouteStates);
}
public States getRouteStates(VehicleRoute route){
return vehicleRouteStates.get(route);
}
public void put(VehicleRoute route, States states) {
vehicleRouteStates.put(route, states);
}
public Map<TourActivity, States> getActivityStates() {
return Collections.unmodifiableMap(activityStates);
}
public States getActivityStates(TourActivity act){
return activityStates.get(act);
}
public void put(TourActivity act, States states) {
activityStates.put(act, states);
}
// Map<VehicleRoute, States> getRouteStates() {
// return Collections.unmodifiableMap(vehicleRouteStates);
// }
//
// States getRouteStates(VehicleRoute route){
// return vehicleRouteStates.get(route);
// }
//
// void put(VehicleRoute route, States states) {
// vehicleRouteStates.put(route, states);
// }
//
// Map<TourActivity, States> getActivityStates() {
// return Collections.unmodifiableMap(activityStates);
// }
//
// States getActivityStates(TourActivity act){
// return activityStates.get(act);
// }
//
// void put(TourActivity act, States states) {
// activityStates.put(act, states);
// }
public void clear(){
vehicleRouteStates.clear();
@ -90,6 +89,7 @@ class StateManagerImpl implements StateManager{
private State getDefaultRouteState(String stateType, VehicleRoute route){
if(stateType.equals(StateTypes.LOAD)) return new StateImpl(0);
if(stateType.equals(StateTypes.LOAD_AT_DEPOT)) return new StateImpl(0);
if(stateType.equals(StateTypes.COSTS)) return new StateImpl(0);
if(stateType.equals(StateTypes.DURATION)) return new StateImpl(0);
return null;

View file

@ -3,6 +3,8 @@ package algorithms;
class StateTypes {
final static String LOAD = "load";
final static String LOAD_AT_DEPOT = "loadAtDepot";
final static String DURATION = "duration";
final static String LATEST_OPERATION_START_TIME = "latestOST";