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:
parent
e6f671cbcc
commit
216df61db4
10 changed files with 90 additions and 56 deletions
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue