mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
Merge remote-tracking branch 'choose_remote_name/vrpWithBackhauls'
Conflicts: jsprit-core/src/main/java/algorithms/CalculatesServiceInsertion.java
This commit is contained in:
commit
f1bb6c7bd0
96 changed files with 17748 additions and 1121 deletions
|
|
@ -52,6 +52,8 @@
|
|||
<version>2.4.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -49,4 +69,8 @@ class BackwardInTimeListeners {
|
|||
for(BackwardInTimeListener l : listeners){ l.end(start, latestDepartureTime); }
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return listeners.isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,38 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import basics.route.TourActivity;
|
||||
|
||||
class CalcUtils {
|
||||
|
||||
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);
|
||||
|
|
@ -96,11 +102,9 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{
|
|||
TourActivity prevAct = start;
|
||||
double prevActStartTime = newVehicleDepartureTime;
|
||||
int actIndex = 0;
|
||||
|
||||
// logger.info("start");
|
||||
for(TourActivity nextAct : currentRoute.getTourActivities().getActivities()){
|
||||
if(deliveryAct2Insert.getTheoreticalLatestOperationStartTime() < prevAct.getTheoreticalEarliestOperationStartTime()){
|
||||
break;
|
||||
}
|
||||
// logger.info("prevActStartTime="+prevActStartTime);
|
||||
if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){
|
||||
Marginals mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
|
||||
if(mc != null){
|
||||
|
|
@ -111,10 +115,16 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{
|
|||
}
|
||||
}
|
||||
}
|
||||
prevActStartTime = CalcUtils.getStartTimeAtAct(prevActStartTime, transportCosts.getTransportTime(prevAct.getLocationId(), nextAct.getLocationId(), prevActStartTime, newDriver, newVehicle), nextAct);
|
||||
|
||||
double nextActArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocationId(), nextAct.getLocationId(), prevActStartTime, newDriver, newVehicle);
|
||||
double nextActEndTime = CalcUtils.getActivityEndTime(nextActArrTime, nextAct);
|
||||
|
||||
prevActStartTime = nextActEndTime;
|
||||
|
||||
prevAct = nextAct;
|
||||
actIndex++;
|
||||
}
|
||||
// logger.info("prevActStartTime="+prevActStartTime);
|
||||
End nextAct = end;
|
||||
if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){
|
||||
Marginals mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ package algorithms;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import algorithms.HardConstraints.ConstraintManager;
|
||||
import basics.VehicleRoutingProblem;
|
||||
import basics.algo.InsertionListener;
|
||||
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
|
||||
|
|
@ -81,6 +82,8 @@ class CalculatorBuilder {
|
|||
private double timeSlice;
|
||||
|
||||
private int neighbors;
|
||||
|
||||
private ConstraintManager constraintManager;
|
||||
|
||||
/**
|
||||
* Constructs the builder.
|
||||
|
|
@ -213,9 +216,11 @@ class CalculatorBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
private CalculatorPlusListeners createStandardLocal(VehicleRoutingProblem vrp, StateManager activityStates2){
|
||||
MarginalsCalculus defaultCalc = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), new HardConstraints.HardTimeWindowConstraint(activityStates2) );
|
||||
JobInsertionCalculator standardServiceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), defaultCalc, new HardConstraints.HardLoadConstraint(activityStates2));
|
||||
private CalculatorPlusListeners createStandardLocal(VehicleRoutingProblem vrp, StateManager statesManager){
|
||||
if(constraintManager == null) throw new IllegalStateException("constraint-manager is null");
|
||||
|
||||
MarginalsCalculus defaultCalc = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), constraintManager);
|
||||
JobInsertionCalculator standardServiceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), defaultCalc, constraintManager);
|
||||
|
||||
((CalculatesServiceInsertion) standardServiceInsertion).setNeighborhood(vrp.getNeighborhood());
|
||||
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(standardServiceInsertion);
|
||||
|
|
@ -246,6 +251,10 @@ class CalculatorBuilder {
|
|||
return new CalculatesVehTypeDepServiceInsertion(fleetManager, baseCalc);
|
||||
}
|
||||
|
||||
public void setConstraintManager(ConstraintManager constraintManager) {
|
||||
this.constraintManager = constraintManager;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -38,4 +58,8 @@ class ForwardInTimeListeners {
|
|||
for(ForwardInTimeListener l : listeners){ l.end(end, arrivalTime); }
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return listeners.isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,9 +32,11 @@ import java.util.Set;
|
|||
import org.apache.log4j.Logger;
|
||||
|
||||
import util.RandomNumberGeneration;
|
||||
import algorithms.RuinStrategy.RuinListener;
|
||||
import basics.Job;
|
||||
import basics.VehicleRoutingProblem;
|
||||
import basics.VehicleRoutingProblemSolution;
|
||||
import basics.algo.InsertionListener;
|
||||
import basics.algo.SearchStrategyModule;
|
||||
import basics.algo.SearchStrategyModuleListener;
|
||||
import basics.route.TourActivity;
|
||||
|
|
@ -53,8 +55,6 @@ final class Gendreau implements SearchStrategyModule{
|
|||
|
||||
private final InsertionStrategy insertionStrategy;
|
||||
|
||||
private final Inserter inserter;
|
||||
|
||||
private VehicleFleetManager fleetManager;
|
||||
|
||||
private Random random = RandomNumberGeneration.getRandom();
|
||||
|
|
@ -71,7 +71,7 @@ final class Gendreau implements SearchStrategyModule{
|
|||
super();
|
||||
InsertionListeners insertionListeners = new InsertionListeners();
|
||||
insertionListeners.addAllListeners(insertionStrategy.getListeners());
|
||||
inserter = new Inserter(insertionListeners);
|
||||
new Inserter(insertionListeners);
|
||||
this.ruin = ruin;
|
||||
this.vrp = vrp;
|
||||
this.insertionStrategy = insertionStrategy;
|
||||
|
|
@ -205,7 +205,18 @@ final class Gendreau implements SearchStrategyModule{
|
|||
|
||||
@Override
|
||||
public void addModuleListener(SearchStrategyModuleListener moduleListener) {
|
||||
// TODO Auto-generated method stub
|
||||
if(moduleListener instanceof InsertionListener){
|
||||
InsertionListener iListener = (InsertionListener) moduleListener;
|
||||
if(!insertionStrategy.getListeners().contains(iListener)){
|
||||
insertionStrategy.addListener(iListener);
|
||||
}
|
||||
}
|
||||
if(moduleListener instanceof RuinListener){
|
||||
RuinListener rListener = (RuinListener) moduleListener;
|
||||
if(!ruin.getListeners().contains(rListener)){
|
||||
ruin.addListener(rListener);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,54 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import basics.Delivery;
|
||||
import basics.Pickup;
|
||||
import basics.Service;
|
||||
import basics.costs.VehicleRoutingTransportCosts;
|
||||
import basics.route.DeliveryActivity;
|
||||
import basics.route.PickupActivity;
|
||||
import basics.route.ServiceActivity;
|
||||
import basics.route.Start;
|
||||
import basics.route.TourActivity;
|
||||
|
||||
/**
|
||||
* collection of hard constrainters bot at activity and at route level.
|
||||
*
|
||||
* <p>HardPickupAndDeliveryLoadConstraint requires LOAD_AT_DEPOT and LOAD (i.e. load at end) at route-level
|
||||
*
|
||||
* <p>HardTimeWindowConstraint requires LATEST_OPERATION_START_TIME
|
||||
*
|
||||
* <p>HardPickupAndDeliveryConstraint requires LOAD_AT_DEPOT and LOAD at route-level and FUTURE_PICKS and PAST_DELIVIERS on activity-level
|
||||
*
|
||||
* <p>HardPickupAndDeliveryBackhaulConstraint requires LOAD_AT_DEPOT and LOAD at route-level and FUTURE_PICKS and PAST_DELIVIERS on activity-level
|
||||
*
|
||||
* @author stefan
|
||||
*
|
||||
*/
|
||||
class HardConstraints {
|
||||
|
||||
interface HardRouteLevelConstraint {
|
||||
|
|
@ -13,10 +59,76 @@ 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);
|
||||
|
||||
}
|
||||
|
||||
static class HardRouteLevelConstraintManager implements HardRouteLevelConstraint {
|
||||
|
||||
private Collection<HardRouteLevelConstraint> hardConstraints = new ArrayList<HardRouteLevelConstraint>();
|
||||
|
||||
public void addConstraint(HardRouteLevelConstraint constraint){
|
||||
hardConstraints.add(constraint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(InsertionContext insertionContext) {
|
||||
for(HardRouteLevelConstraint constraint : hardConstraints){
|
||||
if(!constraint.fulfilled(insertionContext)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class ConstraintManager implements HardActivityLevelConstraint, HardRouteLevelConstraint{
|
||||
|
||||
private HardActivityLevelConstraintManager actLevelConstraintManager = new HardActivityLevelConstraintManager();
|
||||
|
||||
private HardRouteLevelConstraintManager routeLevelConstraintManager = new HardRouteLevelConstraintManager();
|
||||
|
||||
public void addConstraint(HardActivityLevelConstraint actLevelConstraint){
|
||||
actLevelConstraintManager.addConstraint(actLevelConstraint);
|
||||
}
|
||||
|
||||
public void addConstraint(HardRouteLevelConstraint routeLevelConstraint){
|
||||
routeLevelConstraintManager.addConstraint(routeLevelConstraint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(InsertionContext insertionContext) {
|
||||
return routeLevelConstraintManager.fulfilled(insertionContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct,TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||
return actLevelConstraintManager.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class HardActivityLevelConstraintManager implements HardActivityLevelConstraint {
|
||||
|
||||
private Collection<HardActivityLevelConstraint> hardConstraints = new ArrayList<HardActivityLevelConstraint>();
|
||||
|
||||
public void addConstraint(HardActivityLevelConstraint constraint){
|
||||
hardConstraints.add(constraint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||
for(HardActivityLevelConstraint constraint : hardConstraints){
|
||||
if(!constraint.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class HardLoadConstraint implements HardRouteLevelConstraint{
|
||||
|
||||
private StateManager states;
|
||||
|
|
@ -37,23 +149,163 @@ class HardConstraints {
|
|||
}
|
||||
}
|
||||
|
||||
static class HardTimeWindowConstraint implements HardActivityLevelConstraint {
|
||||
/**
|
||||
* lsjdfjsdlfjsa
|
||||
*
|
||||
* @author stefan
|
||||
*
|
||||
*/
|
||||
static class HardPickupAndDeliveryLoadConstraint implements HardRouteLevelConstraint {
|
||||
|
||||
private StateManager states;
|
||||
private StateManager stateManager;
|
||||
|
||||
public HardTimeWindowConstraint(StateManager states) {
|
||||
public HardPickupAndDeliveryLoadConstraint(StateManager stateManager) {
|
||||
super();
|
||||
this.states = states;
|
||||
this.stateManager = stateManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(InsertionContext iFacts, TourActivity act, double arrTime) {
|
||||
if(arrTime > states.getActivityState(act, StateTypes.LATEST_OPERATION_START_TIME).toDouble()){
|
||||
return false;
|
||||
public boolean fulfilled(InsertionContext insertionContext) {
|
||||
if(insertionContext.getJob() instanceof Delivery){
|
||||
int loadAtDepot = (int) stateManager.getRouteState(insertionContext.getRoute(), StateTypes.LOAD_AT_DEPOT).toDouble();
|
||||
if(loadAtDepot + insertionContext.getJob().getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(insertionContext.getJob() instanceof Pickup || insertionContext.getJob() instanceof Service){
|
||||
int loadAtEnd = (int) stateManager.getRouteState(insertionContext.getRoute(), StateTypes.LOAD).toDouble();
|
||||
if(loadAtEnd + insertionContext.getJob().getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ljsljslfjs
|
||||
* @author stefan
|
||||
*
|
||||
*/
|
||||
public static class HardTimeWindowActivityLevelConstraint implements HardActivityLevelConstraint {
|
||||
|
||||
private static Logger log = Logger.getLogger(HardTimeWindowActivityLevelConstraint.class);
|
||||
|
||||
private StateManager states;
|
||||
|
||||
private VehicleRoutingTransportCosts routingCosts;
|
||||
|
||||
public HardTimeWindowActivityLevelConstraint(StateManager states, VehicleRoutingTransportCosts routingCosts) {
|
||||
super();
|
||||
this.states = states;
|
||||
this.routingCosts = routingCosts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||
// log.info("check insertion of " + newAct + " between " + prevAct + " and " + nextAct + ". prevActDepTime=" + prevActDepTime);
|
||||
double arrTimeAtNewAct = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
||||
double latestArrTimeAtNewAct = states.getActivityState(newAct, StateTypes.LATEST_OPERATION_START_TIME).toDouble();
|
||||
if(arrTimeAtNewAct > latestArrTimeAtNewAct){
|
||||
return false;
|
||||
}
|
||||
// log.info(newAct + " arrTime=" + arrTimeAtNewAct);
|
||||
double endTimeAtNewAct = CalcUtils.getActivityEndTime(arrTimeAtNewAct, newAct);
|
||||
double arrTimeAtNextAct = endTimeAtNewAct + routingCosts.getTransportTime(newAct.getLocationId(), nextAct.getLocationId(), endTimeAtNewAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
||||
double latestArrTimeAtNextAct = states.getActivityState(nextAct, StateTypes.LATEST_OPERATION_START_TIME).toDouble();
|
||||
if(arrTimeAtNextAct > latestArrTimeAtNextAct){
|
||||
return false;
|
||||
}
|
||||
// log.info(nextAct + " arrTime=" + arrTimeAtNextAct);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static class HardPickupAndDeliveryActivityLevelConstraint implements HardActivityLevelConstraint {
|
||||
|
||||
private StateManager stateManager;
|
||||
|
||||
public HardPickupAndDeliveryActivityLevelConstraint(StateManager stateManager) {
|
||||
super();
|
||||
this.stateManager = stateManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||
int loadAtPrevAct;
|
||||
int futurePicks;
|
||||
int pastDeliveries;
|
||||
if(prevAct instanceof Start){
|
||||
loadAtPrevAct = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD_AT_DEPOT).toDouble();
|
||||
futurePicks = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD).toDouble();
|
||||
pastDeliveries = 0;
|
||||
}
|
||||
else{
|
||||
loadAtPrevAct = (int) stateManager.getActivityState(prevAct, StateTypes.LOAD).toDouble();
|
||||
futurePicks = (int) stateManager.getActivityState(prevAct, StateTypes.FUTURE_PICKS).toDouble();
|
||||
pastDeliveries = (int) stateManager.getActivityState(prevAct, StateTypes.PAST_DELIVERIES).toDouble();
|
||||
}
|
||||
if(newAct instanceof PickupActivity || newAct instanceof ServiceActivity){
|
||||
if(loadAtPrevAct + newAct.getCapacityDemand() + futurePicks > iFacts.getNewVehicle().getCapacity()){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(newAct instanceof DeliveryActivity){
|
||||
if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) + pastDeliveries > iFacts.getNewVehicle().getCapacity()){
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class HardPickupAndDeliveryBackhaulActivityLevelConstraint implements HardActivityLevelConstraint {
|
||||
|
||||
private StateManager stateManager;
|
||||
|
||||
public HardPickupAndDeliveryBackhaulActivityLevelConstraint(StateManager stateManager) {
|
||||
super();
|
||||
this.stateManager = stateManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||
if(newAct instanceof PickupActivity && nextAct instanceof DeliveryActivity){ return false; }
|
||||
if(newAct instanceof ServiceActivity && nextAct instanceof DeliveryActivity){ return false; }
|
||||
if(newAct instanceof DeliveryActivity && prevAct instanceof PickupActivity){ return false; }
|
||||
if(newAct instanceof DeliveryActivity && prevAct instanceof ServiceActivity){ return false; }
|
||||
int loadAtPrevAct;
|
||||
int futurePicks;
|
||||
int pastDeliveries;
|
||||
if(prevAct instanceof Start){
|
||||
loadAtPrevAct = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD_AT_DEPOT).toDouble();
|
||||
futurePicks = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD).toDouble();
|
||||
pastDeliveries = 0;
|
||||
}
|
||||
else{
|
||||
loadAtPrevAct = (int) stateManager.getActivityState(prevAct, StateTypes.LOAD).toDouble();
|
||||
futurePicks = (int) stateManager.getActivityState(prevAct, StateTypes.FUTURE_PICKS).toDouble();
|
||||
pastDeliveries = (int) stateManager.getActivityState(prevAct, StateTypes.PAST_DELIVERIES).toDouble();
|
||||
}
|
||||
if(newAct instanceof PickupActivity || newAct instanceof ServiceActivity){
|
||||
if(loadAtPrevAct + newAct.getCapacityDemand() + futurePicks > iFacts.getNewVehicle().getCapacity()){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(newAct instanceof DeliveryActivity){
|
||||
if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) + pastDeliveries > iFacts.getNewVehicle().getCapacity()){
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,42 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
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 +50,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.");
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import basics.Job;
|
||||
|
|
|
|||
|
|
@ -25,11 +25,11 @@ import java.util.List;
|
|||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.apache.commons.configuration.HierarchicalConfiguration;
|
||||
import org.apache.commons.configuration.XMLConfiguration;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import algorithms.HardConstraints.ConstraintManager;
|
||||
import algorithms.StateUpdates.UpdateStates;
|
||||
import basics.VehicleRoutingProblem;
|
||||
import basics.VehicleRoutingProblem.FleetComposition;
|
||||
import basics.algo.InsertionListener;
|
||||
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ class InsertionFactory {
|
|||
private static Logger log = Logger.getLogger(InsertionFactory.class);
|
||||
|
||||
public static InsertionStrategy createInsertion(VehicleRoutingProblem vrp, HierarchicalConfiguration config,
|
||||
VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads){
|
||||
VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager){
|
||||
boolean concurrentInsertion = false;
|
||||
if(executorService != null) concurrentInsertion = true;
|
||||
if(config.containsKey("[@name]")){
|
||||
|
|
@ -54,6 +54,7 @@ class InsertionFactory {
|
|||
calcBuilder.setStates(routeStates);
|
||||
calcBuilder.setVehicleRoutingProblem(vrp);
|
||||
calcBuilder.setVehicleFleetManager(vehicleFleetManager);
|
||||
calcBuilder.setConstraintManager(constraintManager);
|
||||
|
||||
if(config.containsKey("level")){
|
||||
String level = config.getString("level");
|
||||
|
|
@ -103,13 +104,13 @@ class InsertionFactory {
|
|||
// insertionStrategy = RegretInsertion.newInstance(routeAlgorithm);
|
||||
// }
|
||||
|
||||
insertionStrategy.addListener(new RemoveEmptyVehicles(vehicleFleetManager));
|
||||
insertionStrategy.addListener(new ResetAndIniFleetManager(vehicleFleetManager));
|
||||
insertionStrategy.addListener(new VehicleSwitched(vehicleFleetManager));
|
||||
// insertionStrategy.addListener(new RemoveEmptyVehicles(vehicleFleetManager));
|
||||
// insertionStrategy.addListener(new ResetAndIniFleetManager(vehicleFleetManager));
|
||||
// insertionStrategy.addListener(new VehicleSwitched(vehicleFleetManager));
|
||||
|
||||
// insertionStrategy.addListener(new UpdateLoadAtRouteLevel(routeStates));
|
||||
|
||||
insertionStrategy.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
|
||||
// insertionStrategy.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
|
||||
for(InsertionListener l : insertionListeners) insertionStrategy.addListener(l);
|
||||
// insertionStrategy.addListener(new FindCheaperVehicle(
|
||||
// new FindCheaperVehicleAlgoNew(vehicleFleetManager, tourStateCalculator, auxCalculator)));
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ class IterateRouteBackwardInTime implements VehicleRouteUpdater{
|
|||
*
|
||||
*/
|
||||
public void iterate(VehicleRoute vehicleRoute) {
|
||||
if(listeners.isEmpty()) return;
|
||||
listeners.start(vehicleRoute, vehicleRoute.getEnd(), vehicleRoute.getEnd().getTheoreticalLatestOperationStartTime());
|
||||
|
||||
Iterator<TourActivity> reverseActIter = vehicleRoute.getTourActivities().reverseActivityIterator();
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ class IterateRouteForwardInTime implements VehicleRouteUpdater{
|
|||
*
|
||||
*/
|
||||
public void iterate(VehicleRoute vehicleRoute) {
|
||||
if(listeners.isEmpty()) return;
|
||||
listeners.start(vehicleRoute, vehicleRoute.getStart(), vehicleRoute.getStart().getEndTime());
|
||||
|
||||
Vehicle vehicle = vehicleRoute.getVehicle();
|
||||
|
|
|
|||
|
|
@ -1,156 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import algorithms.RouteStates.ActivityState;
|
||||
import basics.algo.AlgorithmEndsListener;
|
||||
import basics.algo.JobInsertedListener;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.VehicleRoute;
|
||||
import basics.route.TourActivity.JobActivity;
|
||||
import basics.Job;
|
||||
import basics.Service;
|
||||
import basics.VehicleRoutingProblem;
|
||||
import basics.VehicleRoutingProblemSolution;
|
||||
|
||||
class JobObserver implements JobInsertedListener, BeforeJobInsertionListener, AlgorithmEndsListener{
|
||||
|
||||
private static class Info {
|
||||
double depTime;
|
||||
double tourSize;
|
||||
double insertionIndex;
|
||||
double error;
|
||||
public Info(double depTime, double tourSize, double insertionIndex,
|
||||
double error) {
|
||||
super();
|
||||
this.depTime = depTime;
|
||||
this.tourSize = tourSize;
|
||||
this.insertionIndex = insertionIndex;
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String locationId = "70";
|
||||
|
||||
private double routeCostBefore;
|
||||
private double estimatedMC;
|
||||
private boolean beforeFirst = false;
|
||||
|
||||
private RouteStates actStates;
|
||||
|
||||
public void setActivityStates(RouteStates actStates){
|
||||
this.actStates = actStates;
|
||||
}
|
||||
|
||||
public ActivityState state(TourActivity act){
|
||||
return actStates.getState(act);
|
||||
}
|
||||
|
||||
|
||||
Collection<Info> infos = new ArrayList<Info>();
|
||||
|
||||
@Override
|
||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||
if(job2insert instanceof Service){
|
||||
if(((Service) job2insert).getLocationId().equals(locationId)){
|
||||
double actualMC = inRoute.getCost()-routeCostBefore;
|
||||
TourActivity act = getAct(job2insert,inRoute);
|
||||
double error = (estimatedMC-actualMC);
|
||||
int tourSize = inRoute.getTourActivities().getActivities().size();
|
||||
int insertionIndex = getIndexOf(job2insert, inRoute);
|
||||
// infos.add(new Info())
|
||||
double depTime = state(act).getEarliestOperationStart()+act.getOperationTime();
|
||||
infos.add(new Info(depTime,tourSize,insertionIndex,error));
|
||||
// System.out.println("[id=1][tourSize="+tourSize+"][index="+insertionIndex+
|
||||
// "][earliestDeparture="+depTime+
|
||||
// "][tourCostBefore="+routeCostBefore+"][routeCostAfter="+insertedIn.getCost()+"]" +
|
||||
// "[estimated="+Math.round(estimatedMC)+"][actual="+Math.round(actualMC)+"][error(abs)="+error +
|
||||
// "][errorPerNextCustomer="+ (error/(double)(tourSize-insertionIndex)) + "]");
|
||||
routeCostBefore = 0.0;
|
||||
estimatedMC = 0.0;
|
||||
if(!beforeFirst) throw new IllegalStateException("ähhh");
|
||||
beforeFirst = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private TourActivity getAct(Job job2insert, VehicleRoute insertedIn) {
|
||||
for(TourActivity act : insertedIn.getTourActivities().getActivities()){
|
||||
if(act instanceof JobActivity){
|
||||
if(((JobActivity) act).getJob().getId().equals(job2insert.getId())){
|
||||
return act;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int getIndexOf(Job job2insert, VehicleRoute insertedIn) {
|
||||
int index=0;
|
||||
for(TourActivity act : insertedIn.getTourActivities().getActivities()){
|
||||
if(act instanceof JobActivity){
|
||||
if(((JobActivity) act).getJob().getId().equals(job2insert.getId())){
|
||||
return index;
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informBeforeJobInsertion(Job job, InsertionData data, VehicleRoute route) {
|
||||
if(job instanceof Service){
|
||||
if(((Service) job).getLocationId().equals(locationId)){
|
||||
// System.out.println("[id=1][tourSize="+route.getTour().getActivities().size()+"][tourCost="+route.getCost()+"]" +
|
||||
// "[estimatedMarginalInsertionCost="+data.getInsertionCost()+"]");
|
||||
routeCostBefore = route.getCost();
|
||||
estimatedMC = data.getInsertionCost();
|
||||
beforeFirst = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||
try {
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter("output/errorAna.txt"));
|
||||
for(Info info : infos){
|
||||
writer.write(new StringBuilder().append(info.depTime).append(";").append(info.tourSize).append(";").append(info.insertionIndex).append(";")
|
||||
.append(info.error).append("\n").toString());
|
||||
}
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import basics.route.TourActivity;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import algorithms.HardConstraints.HardActivityLevelConstraint;
|
||||
|
|
@ -21,16 +41,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 +58,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,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
///*******************************************************************************
|
||||
// * Copyright (c) 2011 Stefan Schroeder.
|
||||
// * eMail: stefan.schroeder@kit.edu
|
||||
|
|
|
|||
|
|
@ -1,208 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import basics.Job;
|
||||
import basics.Service;
|
||||
import basics.VehicleRoutingProblem;
|
||||
import basics.VehicleRoutingProblemSolution;
|
||||
import basics.algo.AlgorithmEndsListener;
|
||||
import basics.algo.IterationEndsListener;
|
||||
import basics.algo.IterationStartsListener;
|
||||
import basics.route.ServiceActivity;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
class RouteStates implements IterationStartsListener{
|
||||
|
||||
Logger log = Logger.getLogger(RouteStates.class);
|
||||
|
||||
static class RouteState {
|
||||
private double costs;
|
||||
private int load;
|
||||
private VehicleRoute route;
|
||||
public RouteState(VehicleRoute route) {
|
||||
super();
|
||||
this.route = route;
|
||||
}
|
||||
/**
|
||||
* @return the costs
|
||||
*/
|
||||
public double getCosts() {
|
||||
return costs;
|
||||
}
|
||||
/**
|
||||
* @param costs the costs to set
|
||||
*/
|
||||
public void setCosts(double costs) {
|
||||
this.costs = costs;
|
||||
}
|
||||
/**
|
||||
* @return the load
|
||||
*/
|
||||
public int getLoad() {
|
||||
return load;
|
||||
}
|
||||
/**
|
||||
* @param load the load to set
|
||||
*/
|
||||
public void setLoad(int load) {
|
||||
this.load = load;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class ActivityState {
|
||||
private double earliestOperationStart;
|
||||
private double latestOperationStart;
|
||||
private double currentLoad;
|
||||
private double currentCost;
|
||||
private TourActivity act;
|
||||
|
||||
public ActivityState(TourActivity activity){
|
||||
this.earliestOperationStart=activity.getTheoreticalEarliestOperationStartTime();
|
||||
this.latestOperationStart=activity.getTheoreticalLatestOperationStartTime();
|
||||
this.act = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[earliestStart="+earliestOperationStart+"][latestStart="+
|
||||
latestOperationStart+"][currLoad="+currentLoad+"][currCost="+currentCost+"]";
|
||||
}
|
||||
|
||||
public double getEarliestOperationStart() {
|
||||
return earliestOperationStart;
|
||||
}
|
||||
|
||||
void setEarliestOperationStart(double earliestOperationStart) {
|
||||
this.earliestOperationStart = earliestOperationStart;
|
||||
}
|
||||
|
||||
public double getLatestOperationStart() {
|
||||
return latestOperationStart;
|
||||
}
|
||||
|
||||
void setLatestOperationStart(double latestOperationStart) {
|
||||
this.latestOperationStart = latestOperationStart;
|
||||
}
|
||||
|
||||
public double getCurrentLoad() {
|
||||
return currentLoad;
|
||||
}
|
||||
|
||||
void setCurrentLoad(double currentLoad) {
|
||||
this.currentLoad = currentLoad;
|
||||
}
|
||||
|
||||
public double getCurrentCost() {
|
||||
return currentCost;
|
||||
}
|
||||
|
||||
void setCurrentCost(double currentCost) {
|
||||
this.currentCost = currentCost;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
earliestOperationStart = act.getTheoreticalEarliestOperationStartTime();
|
||||
latestOperationStart = act.getTheoreticalLatestOperationStartTime() ;
|
||||
currentLoad = 0.0;
|
||||
currentCost = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Map<TourActivity, ActivityState> activityStates;
|
||||
|
||||
private Map<Service, TourActivity> tourActivities;
|
||||
|
||||
private Map<VehicleRoute, RouteState> routeStates;
|
||||
|
||||
public RouteStates() {
|
||||
activityStates = new HashMap<TourActivity, RouteStates.ActivityState>();
|
||||
tourActivities = new HashMap<Service,TourActivity>();
|
||||
routeStates = new HashMap<VehicleRoute, RouteStates.RouteState>();
|
||||
}
|
||||
|
||||
ActivityState getState(TourActivity act){
|
||||
if(!activityStates.containsKey(act)) return null;
|
||||
return activityStates.get(act);
|
||||
}
|
||||
|
||||
public void clearStates(){
|
||||
activityStates.clear();
|
||||
}
|
||||
|
||||
public Map<TourActivity, ActivityState> getActivityStates() {
|
||||
return activityStates;
|
||||
}
|
||||
|
||||
TourActivity getActivity(Service service, boolean resetState){
|
||||
TourActivity tourActivity = tourActivities.get(service);
|
||||
getState(tourActivity).reset();
|
||||
return tourActivity;
|
||||
}
|
||||
|
||||
public void resetRouteStates(){
|
||||
routeStates.clear();
|
||||
}
|
||||
|
||||
public RouteState getRouteState(VehicleRoute route){
|
||||
RouteState routeState = routeStates.get(route);
|
||||
if(routeState == null){
|
||||
routeState = new RouteState(route);
|
||||
putRouteState(route, routeState);
|
||||
}
|
||||
return routeState;
|
||||
}
|
||||
|
||||
private void putRouteState(VehicleRoute route, RouteState routeState){
|
||||
routeStates.put(route, routeState);
|
||||
}
|
||||
|
||||
void initialiseStateOfJobs(Collection<Job> jobs){
|
||||
for(Job job : jobs){
|
||||
if(job instanceof Service){
|
||||
ServiceActivity service = ServiceActivity.newInstance((Service)job);
|
||||
ActivityState state = new ActivityState(service);
|
||||
tourActivities.put((Service) job, service);
|
||||
activityStates.put(service, state);
|
||||
}
|
||||
else{
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||
resetRouteStates();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import java.util.Collection;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import basics.route.TourActivity;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,25 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -28,30 +47,6 @@ 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);
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
vehicleRouteStates.clear();
|
||||
activityStates.clear();
|
||||
|
|
@ -85,11 +80,14 @@ class StateManagerImpl implements StateManager{
|
|||
if(stateType.equals(StateTypes.DURATION)) return new StateImpl(0);
|
||||
if(stateType.equals(StateTypes.EARLIEST_OPERATION_START_TIME)) return new StateImpl(act.getTheoreticalEarliestOperationStartTime());
|
||||
if(stateType.equals(StateTypes.LATEST_OPERATION_START_TIME)) return new StateImpl(act.getTheoreticalLatestOperationStartTime());
|
||||
if(stateType.equals(StateTypes.FUTURE_PICKS)) return new StateImpl(0);
|
||||
if(stateType.equals(StateTypes.PAST_DELIVERIES)) return new StateImpl(0);
|
||||
return null;
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,39 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
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";
|
||||
|
||||
final static String EARLIEST_OPERATION_START_TIME = "earliestOST";
|
||||
|
||||
public static final String COSTS = "costs";
|
||||
static final String COSTS = "costs";
|
||||
|
||||
final static String FUTURE_PICKS = "futurePicks";
|
||||
|
||||
final static String PAST_DELIVERIES = "pastDeliveries";
|
||||
}
|
||||
|
|
|
|||
678
jsprit-core/src/main/java/algorithms/StateUpdates.java
Normal file
678
jsprit-core/src/main/java/algorithms/StateUpdates.java
Normal file
|
|
@ -0,0 +1,678 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import algorithms.BackwardInTimeListeners.BackwardInTimeListener;
|
||||
import algorithms.ForwardInTimeListeners.ForwardInTimeListener;
|
||||
import algorithms.RuinStrategy.RuinListener;
|
||||
import algorithms.StateManager.StateImpl;
|
||||
import basics.Delivery;
|
||||
import basics.Job;
|
||||
import basics.Pickup;
|
||||
import basics.Service;
|
||||
import basics.VehicleRoutingProblem;
|
||||
import basics.VehicleRoutingProblemSolution;
|
||||
import basics.algo.InsertionEndsListener;
|
||||
import basics.algo.InsertionStartsListener;
|
||||
import basics.algo.IterationEndsListener;
|
||||
import basics.algo.IterationStartsListener;
|
||||
import basics.algo.JobInsertedListener;
|
||||
import basics.algo.VehicleRoutingAlgorithmListener;
|
||||
import basics.costs.ForwardTransportCost;
|
||||
import basics.costs.VehicleRoutingActivityCosts;
|
||||
import basics.costs.VehicleRoutingTransportCosts;
|
||||
import basics.route.DeliveryActivity;
|
||||
import basics.route.End;
|
||||
import basics.route.PickupActivity;
|
||||
import basics.route.ServiceActivity;
|
||||
import basics.route.Start;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
class StateUpdates {
|
||||
|
||||
static class VRAListenersManager implements IterationStartsListener, IterationEndsListener, InsertionStartsListener, InsertionEndsListener, JobInsertedListener, RuinListener{
|
||||
|
||||
private Map<Class<? extends VehicleRoutingAlgorithmListener>,Collection<VehicleRoutingAlgorithmListener>> listeners = new HashMap<Class<? extends VehicleRoutingAlgorithmListener>,Collection<VehicleRoutingAlgorithmListener>>();
|
||||
|
||||
public void addListener(VehicleRoutingAlgorithmListener vraListener){
|
||||
if(!listeners.containsKey(vraListener.getClass())){
|
||||
listeners.put(vraListener.getClass(), new ArrayList<VehicleRoutingAlgorithmListener>());
|
||||
}
|
||||
listeners.get(vraListener.getClass()).add(vraListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ruinStarts(Collection<VehicleRoute> routes) {
|
||||
if(listeners.containsKey(RuinListener.class)){
|
||||
for(VehicleRoutingAlgorithmListener l : listeners.get(RuinListener.class)){
|
||||
((RuinListener)l).ruinStarts(routes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ruinEnds(Collection<VehicleRoute> routes,Collection<Job> unassignedJobs) {
|
||||
if(listeners.containsKey(RuinListener.class)){
|
||||
for(VehicleRoutingAlgorithmListener l : listeners.get(RuinListener.class)){
|
||||
((RuinListener)l).ruinEnds(routes,unassignedJobs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed(Job job, VehicleRoute fromRoute) {
|
||||
if(listeners.containsKey(RuinListener.class)){
|
||||
for(VehicleRoutingAlgorithmListener l : listeners.get(RuinListener.class)){
|
||||
((RuinListener)l).removed(job, fromRoute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||
if(listeners.containsKey(JobInsertedListener.class)){
|
||||
for(VehicleRoutingAlgorithmListener l : listeners.get(RuinListener.class)){
|
||||
((JobInsertedListener)l).informJobInserted(job2insert, inRoute, additionalCosts, additionalTime);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informInsertionEnds(Collection<VehicleRoute> vehicleRoutes) {
|
||||
// if(listeners.containsKey(JobInsertedListener.class)){
|
||||
// for(VehicleRoutingAlgorithmListener l : listeners.get(RuinListener.class)){
|
||||
// ((JobInsertedListener)l).informJobInserted(job2insert, inRoute, additionalCosts, additionalTime);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes,Collection<Job> unassignedJobs) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informIterationEnds(int i, VehicleRoutingProblem problem,Collection<VehicleRoutingProblemSolution> solutions) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informIterationStarts(int i, VehicleRoutingProblem problem,Collection<VehicleRoutingProblemSolution> solutions) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class UpdateCostsAtRouteLevel implements JobInsertedListener, InsertionStartsListener, InsertionEndsListener{
|
||||
|
||||
private StateManagerImpl states;
|
||||
|
||||
private VehicleRoutingTransportCosts tpCosts;
|
||||
|
||||
private VehicleRoutingActivityCosts actCosts;
|
||||
|
||||
public UpdateCostsAtRouteLevel(StateManagerImpl states, VehicleRoutingTransportCosts tpCosts, VehicleRoutingActivityCosts actCosts) {
|
||||
super();
|
||||
this.states = states;
|
||||
this.tpCosts = tpCosts;
|
||||
this.actCosts = actCosts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||
// inRoute.getVehicleRouteCostCalculator().addTransportCost(additionalCosts);
|
||||
double oldCosts = states.getRouteState(inRoute, StateTypes.COSTS).toDouble();
|
||||
oldCosts += additionalCosts;
|
||||
states.putRouteState(inRoute, StateTypes.COSTS, new StateImpl(oldCosts));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(tpCosts);
|
||||
forwardInTime.addListener(new UpdateCostsAtAllLevels(actCosts, tpCosts, states));
|
||||
for(VehicleRoute route : vehicleRoutes){
|
||||
forwardInTime.iterate(route);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informInsertionEnds(Collection<VehicleRoute> vehicleRoutes) {
|
||||
|
||||
// IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(tpCosts);
|
||||
// forwardInTime.addListener(new UpdateCostsAtAllLevels(actCosts, tpCosts, states));
|
||||
for(VehicleRoute route : vehicleRoutes){
|
||||
if(route.isEmpty()) continue;
|
||||
route.getVehicleRouteCostCalculator().reset();
|
||||
route.getVehicleRouteCostCalculator().addOtherCost(states.getRouteState(route, StateTypes.COSTS).toDouble());
|
||||
route.getVehicleRouteCostCalculator().price(route.getVehicle());
|
||||
// forwardInTime.iterate(route);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class UpdateActivityTimes implements ForwardInTimeListener{
|
||||
|
||||
private Logger log = Logger.getLogger(UpdateActivityTimes.class);
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, Start start, double departureTime) {
|
||||
start.setEndTime(departureTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
||||
act.setArrTime(arrTime);
|
||||
act.setEndTime(endTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(End end, double arrivalTime) {
|
||||
end.setArrTime(arrivalTime);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class UpdateCostsAtAllLevels implements ForwardInTimeListener{
|
||||
|
||||
private static Logger log = Logger.getLogger(UpdateCostsAtAllLevels.class);
|
||||
|
||||
private VehicleRoutingActivityCosts activityCost;
|
||||
|
||||
private ForwardTransportCost transportCost;
|
||||
|
||||
private StateManagerImpl states;
|
||||
|
||||
private double totalOperationCost = 0.0;
|
||||
|
||||
private VehicleRoute vehicleRoute = null;
|
||||
|
||||
private TourActivity prevAct = null;
|
||||
|
||||
private double startTimeAtPrevAct = 0.0;
|
||||
|
||||
public UpdateCostsAtAllLevels(VehicleRoutingActivityCosts activityCost, ForwardTransportCost transportCost, StateManagerImpl states) {
|
||||
super();
|
||||
this.activityCost = activityCost;
|
||||
this.transportCost = transportCost;
|
||||
this.states = states;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, Start start, double departureTime) {
|
||||
vehicleRoute = route;
|
||||
vehicleRoute.getVehicleRouteCostCalculator().reset();
|
||||
prevAct = start;
|
||||
startTimeAtPrevAct = departureTime;
|
||||
// log.info(start + " depTime=" + departureTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
||||
// log.info(act + " job " + ((JobActivity)act).getJob().getId() + " arrTime=" + arrTime + " endTime=" + endTime);
|
||||
double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), act.getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
double actCost = activityCost.getActivityCost(act, arrTime, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
|
||||
vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost);
|
||||
vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost);
|
||||
|
||||
if(transportCost > 10000 || actCost > 100000){
|
||||
throw new IllegalStateException("aaaääähh");
|
||||
}
|
||||
|
||||
totalOperationCost += transportCost;
|
||||
totalOperationCost += actCost;
|
||||
|
||||
states.putActivityState(act, StateTypes.COSTS, new StateImpl(totalOperationCost));
|
||||
|
||||
prevAct = act;
|
||||
startTimeAtPrevAct = endTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(End end, double arrivalTime) {
|
||||
// log.info(end + " arrTime=" + arrivalTime);
|
||||
double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), end.getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
double actCost = activityCost.getActivityCost(end, arrivalTime, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
|
||||
vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost);
|
||||
vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost);
|
||||
|
||||
if(transportCost > 10000 || actCost > 100000){
|
||||
throw new IllegalStateException("aaaääähh");
|
||||
}
|
||||
|
||||
totalOperationCost += transportCost;
|
||||
totalOperationCost += actCost;
|
||||
|
||||
states.putRouteState(vehicleRoute, StateTypes.COSTS, new StateImpl(totalOperationCost));
|
||||
|
||||
//this is rather strange and likely to change
|
||||
vehicleRoute.getVehicleRouteCostCalculator().price(vehicleRoute.getDriver());
|
||||
vehicleRoute.getVehicleRouteCostCalculator().price(vehicleRoute.getVehicle());
|
||||
vehicleRoute.getVehicleRouteCostCalculator().finish();
|
||||
|
||||
startTimeAtPrevAct = 0.0;
|
||||
prevAct = null;
|
||||
vehicleRoute = null;
|
||||
totalOperationCost = 0.0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class UpdateEarliestStartTimeWindowAtActLocations implements ForwardInTimeListener{
|
||||
|
||||
private StateManagerImpl states;
|
||||
|
||||
public UpdateEarliestStartTimeWindowAtActLocations(StateManagerImpl states) {
|
||||
super();
|
||||
this.states = states;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, Start start, double departureTime) {}
|
||||
|
||||
@Override
|
||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
||||
states.putActivityState(act, StateTypes.EARLIEST_OPERATION_START_TIME, new StateImpl(Math.max(arrTime, act.getTheoreticalEarliestOperationStartTime())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(End end, double arrivalTime) {}
|
||||
|
||||
}
|
||||
|
||||
static class UpdateLatestOperationStartTimeAtActLocations implements BackwardInTimeListener{
|
||||
|
||||
private static Logger log = Logger.getLogger(UpdateLatestOperationStartTimeAtActLocations.class);
|
||||
|
||||
private StateManagerImpl states;
|
||||
|
||||
public UpdateLatestOperationStartTimeAtActLocations(StateManagerImpl states) {
|
||||
super();
|
||||
this.states = states;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, End end, double latestArrivalTime) {}
|
||||
|
||||
@Override
|
||||
public void prevActivity(TourActivity act,double latestDepartureTime, double latestOperationStartTime) {
|
||||
// log.info(act + " jobId=" + ((JobActivity)act).getJob().getId() + " " + latestOperationStartTime);
|
||||
states.putActivityState(act, StateTypes.LATEST_OPERATION_START_TIME, new StateImpl(latestOperationStartTime));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(Start start, double latestDepartureTime) {}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
static class UpdateLoadAtAllLevels implements ForwardInTimeListener{
|
||||
|
||||
private double load = 0.0;
|
||||
|
||||
private StateManagerImpl states;
|
||||
|
||||
private VehicleRoute vehicleRoute;
|
||||
|
||||
public UpdateLoadAtAllLevels(StateManagerImpl states) {
|
||||
super();
|
||||
this.states = states;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, Start start, double departureTime) { vehicleRoute = route; }
|
||||
|
||||
@Override
|
||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
||||
load += (double)act.getCapacityDemand();
|
||||
states.putActivityState(act, StateTypes.LOAD, new StateImpl(load));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(End end, double arrivalTime) {
|
||||
states.putRouteState(vehicleRoute, StateTypes.LOAD, new StateImpl(load));
|
||||
load=0;
|
||||
vehicleRoute = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class UpdateLoadAtRouteLevel implements JobInsertedListener, InsertionStartsListener{
|
||||
|
||||
private StateManagerImpl states;
|
||||
|
||||
public UpdateLoadAtRouteLevel(StateManagerImpl states) {
|
||||
super();
|
||||
this.states = states;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||
if(!(job2insert instanceof Service)){
|
||||
return;
|
||||
}
|
||||
double oldLoad = states.getRouteState(inRoute, StateTypes.LOAD).toDouble();
|
||||
states.putRouteState(inRoute, StateTypes.LOAD, new StateImpl(oldLoad + job2insert.getCapacityDemand()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||
for(VehicleRoute route : vehicleRoutes){
|
||||
int load = 0;
|
||||
for(Job j : route.getTourActivities().getJobs()){
|
||||
load += j.getCapacityDemand();
|
||||
}
|
||||
states.putRouteState(route, StateTypes.LOAD, new StateImpl(load));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class UpdateStates implements JobInsertedListener, RuinListener{
|
||||
|
||||
private IterateRouteForwardInTime iterateForward;
|
||||
|
||||
private IterateRouteBackwardInTime iterateBackward;
|
||||
|
||||
public UpdateStates(StateManagerImpl states, VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts activityCosts) {
|
||||
|
||||
iterateForward = new IterateRouteForwardInTime(routingCosts);
|
||||
iterateForward.addListener(new UpdateActivityTimes());
|
||||
iterateForward.addListener(new UpdateCostsAtAllLevels(activityCosts, routingCosts, states));
|
||||
iterateForward.addListener(new UpdateLoadAtAllLevels(states));
|
||||
// iterateForward.addListener(new UpdateEarliestStartTimeWindowAtActLocations(states));
|
||||
|
||||
iterateBackward = new IterateRouteBackwardInTime(routingCosts);
|
||||
iterateBackward.addListener(new UpdateLatestOperationStartTimeAtActLocations(states));
|
||||
}
|
||||
|
||||
public void update(VehicleRoute route){
|
||||
iterateForward.iterate(route);
|
||||
iterateBackward.iterate(route);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||
iterateForward.iterate(inRoute);
|
||||
iterateBackward.iterate(inRoute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ruinStarts(Collection<VehicleRoute> routes) {}
|
||||
|
||||
@Override
|
||||
public void ruinEnds(Collection<VehicleRoute> routes,Collection<Job> unassignedJobs) {
|
||||
for(VehicleRoute route : routes) {
|
||||
iterateForward.iterate(route);
|
||||
iterateBackward.iterate(route);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed(Job job, VehicleRoute fromRoute) {}
|
||||
|
||||
}
|
||||
|
||||
static class UpdateFuturePickupsAtActivityLevel implements BackwardInTimeListener {
|
||||
private StateManagerImpl stateManager;
|
||||
private int futurePicks = 0;
|
||||
private VehicleRoute route;
|
||||
|
||||
public UpdateFuturePickupsAtActivityLevel(StateManagerImpl stateManager) {
|
||||
super();
|
||||
this.stateManager = stateManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, End end, double latestArrivalTime) {
|
||||
this.route = route;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prevActivity(TourActivity act, double latestDepartureTime, double latestOperationStartTime) {
|
||||
stateManager.putActivityState(act, StateTypes.FUTURE_PICKS, new StateImpl(futurePicks));
|
||||
if(act instanceof PickupActivity || act instanceof ServiceActivity){
|
||||
futurePicks += act.getCapacityDemand();
|
||||
}
|
||||
assert futurePicks <= route.getVehicle().getCapacity() : "sum of pickups must not be > vehicleCap";
|
||||
assert futurePicks >= 0 : "sum of pickups must not < 0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(Start start, double latestDepartureTime) {
|
||||
futurePicks = 0;
|
||||
route = null;
|
||||
}
|
||||
}
|
||||
|
||||
static class UpdateOccuredDeliveriesAtActivityLevel implements ForwardInTimeListener {
|
||||
private StateManagerImpl stateManager;
|
||||
private int deliveries = 0;
|
||||
private VehicleRoute route;
|
||||
|
||||
public UpdateOccuredDeliveriesAtActivityLevel(StateManagerImpl stateManager) {
|
||||
super();
|
||||
this.stateManager = stateManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, Start start, double departureTime) {
|
||||
this.route = route;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
||||
if(act instanceof DeliveryActivity){
|
||||
deliveries += Math.abs(act.getCapacityDemand());
|
||||
}
|
||||
stateManager.putActivityState(act, StateTypes.PAST_DELIVERIES, new StateImpl(deliveries));
|
||||
assert deliveries >= 0 : "deliveries < 0";
|
||||
assert deliveries <= route.getVehicle().getCapacity() : "deliveries > vehicleCap";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(End end, double arrivalTime) {
|
||||
deliveries = 0;
|
||||
route = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates load at activity level. Note that this assumed that StateTypes.LOAD_AT_DEPOT is already updated, i.e. it starts by setting loadAtDepot to StateTypes.LOAD_AT_DEPOT.
|
||||
* If StateTypes.LOAD_AT_DEPOT is not set, it starts with 0 load at depot.
|
||||
*
|
||||
* @author stefan
|
||||
*
|
||||
*/
|
||||
static class UpdateLoadAtActivityLevel implements ForwardInTimeListener {
|
||||
private StateManagerImpl stateManager;
|
||||
private int currentLoad = 0;
|
||||
private VehicleRoute route;
|
||||
|
||||
public UpdateLoadAtActivityLevel(StateManagerImpl stateManager) {
|
||||
super();
|
||||
this.stateManager = stateManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, Start start, double departureTime) {
|
||||
currentLoad = (int) stateManager.getRouteState(route, StateTypes.LOAD_AT_DEPOT).toDouble();
|
||||
this.route = route;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
||||
currentLoad += act.getCapacityDemand();
|
||||
stateManager.putActivityState(act, StateTypes.LOAD, new StateImpl(currentLoad));
|
||||
assert currentLoad <= route.getVehicle().getCapacity() : "currentLoad at activity must not be > vehicleCapacity";
|
||||
assert currentLoad >= 0 : "currentLoad at act must not be < 0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(End end, double arrivalTime) {
|
||||
currentLoad = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static class ResetStateManager implements IterationStartsListener {
|
||||
|
||||
private StateManagerImpl stateManager;
|
||||
|
||||
public ResetStateManager(StateManagerImpl stateManager) {
|
||||
super();
|
||||
this.stateManager = stateManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||
stateManager.clear();
|
||||
}
|
||||
}
|
||||
|
||||
static interface InsertionStarts {
|
||||
|
||||
void insertionStarts(VehicleRoute route);
|
||||
|
||||
}
|
||||
|
||||
static class UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts implements InsertionStarts {
|
||||
|
||||
private StateManagerImpl stateManager;
|
||||
|
||||
public UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(StateManagerImpl stateManager) {
|
||||
super();
|
||||
this.stateManager = stateManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertionStarts(VehicleRoute route) {
|
||||
int loadAtDepot = 0;
|
||||
int loadAtEnd = 0;
|
||||
for(Job j : route.getTourActivities().getJobs()){
|
||||
if(j instanceof Delivery){
|
||||
loadAtDepot += j.getCapacityDemand();
|
||||
}
|
||||
else if(j instanceof Pickup || j instanceof Service){
|
||||
loadAtEnd += j.getCapacityDemand();
|
||||
}
|
||||
}
|
||||
stateManager.putRouteState(route, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot));
|
||||
stateManager.putRouteState(route, StateTypes.LOAD, new StateImpl(loadAtEnd));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted implements JobInsertedListener {
|
||||
|
||||
private StateManagerImpl stateManager;
|
||||
|
||||
public UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(StateManagerImpl stateManager) {
|
||||
super();
|
||||
this.stateManager = stateManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||
if(job2insert instanceof Delivery){
|
||||
int loadAtDepot = (int) stateManager.getRouteState(inRoute, StateTypes.LOAD_AT_DEPOT).toDouble();
|
||||
// log.info("loadAtDepot="+loadAtDepot);
|
||||
stateManager.putRouteState(inRoute, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot + job2insert.getCapacityDemand()));
|
||||
}
|
||||
else if(job2insert instanceof Pickup || job2insert instanceof Service){
|
||||
int loadAtEnd = (int) stateManager.getRouteState(inRoute, StateTypes.LOAD).toDouble();
|
||||
// log.info("loadAtEnd="+loadAtEnd);
|
||||
stateManager.putRouteState(inRoute, StateTypes.LOAD, new StateImpl(loadAtEnd + job2insert.getCapacityDemand()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class UpdateRouteStatesOnceTheRouteHasBeenChanged implements InsertionStartsListener, JobInsertedListener {
|
||||
|
||||
private IterateRouteForwardInTime forwardInTimeIterator;
|
||||
|
||||
private IterateRouteBackwardInTime backwardInTimeIterator;
|
||||
|
||||
private Collection<InsertionStarts> insertionStartsListeners;
|
||||
|
||||
private Collection<JobInsertedListener> jobInsertionListeners;
|
||||
|
||||
public UpdateRouteStatesOnceTheRouteHasBeenChanged(VehicleRoutingTransportCosts routingCosts) {
|
||||
forwardInTimeIterator = new IterateRouteForwardInTime(routingCosts);
|
||||
backwardInTimeIterator = new IterateRouteBackwardInTime(routingCosts);
|
||||
insertionStartsListeners = new ArrayList<InsertionStarts>();
|
||||
jobInsertionListeners = new ArrayList<JobInsertedListener>();
|
||||
}
|
||||
|
||||
void addListener(ForwardInTimeListener l){
|
||||
forwardInTimeIterator.addListener(l);
|
||||
}
|
||||
|
||||
void addListener(BackwardInTimeListener l){
|
||||
backwardInTimeIterator.addListener(l);
|
||||
}
|
||||
|
||||
void addInsertionStartsListener(InsertionStarts insertionStartListener){
|
||||
insertionStartsListeners.add(insertionStartListener);
|
||||
}
|
||||
|
||||
void addJobInsertedListener(JobInsertedListener jobInsertedListener){
|
||||
jobInsertionListeners.add(jobInsertedListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||
for(JobInsertedListener l : jobInsertionListeners){ l.informJobInserted(job2insert, inRoute, additionalCosts, additionalTime); }
|
||||
forwardInTimeIterator.iterate(inRoute);
|
||||
backwardInTimeIterator.iterate(inRoute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||
for(VehicleRoute route : vehicleRoutes){
|
||||
for(InsertionStarts insertionsStartsHandler : insertionStartsListeners){
|
||||
insertionsStartsHandler.insertionStarts(route);
|
||||
}
|
||||
forwardInTimeIterator.iterate(route);
|
||||
backwardInTimeIterator.iterate(route);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
package algorithms;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import algorithms.StateManager.StateImpl;
|
||||
import basics.Job;
|
||||
import basics.algo.InsertionEndsListener;
|
||||
import basics.algo.InsertionStartsListener;
|
||||
import basics.algo.JobInsertedListener;
|
||||
import basics.costs.VehicleRoutingActivityCosts;
|
||||
import basics.costs.VehicleRoutingTransportCosts;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
class UdateCostsAtRouteLevel implements JobInsertedListener, InsertionStartsListener, InsertionEndsListener{
|
||||
|
||||
private StateManagerImpl states;
|
||||
|
||||
private VehicleRoutingTransportCosts tpCosts;
|
||||
|
||||
private VehicleRoutingActivityCosts actCosts;
|
||||
|
||||
public UdateCostsAtRouteLevel(StateManagerImpl states, VehicleRoutingTransportCosts tpCosts, VehicleRoutingActivityCosts actCosts) {
|
||||
super();
|
||||
this.states = states;
|
||||
this.tpCosts = tpCosts;
|
||||
this.actCosts = actCosts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||
// inRoute.getVehicleRouteCostCalculator().addTransportCost(additionalCosts);
|
||||
double oldCosts = states.getRouteState(inRoute, StateTypes.COSTS).toDouble();
|
||||
oldCosts += additionalCosts;
|
||||
states.putRouteState(inRoute, StateTypes.COSTS, new StateImpl(oldCosts));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(tpCosts);
|
||||
forwardInTime.addListener(new UpdateCostsAtAllLevels(actCosts, tpCosts, states));
|
||||
for(VehicleRoute route : vehicleRoutes){
|
||||
forwardInTime.iterate(route);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informInsertionEnds(Collection<VehicleRoute> vehicleRoutes) {
|
||||
|
||||
// IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(tpCosts);
|
||||
// forwardInTime.addListener(new UpdateCostsAtAllLevels(actCosts, tpCosts, states));
|
||||
for(VehicleRoute route : vehicleRoutes){
|
||||
if(route.isEmpty()) continue;
|
||||
route.getVehicleRouteCostCalculator().reset();
|
||||
route.getVehicleRouteCostCalculator().addOtherCost(states.getRouteState(route, StateTypes.COSTS).toDouble());
|
||||
route.getVehicleRouteCostCalculator().price(route.getVehicle());
|
||||
// forwardInTime.iterate(route);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
package algorithms;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import algorithms.ForwardInTimeListeners.ForwardInTimeListener;
|
||||
import basics.route.End;
|
||||
import basics.route.Start;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
class UpdateActivityTimes implements ForwardInTimeListener{
|
||||
|
||||
private Logger log = Logger.getLogger(UpdateActivityTimes.class);
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, Start start, double departureTime) {
|
||||
start.setEndTime(departureTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
||||
act.setArrTime(arrTime);
|
||||
act.setEndTime(endTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(End end, double arrivalTime) {
|
||||
end.setArrTime(arrivalTime);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
package algorithms;
|
||||
|
||||
import algorithms.ForwardInTimeListeners.ForwardInTimeListener;
|
||||
import algorithms.StateManager.StateImpl;
|
||||
import basics.costs.ForwardTransportCost;
|
||||
import basics.costs.VehicleRoutingActivityCosts;
|
||||
import basics.route.End;
|
||||
import basics.route.Start;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
class UpdateCostsAtAllLevels implements ForwardInTimeListener{
|
||||
|
||||
private VehicleRoutingActivityCosts activityCost;
|
||||
|
||||
private ForwardTransportCost transportCost;
|
||||
|
||||
private StateManagerImpl states;
|
||||
|
||||
private double totalOperationCost = 0.0;
|
||||
|
||||
private VehicleRoute vehicleRoute = null;
|
||||
|
||||
private TourActivity prevAct = null;
|
||||
|
||||
private double startTimeAtPrevAct = 0.0;
|
||||
|
||||
public UpdateCostsAtAllLevels(VehicleRoutingActivityCosts activityCost, ForwardTransportCost transportCost, StateManagerImpl states) {
|
||||
super();
|
||||
this.activityCost = activityCost;
|
||||
this.transportCost = transportCost;
|
||||
this.states = states;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, Start start, double departureTime) {
|
||||
vehicleRoute = route;
|
||||
vehicleRoute.getVehicleRouteCostCalculator().reset();
|
||||
prevAct = start;
|
||||
startTimeAtPrevAct = departureTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
||||
double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), act.getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
double actCost = activityCost.getActivityCost(act, arrTime, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
|
||||
vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost);
|
||||
vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost);
|
||||
|
||||
totalOperationCost += transportCost;
|
||||
totalOperationCost += actCost;
|
||||
|
||||
states.putActivityState(act, StateTypes.COSTS, new StateImpl(totalOperationCost));
|
||||
|
||||
prevAct = act;
|
||||
startTimeAtPrevAct = endTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(End end, double arrivalTime) {
|
||||
double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), end.getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
double actCost = activityCost.getActivityCost(end, arrivalTime, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
|
||||
vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost);
|
||||
vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost);
|
||||
|
||||
totalOperationCost += transportCost;
|
||||
totalOperationCost += actCost;
|
||||
|
||||
states.putRouteState(vehicleRoute, StateTypes.COSTS, new StateImpl(totalOperationCost));
|
||||
|
||||
//this is rather strange and likely to change
|
||||
vehicleRoute.getVehicleRouteCostCalculator().price(vehicleRoute.getDriver());
|
||||
vehicleRoute.getVehicleRouteCostCalculator().price(vehicleRoute.getVehicle());
|
||||
vehicleRoute.getVehicleRouteCostCalculator().finish();
|
||||
|
||||
startTimeAtPrevAct = 0.0;
|
||||
prevAct = null;
|
||||
vehicleRoute = null;
|
||||
totalOperationCost = 0.0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
package algorithms;
|
||||
|
||||
import algorithms.ForwardInTimeListeners.ForwardInTimeListener;
|
||||
import algorithms.StateManager.StateImpl;
|
||||
import basics.route.End;
|
||||
import basics.route.Start;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
class UpdateEarliestStartTimeWindowAtActLocations implements ForwardInTimeListener{
|
||||
|
||||
private StateManagerImpl states;
|
||||
|
||||
public UpdateEarliestStartTimeWindowAtActLocations(StateManagerImpl states) {
|
||||
super();
|
||||
this.states = states;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, Start start, double departureTime) {}
|
||||
|
||||
@Override
|
||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
||||
states.putActivityState(act, StateTypes.EARLIEST_OPERATION_START_TIME, new StateImpl(Math.max(arrTime, act.getTheoreticalEarliestOperationStartTime())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(End end, double arrivalTime) {}
|
||||
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
package algorithms;
|
||||
|
||||
import algorithms.BackwardInTimeListeners.BackwardInTimeListener;
|
||||
import algorithms.StateManager.StateImpl;
|
||||
import basics.route.End;
|
||||
import basics.route.Start;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
class UpdateLatestOperationStartTimeAtActLocations implements BackwardInTimeListener{
|
||||
|
||||
private StateManagerImpl states;
|
||||
|
||||
public UpdateLatestOperationStartTimeAtActLocations(StateManagerImpl states) {
|
||||
super();
|
||||
this.states = states;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, End end, double latestArrivalTime) {}
|
||||
|
||||
@Override
|
||||
public void prevActivity(TourActivity act,double latestDepartureTime, double latestOperationStartTime) {
|
||||
states.putActivityState(act, StateTypes.LATEST_OPERATION_START_TIME, new StateImpl(latestOperationStartTime));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(Start start, double latestDepartureTime) {}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
package algorithms;
|
||||
|
||||
import algorithms.ForwardInTimeListeners.ForwardInTimeListener;
|
||||
import algorithms.StateManager.StateImpl;
|
||||
import basics.route.End;
|
||||
import basics.route.Start;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
/**
|
||||
* It does not update start and end activities.
|
||||
*
|
||||
* @author stefan
|
||||
*
|
||||
*/
|
||||
class UpdateLoadAtAllLevels implements ForwardInTimeListener{
|
||||
|
||||
private double load = 0.0;
|
||||
|
||||
private StateManagerImpl states;
|
||||
|
||||
private VehicleRoute vehicleRoute;
|
||||
|
||||
public UpdateLoadAtAllLevels(StateManagerImpl states) {
|
||||
super();
|
||||
this.states = states;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, Start start, double departureTime) { vehicleRoute = route; }
|
||||
|
||||
@Override
|
||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
||||
load += (double)act.getCapacityDemand();
|
||||
states.putActivityState(act, StateTypes.LOAD, new StateImpl(load));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(End end, double arrivalTime) {
|
||||
states.putRouteState(vehicleRoute, StateTypes.LOAD, new StateImpl(load));
|
||||
load=0;
|
||||
vehicleRoute = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
package algorithms;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import algorithms.StateManager.StateImpl;
|
||||
import basics.Job;
|
||||
import basics.Service;
|
||||
import basics.algo.InsertionStartsListener;
|
||||
import basics.algo.JobInsertedListener;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
class UpdateLoadAtRouteLevel implements JobInsertedListener, InsertionStartsListener{
|
||||
|
||||
private StateManagerImpl states;
|
||||
|
||||
public UpdateLoadAtRouteLevel(StateManagerImpl states) {
|
||||
super();
|
||||
this.states = states;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||
if(!(job2insert instanceof Service)){
|
||||
return;
|
||||
}
|
||||
double oldLoad = states.getRouteState(inRoute, StateTypes.LOAD).toDouble();
|
||||
states.putRouteState(inRoute, StateTypes.LOAD, new StateImpl(oldLoad + job2insert.getCapacityDemand()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||
for(VehicleRoute route : vehicleRoutes){
|
||||
int load = 0;
|
||||
for(Job j : route.getTourActivities().getJobs()){
|
||||
load += j.getCapacityDemand();
|
||||
}
|
||||
states.putRouteState(route, StateTypes.LOAD, new StateImpl(load));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
package algorithms;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import algorithms.RuinStrategy.RuinListener;
|
||||
import basics.Job;
|
||||
import basics.algo.JobInsertedListener;
|
||||
import basics.costs.VehicleRoutingActivityCosts;
|
||||
import basics.costs.VehicleRoutingTransportCosts;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
class UpdateStates implements JobInsertedListener, RuinListener{
|
||||
|
||||
private IterateRouteForwardInTime iterateForward;
|
||||
|
||||
private IterateRouteBackwardInTime iterateBackward;
|
||||
|
||||
public UpdateStates(StateManagerImpl states, VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts activityCosts) {
|
||||
|
||||
iterateForward = new IterateRouteForwardInTime(routingCosts);
|
||||
iterateForward.addListener(new UpdateActivityTimes());
|
||||
iterateForward.addListener(new UpdateCostsAtAllLevels(activityCosts, routingCosts, states));
|
||||
iterateForward.addListener(new UpdateLoadAtAllLevels(states));
|
||||
// iterateForward.addListener(new UpdateEarliestStartTimeWindowAtActLocations(states));
|
||||
|
||||
iterateBackward = new IterateRouteBackwardInTime(routingCosts);
|
||||
iterateBackward.addListener(new UpdateLatestOperationStartTimeAtActLocations(states));
|
||||
}
|
||||
|
||||
public void update(VehicleRoute route){
|
||||
iterateForward.iterate(route);
|
||||
iterateBackward.iterate(route);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||
iterateForward.iterate(inRoute);
|
||||
iterateBackward.iterate(inRoute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ruinStarts(Collection<VehicleRoute> routes) {}
|
||||
|
||||
@Override
|
||||
public void ruinEnds(Collection<VehicleRoute> routes,Collection<Job> unassignedJobs) {
|
||||
for(VehicleRoute route : routes) {
|
||||
iterateForward.iterate(route);
|
||||
iterateBackward.iterate(route);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed(Job job, VehicleRoute fromRoute) {}
|
||||
|
||||
}
|
||||
|
|
@ -35,11 +35,16 @@ import org.apache.commons.configuration.HierarchicalConfiguration;
|
|||
import org.apache.commons.configuration.XMLConfiguration;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import util.RouteUtils;
|
||||
import algorithms.RuinStrategy.RuinListener;
|
||||
import algorithms.VehicleRoutingAlgorithms.TypedMap.InsertionStrategyKey;
|
||||
import algorithms.HardConstraints.ConstraintManager;
|
||||
import algorithms.HardConstraints.HardTimeWindowActivityLevelConstraint;
|
||||
import algorithms.StateUpdates.UpdateActivityTimes;
|
||||
import algorithms.StateUpdates.UpdateCostsAtAllLevels;
|
||||
import algorithms.StateUpdates.UpdateEarliestStartTimeWindowAtActLocations;
|
||||
import algorithms.StateUpdates.UpdateLatestOperationStartTimeAtActLocations;
|
||||
import algorithms.StateUpdates.UpdateStates;
|
||||
import algorithms.VehicleRoutingAlgorithms.TypedMap.AbstractKey;
|
||||
import algorithms.VehicleRoutingAlgorithms.TypedMap.AcceptorKey;
|
||||
import algorithms.VehicleRoutingAlgorithms.TypedMap.InsertionStrategyKey;
|
||||
import algorithms.VehicleRoutingAlgorithms.TypedMap.RuinStrategyKey;
|
||||
import algorithms.VehicleRoutingAlgorithms.TypedMap.SelectorKey;
|
||||
import algorithms.VehicleRoutingAlgorithms.TypedMap.StrategyModuleKey;
|
||||
|
|
@ -50,28 +55,25 @@ import algorithms.acceptors.SolutionAcceptor;
|
|||
import algorithms.selectors.SelectBest;
|
||||
import algorithms.selectors.SelectRandomly;
|
||||
import algorithms.selectors.SolutionSelector;
|
||||
import basics.Job;
|
||||
import basics.VehicleRoutingAlgorithm;
|
||||
import basics.VehicleRoutingProblem;
|
||||
import basics.VehicleRoutingProblem.Constraint;
|
||||
import basics.VehicleRoutingProblem.FleetSize;
|
||||
import basics.VehicleRoutingProblemSolution;
|
||||
import basics.algo.AlgorithmStartsListener;
|
||||
import basics.algo.InsertionListener;
|
||||
import basics.algo.IterationStartsListener;
|
||||
import basics.algo.IterationWithoutImprovementBreaker;
|
||||
import basics.algo.PrematureAlgorithmBreaker;
|
||||
import basics.algo.SearchStrategy;
|
||||
import basics.algo.SearchStrategy.DiscoveredSolution;
|
||||
import basics.algo.SearchStrategyManager;
|
||||
import basics.algo.SearchStrategyModule;
|
||||
import basics.algo.SearchStrategyModuleListener;
|
||||
import basics.algo.TimeBreaker;
|
||||
import basics.algo.VariationCoefficientBreaker;
|
||||
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
|
||||
import basics.algo.VehicleRoutingAlgorithmListeners.Priority;
|
||||
import basics.io.AlgorithmConfig;
|
||||
import basics.io.AlgorithmConfigXmlReader;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
|
||||
|
||||
|
|
@ -428,50 +430,43 @@ public class VehicleRoutingAlgorithms {
|
|||
}
|
||||
|
||||
private static VehicleRoutingAlgorithm createAlgo(final VehicleRoutingProblem vrp, XMLConfiguration config, ExecutorService executorService, int nuOfThreads){
|
||||
|
||||
//fleetmanager
|
||||
final VehicleFleetManager vehicleFleetManager;
|
||||
if(vrp.getFleetSize().equals(FleetSize.INFINITE)){
|
||||
vehicleFleetManager = new InfiniteVehicles(vrp.getVehicles());
|
||||
|
||||
}
|
||||
else if(vrp.getFleetSize().equals(FleetSize.FINITE)){
|
||||
vehicleFleetManager = new VehicleFleetManagerImpl(vrp.getVehicles());
|
||||
}
|
||||
else{
|
||||
throw new IllegalStateException("fleet size can only be infinite or finite. " +
|
||||
"makes sure your config file contains one of these options");
|
||||
}
|
||||
|
||||
|
||||
// map to store constructed modules
|
||||
TypedMap definedClasses = new TypedMap();
|
||||
|
||||
// algorithm listeners
|
||||
Set<PrioritizedVRAListener> algorithmListeners = new HashSet<PrioritizedVRAListener>();
|
||||
|
||||
// insertion listeners
|
||||
List<InsertionListener> insertionListeners = new ArrayList<InsertionListener>();
|
||||
|
||||
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new SolutionVerifier()));
|
||||
|
||||
final StateManagerImpl routeStates = new StateManagerImpl();
|
||||
IterationStartsListener resetStates = new IterationStartsListener() {
|
||||
|
||||
@Override
|
||||
public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||
routeStates.clear();
|
||||
}
|
||||
};
|
||||
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, resetStates));
|
||||
//create fleetmanager
|
||||
final VehicleFleetManager vehicleFleetManager = createFleetManager(vrp);
|
||||
|
||||
// insertionListeners.add(new UdateCostsAtRouteLevel(routeStates,vrp.getTransportCosts(),vrp.getActivityCosts()));
|
||||
//create state-manager
|
||||
final StateManagerImpl stateManager = new StateManagerImpl();
|
||||
|
||||
// RouteStates routeStates = new RouteStates();
|
||||
// routeStates.initialiseStateOfJobs(vrp.getJobs().values());
|
||||
// algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, routeStates));
|
||||
|
||||
TypedMap definedClasses = new TypedMap();
|
||||
|
||||
/*
|
||||
* initial solution - construction
|
||||
* define constraints
|
||||
*/
|
||||
AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,routeStates,algorithmListeners,definedClasses,executorService,nuOfThreads);
|
||||
//constraint manager
|
||||
ConstraintManager constraintManager = new ConstraintManager();
|
||||
constraintManager.addConstraint(new HardConstraints.HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts()));
|
||||
|
||||
if(vrp.getProblemConstraints().contains(Constraint.DELIVERIES_FIRST)){
|
||||
constraintManager.addConstraint(new HardConstraints.HardPickupAndDeliveryBackhaulActivityLevelConstraint(stateManager));
|
||||
}
|
||||
else{
|
||||
constraintManager.addConstraint(new HardConstraints.HardPickupAndDeliveryActivityLevelConstraint(stateManager));
|
||||
}
|
||||
|
||||
constraintManager.addConstraint(new HardConstraints.HardPickupAndDeliveryLoadConstraint(stateManager));
|
||||
|
||||
//construct initial solution creator
|
||||
AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads,constraintManager);
|
||||
if(createInitialSolution != null) algorithmListeners.add(new PrioritizedVRAListener(Priority.MEDIUM, createInitialSolution));
|
||||
|
||||
//construct algorithm, i.e. search-strategies and its modules
|
||||
int solutionMemory = config.getInt("strategy.memory");
|
||||
SearchStrategyManager searchStratManager = new SearchStrategyManager();
|
||||
List<HierarchicalConfiguration> strategyConfigs = config.configurationsAt("strategy.searchStrategies.searchStrategy");
|
||||
|
|
@ -483,26 +478,72 @@ public class VehicleRoutingAlgorithms {
|
|||
strategy.setName(name);
|
||||
List<HierarchicalConfiguration> modulesConfig = strategyConfig.configurationsAt("modules.module");
|
||||
for(HierarchicalConfiguration moduleConfig : modulesConfig){
|
||||
SearchStrategyModule module = buildModule(moduleConfig,vrp,vehicleFleetManager,routeStates,algorithmListeners,definedClasses,executorService,nuOfThreads);
|
||||
SearchStrategyModule module = buildModule(moduleConfig,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads, constraintManager);
|
||||
strategy.addModule(module);
|
||||
}
|
||||
searchStratManager.addStrategy(strategy, strategyConfig.getDouble("probability"));
|
||||
}
|
||||
|
||||
//construct algorithm
|
||||
VehicleRoutingAlgorithm metaAlgorithm = new VehicleRoutingAlgorithm(vrp, searchStratManager);
|
||||
if(config.containsKey("iterations")){
|
||||
int iter = config.getInt("iterations");
|
||||
metaAlgorithm.setNuOfIterations(iter);
|
||||
log.info("set nuOfIterations to " + iter);
|
||||
}
|
||||
//prematureBreak
|
||||
|
||||
|
||||
/*
|
||||
* define stateUpdates
|
||||
*/
|
||||
|
||||
//reset stateManager
|
||||
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new StateUpdates.ResetStateManager(stateManager)));
|
||||
//update states
|
||||
// metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new UpdateStates(stateManager, vrp.getTransportCosts(), vrp.getActivityCosts()));
|
||||
StateUpdates.UpdateRouteStatesOnceTheRouteHasBeenChanged routeChangedListener = new StateUpdates.UpdateRouteStatesOnceTheRouteHasBeenChanged(vrp.getTransportCosts());
|
||||
|
||||
routeChangedListener.addInsertionStartsListener(new StateUpdates.UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
|
||||
routeChangedListener.addJobInsertedListener(new StateUpdates.UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
|
||||
|
||||
routeChangedListener.addListener(new StateUpdates.UpdateActivityTimes());
|
||||
routeChangedListener.addListener(new StateUpdates.UpdateLoadAtActivityLevel(stateManager));
|
||||
routeChangedListener.addListener(new StateUpdates.UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
||||
|
||||
routeChangedListener.addListener(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager));
|
||||
routeChangedListener.addListener(new StateUpdates.UpdateLatestOperationStartTimeAtActLocations(stateManager));
|
||||
routeChangedListener.addListener(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager));
|
||||
|
||||
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(routeChangedListener);
|
||||
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(vehicleFleetManager));
|
||||
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new ResetAndIniFleetManager(vehicleFleetManager));
|
||||
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new VehicleSwitched(vehicleFleetManager));
|
||||
|
||||
//define prematureBreak
|
||||
PrematureAlgorithmBreaker prematureAlgoBreaker = getPrematureBreaker(config,algorithmListeners);
|
||||
metaAlgorithm.setPrematureAlgorithmBreaker(prematureAlgoBreaker);
|
||||
|
||||
//misc
|
||||
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new SolutionVerifier()));
|
||||
|
||||
//register listeners
|
||||
registerListeners(metaAlgorithm,algorithmListeners);
|
||||
registerInsertionListeners(definedClasses,insertionListeners);
|
||||
return metaAlgorithm;
|
||||
}
|
||||
|
||||
private static VehicleFleetManager createFleetManager(final VehicleRoutingProblem vrp) {
|
||||
if(vrp.getFleetSize().equals(FleetSize.INFINITE)){
|
||||
return new InfiniteVehicles(vrp.getVehicles());
|
||||
|
||||
}
|
||||
else if(vrp.getFleetSize().equals(FleetSize.FINITE)){
|
||||
return new VehicleFleetManagerImpl(vrp.getVehicles());
|
||||
}
|
||||
throw new IllegalStateException("fleet size can only be infinite or finite. " +
|
||||
"makes sure your config file contains one of these options");
|
||||
}
|
||||
|
||||
private static PrematureAlgorithmBreaker getPrematureBreaker(XMLConfiguration config, Set<PrioritizedVRAListener> algorithmListeners) {
|
||||
String basedOn = config.getString("prematureBreak[@basedOn]");
|
||||
if(basedOn == null){
|
||||
|
|
@ -570,7 +611,7 @@ public class VehicleRoutingAlgorithms {
|
|||
metaAlgorithm.getAlgorithmListeners().addAll(algorithmListeners);
|
||||
}
|
||||
|
||||
private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads) {
|
||||
private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
|
||||
List<HierarchicalConfiguration> modConfigs = config.configurationsAt("construction.insertion");
|
||||
if(modConfigs == null) return null;
|
||||
if(modConfigs.isEmpty()) return null;
|
||||
|
|
@ -585,7 +626,7 @@ public class VehicleRoutingAlgorithms {
|
|||
InsertionStrategy insertionStrategy = definedClasses.get(insertionStrategyKey);
|
||||
if(insertionStrategy == null){
|
||||
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
||||
insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads);
|
||||
insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager);
|
||||
algorithmListeners.addAll(prioListeners);
|
||||
definedClasses.put(insertionStrategyKey,insertionStrategy);
|
||||
}
|
||||
|
|
@ -667,7 +708,7 @@ public class VehicleRoutingAlgorithms {
|
|||
}
|
||||
|
||||
private static SearchStrategyModule buildModule(HierarchicalConfiguration moduleConfig, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager,
|
||||
final StateManagerImpl routeStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads) {
|
||||
final StateManagerImpl routeStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
|
||||
String moduleName = moduleConfig.getString("[@name]");
|
||||
if(moduleName == null) throw new IllegalStateException("module(-name) is missing.");
|
||||
String moduleId = moduleConfig.getString("[@id]");
|
||||
|
|
@ -716,49 +757,14 @@ public class VehicleRoutingAlgorithms {
|
|||
List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
|
||||
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
|
||||
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
||||
insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads);
|
||||
insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager);
|
||||
algorithmListeners.addAll(prioListeners);
|
||||
}
|
||||
final InsertionStrategy final_insertion = insertion;
|
||||
SearchStrategyModule module = new SearchStrategyModule() {
|
||||
|
||||
private Logger logger = Logger.getLogger(SearchStrategyModule.class);
|
||||
|
||||
@Override
|
||||
public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution) {
|
||||
Collection<Job> ruinedJobs = ruin.ruin(vrpSolution.getRoutes());
|
||||
final_insertion.insertJobs(vrpSolution.getRoutes(), ruinedJobs);
|
||||
double totalCost = RouteUtils.getTotalCost(vrpSolution.getRoutes());
|
||||
vrpSolution.setCost(totalCost);
|
||||
return vrpSolution;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "[name=ruin_and_recreate][ruin="+ruin+"][recreate="+final_insertion+"]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addModuleListener(SearchStrategyModuleListener moduleListener) {
|
||||
if(moduleListener instanceof InsertionListener){
|
||||
InsertionListener iListener = (InsertionListener) moduleListener;
|
||||
if(!final_insertion.getListeners().contains(iListener)){
|
||||
logger.info("register moduleListener " + moduleListener);
|
||||
final_insertion.addListener(iListener);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
return module;
|
||||
|
||||
RuinAndRecreateModule rrModule = new RuinAndRecreateModule("ruin_and_recreate", final_insertion, ruin);
|
||||
return rrModule;
|
||||
}
|
||||
|
||||
if(moduleName.equals("gendreau")){
|
||||
int iterations = moduleConfig.getInt("iterations");
|
||||
double share = moduleConfig.getDouble("share");
|
||||
|
|
@ -771,7 +777,6 @@ public class VehicleRoutingAlgorithms {
|
|||
RuinStrategy ruin = definedClasses.get(stratKey);
|
||||
if(ruin == null){
|
||||
ruin = new RuinRadial(vrp, 0.3, new JobDistanceAvgCosts(vrp.getTransportCosts()));
|
||||
ruin.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
|
||||
definedClasses.put(stratKey, ruin);
|
||||
}
|
||||
|
||||
|
|
@ -786,7 +791,7 @@ public class VehicleRoutingAlgorithms {
|
|||
List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
|
||||
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
|
||||
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
||||
insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads);
|
||||
insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager);
|
||||
algorithmListeners.addAll(prioListeners);
|
||||
}
|
||||
Gendreau gendreau = new Gendreau(vrp, ruin, insertion);
|
||||
|
|
@ -810,7 +815,6 @@ public class VehicleRoutingAlgorithms {
|
|||
RuinStrategy ruin = definedClasses.get(stratKey);
|
||||
if(ruin == null){
|
||||
ruin = new RuinRadial(vrp, shareToRuin, jobDistance);
|
||||
ruin.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
|
||||
definedClasses.put(stratKey, ruin);
|
||||
}
|
||||
return ruin;
|
||||
|
|
@ -821,14 +825,13 @@ public class VehicleRoutingAlgorithms {
|
|||
RuinStrategy ruin = definedClasses.get(stratKey);
|
||||
if(ruin == null){
|
||||
ruin = new RuinRandom(vrp, shareToRuin);
|
||||
ruin.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
|
||||
definedClasses.put(stratKey, ruin);
|
||||
}
|
||||
return ruin;
|
||||
}
|
||||
|
||||
private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads) {
|
||||
InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, routeStates, algorithmListeners, executorService, nuOfThreads);
|
||||
private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
|
||||
InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, routeStates, algorithmListeners, executorService, nuOfThreads, constraintManager);
|
||||
return insertion;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import basics.algo.InsertionListener;
|
||||
|
|
|
|||
52
jsprit-core/src/main/java/basics/Delivery.java
Normal file
52
jsprit-core/src/main/java/basics/Delivery.java
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package basics;
|
||||
|
||||
|
||||
public final class Delivery extends Service{
|
||||
|
||||
public static class Builder extends Service.Builder {
|
||||
|
||||
public static Builder newInstance(String id, int size){
|
||||
return new Builder(id,size);
|
||||
}
|
||||
|
||||
Builder(String id, int size) {
|
||||
super(id, size);
|
||||
}
|
||||
|
||||
public Delivery build(){
|
||||
if(locationId == null) {
|
||||
if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not.");
|
||||
locationId = coord.toString();
|
||||
}
|
||||
this.setType("delivery");
|
||||
return new Delivery(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Delivery(Builder builder) {
|
||||
super(builder);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
50
jsprit-core/src/main/java/basics/Pickup.java
Normal file
50
jsprit-core/src/main/java/basics/Pickup.java
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package basics;
|
||||
|
||||
public final class Pickup extends Service {
|
||||
|
||||
public static class Builder extends Service.Builder {
|
||||
|
||||
public static Builder newInstance(String id, int size){
|
||||
return new Builder(id,size);
|
||||
}
|
||||
|
||||
Builder(String id, int size) {
|
||||
super(id, size);
|
||||
}
|
||||
|
||||
public Pickup build(){
|
||||
if(locationId == null) {
|
||||
if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not.");
|
||||
locationId = coord.toString();
|
||||
}
|
||||
this.setType("pickup");
|
||||
return new Pickup(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Pickup(Builder builder) {
|
||||
super(builder);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -26,8 +26,6 @@ import util.Coordinate;
|
|||
|
||||
public class Service implements Job {
|
||||
|
||||
|
||||
|
||||
public static class Builder {
|
||||
|
||||
public static Builder newInstance(String id, int size){
|
||||
|
|
@ -35,21 +33,21 @@ public class Service implements Job {
|
|||
}
|
||||
|
||||
private String id;
|
||||
private String locationId;
|
||||
private String name = "service";
|
||||
private Coordinate coord;
|
||||
private double serviceTime;
|
||||
private TimeWindow timeWindow = TimeWindow.newInstance(0.0, Double.MAX_VALUE);
|
||||
private int demand;
|
||||
protected String locationId;
|
||||
private String type = "service";
|
||||
protected Coordinate coord;
|
||||
protected double serviceTime;
|
||||
protected TimeWindow timeWindow = TimeWindow.newInstance(0.0, Double.MAX_VALUE);
|
||||
protected int demand;
|
||||
|
||||
private Builder(String id, int size) {
|
||||
super();
|
||||
Builder(String id, int size) {
|
||||
if(size < 0) throw new IllegalArgumentException("size must be greater than or equal to zero");
|
||||
this.id = id;
|
||||
this.demand = size;
|
||||
}
|
||||
|
||||
public Builder setName(String name){
|
||||
this.name = name;
|
||||
protected Builder setType(String name){
|
||||
this.type = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +62,7 @@ public class Service implements Job {
|
|||
}
|
||||
|
||||
public Builder setServiceTime(double serviceTime){
|
||||
if(serviceTime < 0) throw new IllegalArgumentException("serviceTime must be greate than or equal to zero");
|
||||
this.serviceTime = serviceTime;
|
||||
return this;
|
||||
}
|
||||
|
|
@ -78,7 +77,7 @@ public class Service implements Job {
|
|||
if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not.");
|
||||
locationId = coord.toString();
|
||||
}
|
||||
|
||||
this.setType("service");
|
||||
return new Service(this);
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +88,7 @@ public class Service implements Job {
|
|||
|
||||
private final String locationId;
|
||||
|
||||
private final String name;
|
||||
private final String type;
|
||||
|
||||
private final Coordinate coord;
|
||||
|
||||
|
|
@ -99,14 +98,14 @@ public class Service implements Job {
|
|||
|
||||
private final int demand;
|
||||
|
||||
private Service(Builder builder){
|
||||
Service(Builder builder){
|
||||
id = builder.id;
|
||||
locationId = builder.locationId;
|
||||
coord = builder.coord;
|
||||
serviceTime = builder.serviceTime;
|
||||
timeWindow = builder.timeWindow;
|
||||
demand = builder.demand;
|
||||
name = builder.name;
|
||||
type = builder.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -139,7 +138,7 @@ public class Service implements Job {
|
|||
* @return the name
|
||||
*/
|
||||
public String getType() {
|
||||
return name;
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -49,6 +49,18 @@ import basics.route.VehicleTypeImpl;
|
|||
*/
|
||||
public class VehicleRoutingProblem {
|
||||
|
||||
/**
|
||||
* Overall problem constraints.
|
||||
*
|
||||
* <p>DELIIVERIES_FIRST corresponds to the vehicle routing problem with back hauls, i.e. before a vehicle is not entirely unloaded, no pickup can be made.
|
||||
*
|
||||
* @author stefan
|
||||
*
|
||||
*/
|
||||
public enum Constraint {
|
||||
DELIVERIES_FIRST
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder to build the routing-problem.
|
||||
*
|
||||
|
|
@ -81,6 +93,8 @@ public class VehicleRoutingProblem {
|
|||
private FleetComposition fleetComposition = FleetComposition.HOMOGENEOUS;
|
||||
|
||||
private Collection<VehicleType> vehicleTypes;
|
||||
|
||||
private Collection<Constraint> problemConstraints;
|
||||
|
||||
/**
|
||||
* by default all locations are neighbors
|
||||
|
|
@ -99,6 +113,7 @@ public class VehicleRoutingProblem {
|
|||
coordinates = new HashMap<String, Coordinate>();
|
||||
vehicleTypes = new ArrayList<VehicleType>();
|
||||
services = new ArrayList<Service>();
|
||||
problemConstraints = new ArrayList<VehicleRoutingProblem.Constraint>();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -117,6 +132,7 @@ public class VehicleRoutingProblem {
|
|||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the unmodifiable map of locations (mapped by their id).
|
||||
|
|
@ -145,6 +161,12 @@ public class VehicleRoutingProblem {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
public void addProblemConstraint(Constraint constraint){
|
||||
if(!problemConstraints.contains(constraint)) problemConstraints.add(constraint);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets routing costs.
|
||||
*
|
||||
|
|
@ -387,6 +409,8 @@ public class VehicleRoutingProblem {
|
|||
private FleetComposition fleetComposition;
|
||||
|
||||
|
||||
private Collection<Constraint> problemConstraints;
|
||||
|
||||
private VehicleRoutingProblem(Builder builder) {
|
||||
this.jobs = builder.jobs;
|
||||
this.fleetComposition = builder.fleetComposition;
|
||||
|
|
@ -396,6 +420,7 @@ public class VehicleRoutingProblem {
|
|||
this.transportCosts = builder.transportCosts;
|
||||
this.activityCosts = builder.activityCosts;
|
||||
this.neighborhood = builder.neighborhood;
|
||||
this.problemConstraints = builder.problemConstraints;
|
||||
log.info("initialise " + this);
|
||||
}
|
||||
|
||||
|
|
@ -441,6 +466,14 @@ public class VehicleRoutingProblem {
|
|||
return Collections.unmodifiableMap(jobs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns unmodifiable collection of problem-constraints.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Collection<Constraint> getProblemConstraints(){
|
||||
return Collections.unmodifiableCollection(problemConstraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entire, unmodifiable collection of types.
|
||||
|
|
|
|||
|
|
@ -20,6 +20,6 @@
|
|||
******************************************************************************/
|
||||
package basics.algo;
|
||||
|
||||
public class SearchStrategyListener {
|
||||
public interface SearchStrategyListener extends VehicleRoutingAlgorithmListener{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,6 @@
|
|||
******************************************************************************/
|
||||
package basics.algo;
|
||||
|
||||
public interface SearchStrategyModuleListener {
|
||||
public interface SearchStrategyModuleListener extends VehicleRoutingAlgorithmListener{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,25 +38,52 @@ import org.xml.sax.SAXException;
|
|||
|
||||
import util.Coordinate;
|
||||
import util.Resource;
|
||||
import basics.Delivery;
|
||||
import basics.Pickup;
|
||||
import basics.Service;
|
||||
import basics.VehicleRoutingProblem;
|
||||
import basics.VehicleRoutingProblem.FleetComposition;
|
||||
import basics.VehicleRoutingProblem.FleetSize;
|
||||
import basics.VehicleRoutingProblemSolution;
|
||||
import basics.route.DefaultTourActivityFactory;
|
||||
import basics.route.DeliveryActivity;
|
||||
import basics.route.Driver;
|
||||
import basics.route.DriverImpl;
|
||||
import basics.route.End;
|
||||
import basics.route.PickupActivity;
|
||||
import basics.route.ServiceActivity;
|
||||
import basics.route.Start;
|
||||
import basics.route.TimeWindow;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.TourActivityFactory;
|
||||
import basics.route.Vehicle;
|
||||
import basics.route.VehicleImpl;
|
||||
import basics.route.VehicleImpl.Builder;
|
||||
import basics.route.VehicleRoute;
|
||||
import basics.route.VehicleType;
|
||||
import basics.route.VehicleTypeImpl;
|
||||
|
||||
public class VrpXMLReader{
|
||||
|
||||
public interface ServiceBuilderFactory {
|
||||
Service.Builder createBuilder(String serviceType, String id, int size);
|
||||
}
|
||||
|
||||
static class DefaultServiceBuilderFactory implements ServiceBuilderFactory{
|
||||
|
||||
@Override
|
||||
public basics.Service.Builder createBuilder(String serviceType, String id, int size) {
|
||||
if(serviceType.equals("pickup")){
|
||||
return Pickup.Builder.newInstance(id, size);
|
||||
}
|
||||
else if(serviceType.equals("delivery")){
|
||||
return Delivery.Builder.newInstance(id, size);
|
||||
}
|
||||
else{
|
||||
return Service.Builder.newInstance(id, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static Logger logger = Logger.getLogger(VrpXMLReader.class);
|
||||
|
||||
|
|
@ -70,6 +97,18 @@ public class VrpXMLReader{
|
|||
|
||||
private Collection<VehicleRoutingProblemSolution> solutions;
|
||||
|
||||
private ServiceBuilderFactory serviceBuilderFactory = new DefaultServiceBuilderFactory();
|
||||
|
||||
private TourActivityFactory tourActivityFactory = new DefaultTourActivityFactory();
|
||||
|
||||
public void setTourActivityFactory(TourActivityFactory tourActivityFactory){
|
||||
this.tourActivityFactory = tourActivityFactory;
|
||||
}
|
||||
|
||||
public void setServiceBuilderFactory(ServiceBuilderFactory serviceBuilderFactory){
|
||||
this.serviceBuilderFactory=serviceBuilderFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param schemaValidation the schemaValidation to set
|
||||
*/
|
||||
|
|
@ -170,10 +209,10 @@ public class VrpXMLReader{
|
|||
if(arrTime == null) throw new IllegalStateException("act.arrTime is missing.");
|
||||
String endTime = actConfig.getString("endTime");
|
||||
if(endTime == null) throw new IllegalStateException("act.endTime is missing.");
|
||||
ServiceActivity serviceActivity = ServiceActivity.newInstance(service);
|
||||
serviceActivity.setArrTime(Double.parseDouble(arrTime));
|
||||
serviceActivity.setEndTime(Double.parseDouble(endTime));
|
||||
routeBuilder.addActivity(serviceActivity);
|
||||
TourActivity tourActivity = tourActivityFactory.createActivity(service);
|
||||
tourActivity.setArrTime(Double.parseDouble(arrTime));
|
||||
tourActivity.setEndTime(Double.parseDouble(endTime));
|
||||
routeBuilder.addActivity(tourActivity);
|
||||
}
|
||||
routes.add(routeBuilder.build());
|
||||
}
|
||||
|
|
@ -210,13 +249,12 @@ public class VrpXMLReader{
|
|||
for(HierarchicalConfiguration serviceConfig : serviceConfigs){
|
||||
String id = serviceConfig.getString("[@id]");
|
||||
if(id == null) throw new IllegalStateException("service[@id] is missing.");
|
||||
String name = serviceConfig.getString("[@type]");
|
||||
if(name == null) name = "service";
|
||||
String type = serviceConfig.getString("[@type]");
|
||||
if(type == null) type = "service";
|
||||
String capacityDemand = serviceConfig.getString("capacity-demand");
|
||||
int cap = 0;
|
||||
if(capacityDemand != null) cap = Integer.parseInt(capacityDemand);
|
||||
Service.Builder builder = Service.Builder.newInstance(id, cap);
|
||||
builder.setName(name);
|
||||
Service.Builder builder = serviceBuilderFactory.createBuilder(type, id, cap);
|
||||
String serviceLocationId = serviceConfig.getString("locationId");
|
||||
builder.setLocationId(serviceLocationId);
|
||||
Coordinate serviceCoord = null;
|
||||
|
|
@ -235,8 +273,6 @@ public class VrpXMLReader{
|
|||
builder.setLocationId(serviceCoord.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(serviceConfig.containsKey("duration")){
|
||||
builder.setServiceTime(serviceConfig.getDouble("duration"));
|
||||
}
|
||||
|
|
@ -264,15 +300,12 @@ public class VrpXMLReader{
|
|||
Double fix = typeConfig.getDouble("costs.fixed");
|
||||
Double timeC = typeConfig.getDouble("costs.time");
|
||||
Double distC = typeConfig.getDouble("costs.distance");
|
||||
// Double start = typeConfig.getDouble("timeSchedule.start");
|
||||
// Double end = typeConfig.getDouble("timeSchedule.end");
|
||||
if(typeId == null) throw new IllegalStateException("typeId is missing.");
|
||||
if(capacity == null) throw new IllegalStateException("capacity is missing.");
|
||||
VehicleTypeImpl.Builder typeBuilder = VehicleTypeImpl.Builder.newInstance(typeId, capacity);
|
||||
if(fix != null) typeBuilder.setFixedCost(fix);
|
||||
if(timeC != null) typeBuilder.setCostPerTime(timeC);
|
||||
if(distC != null) typeBuilder.setCostPerDistance(distC);
|
||||
// if(start != null && end != null) typeBuilder.setTimeSchedule(new TimeSchedule(start, end));
|
||||
VehicleTypeImpl type = typeBuilder.build();
|
||||
types.put(type.getTypeId(), type);
|
||||
vrpBuilder.addVehicleType(type);
|
||||
|
|
@ -310,7 +343,6 @@ public class VrpXMLReader{
|
|||
if(start != null) builder.setEarliestStart(Double.parseDouble(start));
|
||||
if(end != null) builder.setLatestArrival(Double.parseDouble(end));
|
||||
VehicleImpl vehicle = builder.build();
|
||||
// vehicleMap.put(vehicle.getId(), vehicle);
|
||||
vrpBuilder.addVehicle(vehicle);
|
||||
vehicleMap.put(vehicleId, vehicle);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import basics.VehicleRoutingProblem;
|
|||
import basics.VehicleRoutingProblemSolution;
|
||||
import basics.route.ServiceActivity;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.TourActivity.JobActivity;
|
||||
import basics.route.Vehicle;
|
||||
import basics.route.VehicleRoute;
|
||||
import basics.route.VehicleType;
|
||||
|
|
@ -84,7 +85,6 @@ public class VrpXMLWriter {
|
|||
writeProblemType(xmlConfig);
|
||||
writeVehiclesAndTheirTypes(xmlConfig);
|
||||
writerServices(xmlConfig);
|
||||
// writeShipments(xmlConfig);
|
||||
writeSolutions(xmlConfig);
|
||||
|
||||
OutputFormat format = new OutputFormat();
|
||||
|
|
@ -133,8 +133,8 @@ public class VrpXMLWriter {
|
|||
int actCounter = 0;
|
||||
for(TourActivity act : route.getTourActivities().getActivities()){
|
||||
xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+")[@type]", act.getName());
|
||||
if(act instanceof ServiceActivity){
|
||||
xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").serviceId", ((ServiceActivity) act).getJob().getId());
|
||||
if(act instanceof JobActivity){
|
||||
xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").serviceId", ((JobActivity) act).getJob().getId());
|
||||
}
|
||||
xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").arrTime", act.getArrTime());
|
||||
xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").endTime", act.getEndTime());
|
||||
|
|
@ -169,36 +169,6 @@ public class VrpXMLWriter {
|
|||
|
||||
|
||||
}
|
||||
|
||||
// private void writeShipments(XMLConf xmlConfig) {
|
||||
// String shipmentPathString = "shipments.shipment";
|
||||
// int counter = 0;
|
||||
// for(Job j : vrp.getJobs().values()){
|
||||
// Shipment shipment = (Shipment) j;
|
||||
// xmlConfig.setProperty(shipmentPathString + "("+counter+")[@id]", shipment.getId());
|
||||
// if(shipment.getFromId() != null) xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.locationId", shipment.getFromId());
|
||||
// if(shipment.getFromCoord() != null) {
|
||||
// xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.coord[@x]", shipment.getFromCoord().getX());
|
||||
// xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.coord[@y]", shipment.getFromCoord().getY());
|
||||
// }
|
||||
// if(shipment.getToId() != null) xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.locationId", shipment.getToId());
|
||||
// if(shipment.getFromCoord() != null) {
|
||||
// xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.coord[@x]", shipment.getToCoord().getX());
|
||||
// xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.coord[@y]", shipment.getToCoord().getY());
|
||||
// }
|
||||
// xmlConfig.setProperty(shipmentPathString + "("+counter+").size", shipment.getSize());
|
||||
// xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.serviceTime", shipment.getPickupServiceTime());
|
||||
// xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.timeWindows.timeWindow(0).start", shipment.getPickupTW().getStart());
|
||||
// xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.timeWindows.timeWindow(0).end", shipment.getPickupTW().getEnd());
|
||||
//
|
||||
// xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.serviceTime", shipment.getDeliveryServiceTime());
|
||||
// xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.timeWindows.timeWindow(0).start", shipment.getDeliveryTW().getStart());
|
||||
// xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.timeWindows.timeWindow(0).end", shipment.getDeliveryTW().getEnd());
|
||||
//
|
||||
// counter++;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
private void writeProblemType(XMLConfiguration xmlConfig){
|
||||
xmlConfig.setProperty("problemType.fleetSize", vrp.getFleetSize());
|
||||
|
|
@ -206,19 +176,6 @@ public class VrpXMLWriter {
|
|||
}
|
||||
|
||||
private void writeVehiclesAndTheirTypes(XMLConfiguration xmlConfig) {
|
||||
|
||||
// //depots
|
||||
// Map<Depot,Integer> depot2id = new HashMap<Depot, Integer>();
|
||||
// int depotCounter = 0;
|
||||
// for(Depot depot : vrp.getDepots()){
|
||||
// int depotId = depotCounter+1;
|
||||
// depot2id.put(depot, depotId);
|
||||
// xmlConfig.setProperty("depots.depot" + "("+depotCounter+")[@id]", (depotId));
|
||||
// xmlConfig.setProperty("depots.depot" + "("+depotCounter+").locationId", depot.getId());
|
||||
// xmlConfig.setProperty("depots.depot" + "("+depotCounter+").coord[@x]", depot.getCoord().getX());
|
||||
// xmlConfig.setProperty("depots.depot" + "("+depotCounter+").coord[@y]", depot.getCoord().getY());
|
||||
// depotCounter++;
|
||||
// }
|
||||
|
||||
//vehicles
|
||||
String vehiclePathString = new StringBuilder().append(Schema.VEHICLES).append(".").
|
||||
|
|
@ -234,13 +191,7 @@ public class VrpXMLWriter {
|
|||
}
|
||||
xmlConfig.setProperty(vehiclePathString + "("+counter+").timeSchedule.start", vehicle.getEarliestDeparture());
|
||||
xmlConfig.setProperty(vehiclePathString + "("+counter+").timeSchedule.end", vehicle.getLatestArrival());
|
||||
// if(vehicle.getLocationId() != null) xmlConfig.setProperty(vehiclePathString + "("+counter+").locationId", vehicle.getLocationId());
|
||||
// if(vehicle.getCoord() != null) {
|
||||
// xmlConfig.setProperty(vehiclePathString + "("+counter+").coord[@x]", vehicle.getCoord().getX());
|
||||
// xmlConfig.setProperty(vehiclePathString + "("+counter+").coord[@y]", vehicle.getCoord().getY());
|
||||
// }
|
||||
// xmlConfig.setProperty(vehiclePathString + "("+counter+").earliestStart", vehicle.getEarliestDeparture());
|
||||
// xmlConfig.setProperty(vehiclePathString + "("+counter+").latestEnd", vehicle.getLatestArrival());
|
||||
|
||||
counter++;
|
||||
}
|
||||
|
||||
|
|
@ -250,44 +201,13 @@ public class VrpXMLWriter {
|
|||
for(VehicleType type : vrp.getTypes()){
|
||||
xmlConfig.setProperty(typePathString + "("+typeCounter+").id", type.getTypeId());
|
||||
xmlConfig.setProperty(typePathString + "("+typeCounter+").capacity", type.getCapacity());
|
||||
// xmlConfig.setProperty(typePathString + "("+typeCounter+").timeSchedule.start", type.getTimeSchedule().getEarliestStart());
|
||||
// xmlConfig.setProperty(typePathString + "("+typeCounter+").timeSchedule.end", type.getTimeSchedule().getLatestEnd());
|
||||
xmlConfig.setProperty(typePathString + "("+typeCounter+").costs.fixed", type.getVehicleCostParams().fix);
|
||||
xmlConfig.setProperty(typePathString + "("+typeCounter+").costs.distance", type.getVehicleCostParams().perDistanceUnit);
|
||||
xmlConfig.setProperty(typePathString + "("+typeCounter+").costs.time", type.getVehicleCostParams().perTimeUnit);
|
||||
typeCounter++;
|
||||
}
|
||||
|
||||
|
||||
// //type2depot assignments
|
||||
// int assignmentCounter = 0;
|
||||
// boolean first = true;
|
||||
// for(Depot depot : vrp.getDepotToVehicleTypeAssignments().keySet()){
|
||||
// if(first){
|
||||
// xmlConfig.setProperty("assignments[@type]", "vehicleType2depot");
|
||||
// }
|
||||
// for(VehicleType type : vrp.getDepotToVehicleTypeAssignments().get(depot)){
|
||||
// xmlConfig.setProperty("assignments.assignment" + "("+assignmentCounter+").depotId", depot2id.get(depot));
|
||||
// xmlConfig.setProperty("assignments.assignment" + "("+assignmentCounter+").vehicleTypeId", type.getTypeId());
|
||||
// assignmentCounter++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //vehicle2depot assignments
|
||||
// int vehicleAssignmentCounter = 0;
|
||||
// boolean first_ = true;
|
||||
// for(Depot depot : vrp.getDepotToVehicleAssignments().keySet()){
|
||||
// if(first_){
|
||||
// xmlConfig.setProperty("assignments[@type]", "vehicle2depot");
|
||||
// }
|
||||
// for(Vehicle vehicle : vrp.getDepotToVehicleAssignments().get(depot)){
|
||||
// xmlConfig.setProperty("assignments.assignment" + "("+vehicleAssignmentCounter+").depotId", depot2id.get(depot));
|
||||
// xmlConfig.setProperty("assignments.assignment" + "("+vehicleAssignmentCounter+").vehicleId", vehicle.getId());
|
||||
// vehicleAssignmentCounter++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package basics.route;
|
||||
|
||||
import basics.Delivery;
|
||||
import basics.Pickup;
|
||||
import basics.Service;
|
||||
|
||||
public class DefaultTourActivityFactory implements TourActivityFactory{
|
||||
|
||||
@Override
|
||||
public TourActivity createActivity(Service service) {
|
||||
TourActivity act;
|
||||
if(service instanceof Pickup){
|
||||
act = new PickupActivity((Pickup) service);
|
||||
}
|
||||
else if(service instanceof Delivery){
|
||||
act = new DeliveryActivity((Delivery) service);
|
||||
}
|
||||
else{
|
||||
act = ServiceActivity.newInstance(service);
|
||||
}
|
||||
return act;
|
||||
}
|
||||
|
||||
}
|
||||
105
jsprit-core/src/main/java/basics/route/DeliveryActivity.java
Normal file
105
jsprit-core/src/main/java/basics/route/DeliveryActivity.java
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package basics.route;
|
||||
|
||||
import basics.Delivery;
|
||||
import basics.route.TourActivity.JobActivity;
|
||||
|
||||
public class DeliveryActivity implements JobActivity<Delivery>{
|
||||
|
||||
private Delivery delivery;
|
||||
|
||||
private double arrTime;
|
||||
|
||||
private double endTime;
|
||||
|
||||
public DeliveryActivity(Delivery delivery) {
|
||||
super();
|
||||
this.delivery = delivery;
|
||||
}
|
||||
|
||||
private DeliveryActivity(DeliveryActivity deliveryActivity){
|
||||
this.delivery=deliveryActivity.getJob();
|
||||
this.arrTime=deliveryActivity.getArrTime();
|
||||
this.endTime=deliveryActivity.getEndTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCapacityDemand() {
|
||||
return delivery.getCapacityDemand()*-1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return delivery.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocationId() {
|
||||
return delivery.getLocationId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTheoreticalEarliestOperationStartTime() {
|
||||
return delivery.getTimeWindow().getStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTheoreticalLatestOperationStartTime() {
|
||||
return delivery.getTimeWindow().getEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getOperationTime() {
|
||||
return delivery.getServiceDuration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getArrTime() {
|
||||
return arrTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArrTime(double arrTime) {
|
||||
this.arrTime=arrTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEndTime(double endTime) {
|
||||
this.endTime=endTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TourActivity duplicate() {
|
||||
return new DeliveryActivity(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Delivery getJob() {
|
||||
return delivery;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package basics.route;
|
||||
|
||||
import basics.route.VehicleTypeImpl.VehicleCostParams;
|
||||
|
|
|
|||
106
jsprit-core/src/main/java/basics/route/PickupActivity.java
Normal file
106
jsprit-core/src/main/java/basics/route/PickupActivity.java
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package basics.route;
|
||||
|
||||
import basics.Pickup;
|
||||
import basics.route.TourActivity.JobActivity;
|
||||
|
||||
public class PickupActivity implements JobActivity<Pickup>{
|
||||
|
||||
private Pickup pickup;
|
||||
|
||||
private double arrTime;
|
||||
|
||||
private double depTime;
|
||||
|
||||
public PickupActivity(Pickup pickup) {
|
||||
super();
|
||||
this.pickup = pickup;
|
||||
}
|
||||
|
||||
private PickupActivity(PickupActivity pickupActivity){
|
||||
this.pickup=pickupActivity.getJob();
|
||||
this.arrTime=pickupActivity.getArrTime();
|
||||
this.depTime=pickupActivity.getEndTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return pickup.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocationId() {
|
||||
return pickup.getLocationId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTheoreticalEarliestOperationStartTime() {
|
||||
return pickup.getTimeWindow().getStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTheoreticalLatestOperationStartTime() {
|
||||
return pickup.getTimeWindow().getEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getOperationTime() {
|
||||
return pickup.getServiceDuration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getArrTime() {
|
||||
return arrTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getEndTime() {
|
||||
return depTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArrTime(double arrTime) {
|
||||
this.arrTime=arrTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEndTime(double endTime) {
|
||||
this.depTime=endTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TourActivity duplicate() {
|
||||
return new PickupActivity(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pickup getJob() {
|
||||
return pickup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCapacityDemand() {
|
||||
return pickup.getCapacityDemand();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -31,6 +31,8 @@ public class ServiceActivity implements JobActivity<Service>{
|
|||
|
||||
public double endTime;
|
||||
|
||||
public int capacityDemand;
|
||||
|
||||
/**
|
||||
* @return the arrTime
|
||||
*/
|
||||
|
|
@ -67,18 +69,31 @@ public class ServiceActivity implements JobActivity<Service>{
|
|||
return new ServiceActivity(service);
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a new instance of {@link ServiceActivity} with a flag that indicates whether smthing is unloaded or loaded.
|
||||
*
|
||||
* @param service
|
||||
* @param capacityDemand
|
||||
* @return
|
||||
*/
|
||||
// public static ServiceActivity newInstance(Service service, boolean isPickup){
|
||||
// return new ServiceActivity(service, capacityDemand);
|
||||
// }
|
||||
|
||||
private final Service service;
|
||||
|
||||
private ServiceActivity(Service service) {
|
||||
protected ServiceActivity(Service service) {
|
||||
counter++;
|
||||
this.service = service;
|
||||
this.capacityDemand = service.getCapacityDemand();
|
||||
}
|
||||
|
||||
private ServiceActivity(ServiceActivity serviceActivity) {
|
||||
|
||||
protected ServiceActivity(ServiceActivity serviceActivity) {
|
||||
counter++;
|
||||
this.service = serviceActivity.getJob();
|
||||
this.arrTime = serviceActivity.getArrTime();
|
||||
this.endTime = serviceActivity.getEndTime();
|
||||
this.capacityDemand = serviceActivity.getCapacityDemand();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -123,7 +138,7 @@ public class ServiceActivity implements JobActivity<Service>{
|
|||
|
||||
@Override
|
||||
public int getCapacityDemand() {
|
||||
return service.getCapacityDemand();
|
||||
return this.capacityDemand;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package basics.route;
|
||||
|
||||
import basics.Service;
|
||||
|
||||
public interface TourActivityFactory {
|
||||
|
||||
public TourActivity createActivity(Service service);
|
||||
|
||||
}
|
||||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package basics.route;
|
||||
|
||||
import basics.route.VehicleTypeImpl.VehicleCostParams;
|
||||
|
|
@ -13,4 +33,4 @@ public interface VehicleType {
|
|||
|
||||
public VehicleCostParams getVehicleCostParams();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package basics.route;
|
||||
|
||||
|
||||
|
|
@ -148,4 +168,4 @@ public class VehicleTypeImpl implements VehicleType {
|
|||
public double getMaxVelocity() {
|
||||
return maxVelocity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package util;
|
||||
|
||||
import basics.VehicleRoutingProblem;
|
||||
|
|
@ -14,4 +34,4 @@ public class BenchmarkInstance {
|
|||
this.bestKnownResult = bestKnownResult;
|
||||
this.bestKnownVehicles = bestKnowVehicles;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package util;
|
||||
|
||||
import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;
|
||||
|
|
@ -53,4 +73,4 @@ public class BenchmarkResult {
|
|||
return statsTimes;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package util;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,26 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
|
|
@ -9,6 +29,8 @@ import org.junit.Test;
|
|||
|
||||
import util.Solutions;
|
||||
import algorithms.HardConstraints.HardActivityLevelConstraint;
|
||||
import algorithms.StateUpdates.UpdateCostsAtRouteLevel;
|
||||
import algorithms.StateUpdates.UpdateLoadAtRouteLevel;
|
||||
import algorithms.acceptors.AcceptNewIfBetterThanWorst;
|
||||
import algorithms.selectors.SelectBest;
|
||||
import basics.VehicleRoutingAlgorithm;
|
||||
|
|
@ -36,7 +58,7 @@ public class BuildCVRPAlgoFromScratchTest {
|
|||
HardActivityLevelConstraint hardActLevelConstraint = new HardActivityLevelConstraint() {
|
||||
|
||||
@Override
|
||||
public boolean fulfilled(InsertionContext iFacts, TourActivity act, double arrTime) {
|
||||
public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
@ -76,7 +98,7 @@ public class BuildCVRPAlgoFromScratchTest {
|
|||
vra.getAlgorithmListeners().addListener(clearStateManager);
|
||||
vra.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(fleetManager));
|
||||
|
||||
vra.getSearchStrategyManager().addSearchStrategyModuleListener(new UdateCostsAtRouteLevel(stateManager, vrp.getTransportCosts(), vrp.getActivityCosts()));
|
||||
vra.getSearchStrategyManager().addSearchStrategyModuleListener(new UpdateCostsAtRouteLevel(stateManager, vrp.getTransportCosts(), vrp.getActivityCosts()));
|
||||
vra.getSearchStrategyManager().addSearchStrategyModuleListener(new UpdateLoadAtRouteLevel(stateManager));
|
||||
|
||||
VehicleRoutingProblemSolution iniSolution = new CreateInitialSolution(bestInsertion).createInitialSolution(vrp);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,192 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import util.Solutions;
|
||||
import algorithms.BackwardInTimeListeners.BackwardInTimeListener;
|
||||
import algorithms.ForwardInTimeListeners.ForwardInTimeListener;
|
||||
import algorithms.HardConstraints.HardActivityLevelConstraintManager;
|
||||
import algorithms.StateManager.StateImpl;
|
||||
import algorithms.StateUpdates.UpdateActivityTimes;
|
||||
import algorithms.StateUpdates.UpdateCostsAtAllLevels;
|
||||
import algorithms.StateUpdates.UpdateEarliestStartTimeWindowAtActLocations;
|
||||
import algorithms.StateUpdates.UpdateLatestOperationStartTimeAtActLocations;
|
||||
import algorithms.acceptors.AcceptNewIfBetterThanWorst;
|
||||
import algorithms.selectors.SelectBest;
|
||||
import basics.Delivery;
|
||||
import basics.Job;
|
||||
import basics.Pickup;
|
||||
import basics.VehicleRoutingAlgorithm;
|
||||
import basics.VehicleRoutingProblem;
|
||||
import basics.VehicleRoutingProblemSolution;
|
||||
import basics.algo.InsertionStartsListener;
|
||||
import basics.algo.IterationStartsListener;
|
||||
import basics.algo.JobInsertedListener;
|
||||
import basics.algo.SearchStrategy;
|
||||
import basics.algo.SearchStrategyManager;
|
||||
import basics.io.VrpXMLReader;
|
||||
import basics.io.VrpXMLWriter;
|
||||
import basics.route.DeliveryActivity;
|
||||
import basics.route.End;
|
||||
import basics.route.PickupActivity;
|
||||
import basics.route.Start;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
public class BuildPDVRPAlgoFromScratchTest {
|
||||
|
||||
VehicleRoutingProblem vrp;
|
||||
|
||||
VehicleRoutingAlgorithm vra;
|
||||
|
||||
static Logger log = Logger.getLogger(BuildPDVRPAlgoFromScratchTest.class);
|
||||
|
||||
@Before
|
||||
public void setup(){
|
||||
|
||||
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrpXMLReader(builder).read("src/test/resources/pd_solomon_r101.xml");
|
||||
vrp = builder.build();
|
||||
|
||||
final StateManagerImpl stateManager = new StateManagerImpl();
|
||||
|
||||
HardActivityLevelConstraintManager actLevelConstraintAccumulator = new HardActivityLevelConstraintManager();
|
||||
actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardPickupAndDeliveryActivityLevelConstraint(stateManager));
|
||||
actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts()));
|
||||
|
||||
MarginalsCalculus marginalCalculus = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), actLevelConstraintAccumulator);
|
||||
|
||||
CalculatesServiceInsertion serviceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardPickupAndDeliveryLoadConstraint(stateManager));
|
||||
// CalculatesServiceInsertion serviceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardLoadConstraint(stateManager));
|
||||
|
||||
VehicleFleetManager fleetManager = new InfiniteVehicles(vrp.getVehicles());
|
||||
JobInsertionCalculator finalServiceInsertion = new CalculatesVehTypeDepServiceInsertion(fleetManager, serviceInsertion);
|
||||
|
||||
BestInsertion bestInsertion = new BestInsertion(finalServiceInsertion);
|
||||
|
||||
RuinRadial radial = new RuinRadial(vrp, 0.15, new JobDistanceAvgCosts(vrp.getTransportCosts()));
|
||||
RuinRandom random = new RuinRandom(vrp, 0.25);
|
||||
|
||||
SearchStrategy randomStrategy = new SearchStrategy(new SelectBest(), new AcceptNewIfBetterThanWorst(1));
|
||||
RuinAndRecreateModule randomModule = new RuinAndRecreateModule("randomRuin_bestInsertion", bestInsertion, random);
|
||||
randomStrategy.addModule(randomModule);
|
||||
|
||||
SearchStrategy radialStrategy = new SearchStrategy(new SelectBest(), new AcceptNewIfBetterThanWorst(1));
|
||||
RuinAndRecreateModule radialModule = new RuinAndRecreateModule("radialRuin_bestInsertion", bestInsertion, radial);
|
||||
radialStrategy.addModule(radialModule);
|
||||
|
||||
SearchStrategyManager strategyManager = new SearchStrategyManager();
|
||||
strategyManager.addStrategy(radialStrategy, 0.5);
|
||||
strategyManager.addStrategy(randomStrategy, 0.5);
|
||||
|
||||
vra = new VehicleRoutingAlgorithm(vrp, strategyManager);
|
||||
|
||||
|
||||
vra.getAlgorithmListeners().addListener(new StateUpdates.ResetStateManager(stateManager));
|
||||
|
||||
final IterateRouteForwardInTime iterateForward = new IterateRouteForwardInTime(vrp.getTransportCosts());
|
||||
|
||||
iterateForward.addListener(new UpdateActivityTimes());
|
||||
iterateForward.addListener(new UpdateEarliestStartTimeWindowAtActLocations(stateManager));
|
||||
iterateForward.addListener(new UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
||||
|
||||
iterateForward.addListener(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager));
|
||||
iterateForward.addListener(new StateUpdates.UpdateLoadAtActivityLevel(stateManager));
|
||||
|
||||
final IterateRouteBackwardInTime iterateBackward = new IterateRouteBackwardInTime(vrp.getTransportCosts());
|
||||
iterateBackward.addListener(new UpdateLatestOperationStartTimeAtActLocations(stateManager));
|
||||
iterateBackward.addListener(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager));
|
||||
|
||||
|
||||
InsertionStartsListener loadVehicleInDepot = new InsertionStartsListener() {
|
||||
|
||||
@Override
|
||||
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||
for(VehicleRoute route : vehicleRoutes){
|
||||
int loadAtDepot = 0;
|
||||
int loadAtEnd = 0;
|
||||
for(Job j : route.getTourActivities().getJobs()){
|
||||
if(j instanceof Delivery){
|
||||
loadAtDepot += j.getCapacityDemand();
|
||||
}
|
||||
if(j instanceof Pickup){
|
||||
loadAtEnd += j.getCapacityDemand();
|
||||
}
|
||||
}
|
||||
stateManager.putRouteState(route, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot));
|
||||
stateManager.putRouteState(route, StateTypes.LOAD, new StateImpl(loadAtEnd));
|
||||
iterateForward.iterate(route);
|
||||
iterateBackward.iterate(route);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
vra.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(fleetManager));
|
||||
|
||||
JobInsertedListener updateLoadAfterJobHasBeenInserted = new JobInsertedListener() {
|
||||
|
||||
@Override
|
||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||
// log.info("insert job " + job2insert.getClass().toString() + " job " + job2insert + "" + job2insert.getCapacityDemand() + " in route " + inRoute.getTourActivities());
|
||||
|
||||
if(job2insert instanceof Delivery){
|
||||
int loadAtDepot = (int) stateManager.getRouteState(inRoute, StateTypes.LOAD_AT_DEPOT).toDouble();
|
||||
// log.info("loadAtDepot="+loadAtDepot);
|
||||
stateManager.putRouteState(inRoute, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot + job2insert.getCapacityDemand()));
|
||||
}
|
||||
if(job2insert instanceof Pickup){
|
||||
int loadAtEnd = (int) stateManager.getRouteState(inRoute, StateTypes.LOAD).toDouble();
|
||||
// log.info("loadAtEnd="+loadAtEnd);
|
||||
stateManager.putRouteState(inRoute, StateTypes.LOAD, new StateImpl(loadAtEnd + job2insert.getCapacityDemand()));
|
||||
}
|
||||
iterateForward.iterate(inRoute);
|
||||
iterateBackward.iterate(inRoute);
|
||||
}
|
||||
};
|
||||
|
||||
bestInsertion.addListener(loadVehicleInDepot);
|
||||
bestInsertion.addListener(updateLoadAfterJobHasBeenInserted);
|
||||
|
||||
VehicleRoutingProblemSolution iniSolution = new CreateInitialSolution(bestInsertion).createInitialSolution(vrp);
|
||||
// System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size());
|
||||
vra.addInitialSolution(iniSolution);
|
||||
|
||||
vra.setNuOfIterations(10000);
|
||||
vra.setPrematureBreak(1000);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test(){
|
||||
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
||||
// System.out.println(Solutions.getBest(solutions).getCost());
|
||||
// new VrpXMLWriter(vrp, solutions).write("output/pd_solomon_r101.xml");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -33,6 +33,7 @@ import org.junit.Test;
|
|||
import util.Coordinate;
|
||||
import util.ManhattanDistanceCalculator;
|
||||
import util.RouteUtils;
|
||||
import algorithms.StateUpdates.UpdateStates;
|
||||
import basics.Job;
|
||||
import basics.Service;
|
||||
import basics.VehicleRoutingProblem;
|
||||
|
|
@ -151,7 +152,7 @@ public class GendreauPostOptTest {
|
|||
|
||||
activityCosts = new ExampleActivityCostFunction();
|
||||
|
||||
CalculatesServiceInsertion standardServiceInsertion = new CalculatesServiceInsertion(cost, new MarginalsCalculusTriangleInequality(cost, activityCosts, new HardConstraints.HardTimeWindowConstraint(states)), new HardConstraints.HardLoadConstraint(states));
|
||||
CalculatesServiceInsertion standardServiceInsertion = new CalculatesServiceInsertion(cost, new MarginalsCalculusTriangleInequality(cost, activityCosts, new HardConstraints.HardTimeWindowActivityLevelConstraint(states, cost)), new HardConstraints.HardLoadConstraint(states));
|
||||
|
||||
CalculatesServiceInsertionConsideringFixCost withFixCost = new CalculatesServiceInsertionConsideringFixCost(standardServiceInsertion, states);
|
||||
withFixCost.setWeightOfFixCost(1.2);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
|
|
|||
|
|
@ -32,17 +32,18 @@ import org.apache.log4j.Logger;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import algorithms.StateUpdates.UpdateStates;
|
||||
import basics.Job;
|
||||
import basics.Service;
|
||||
import basics.costs.VehicleRoutingTransportCosts;
|
||||
import basics.route.DriverImpl;
|
||||
import basics.route.DriverImpl.NoDriver;
|
||||
import basics.route.ServiceActivity;
|
||||
import basics.route.TimeWindow;
|
||||
import basics.route.TourActivities;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.Vehicle;
|
||||
import basics.route.VehicleRoute;
|
||||
import basics.route.DriverImpl.NoDriver;
|
||||
|
||||
|
||||
|
||||
|
|
@ -156,7 +157,7 @@ public class TestCalculatesServiceInsertion {
|
|||
|
||||
ExampleActivityCostFunction activityCosts = new ExampleActivityCostFunction();
|
||||
|
||||
serviceInsertion = new CalculatesServiceInsertion(costs, new MarginalsCalculusTriangleInequality(costs, activityCosts, new HardConstraints.HardTimeWindowConstraint(states)), new HardConstraints.HardLoadConstraint(states));
|
||||
serviceInsertion = new CalculatesServiceInsertion(costs, new MarginalsCalculusTriangleInequality(costs, activityCosts, new HardConstraints.HardTimeWindowActivityLevelConstraint(states, costs)), new HardConstraints.HardLoadConstraint(states));
|
||||
|
||||
stateUpdater = new UpdateStates(states, costs, activityCosts);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,18 +34,19 @@ import org.junit.Test;
|
|||
|
||||
import util.Coordinate;
|
||||
import util.ManhattanDistanceCalculator;
|
||||
import algorithms.StateUpdates.UpdateStates;
|
||||
import basics.Job;
|
||||
import basics.Service;
|
||||
import basics.costs.VehicleRoutingTransportCosts;
|
||||
import basics.route.Driver;
|
||||
import basics.route.DriverImpl;
|
||||
import basics.route.DriverImpl.NoDriver;
|
||||
import basics.route.ServiceActivity;
|
||||
import basics.route.TimeWindow;
|
||||
import basics.route.TourActivities;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.Vehicle;
|
||||
import basics.route.VehicleRoute;
|
||||
import basics.route.DriverImpl.NoDriver;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
|
@ -10,6 +30,10 @@ import org.junit.Test;
|
|||
|
||||
import util.Coordinate;
|
||||
import util.ManhattanDistanceCalculator;
|
||||
import algorithms.StateUpdates.UpdateActivityTimes;
|
||||
import algorithms.StateUpdates.UpdateCostsAtAllLevels;
|
||||
import algorithms.StateUpdates.UpdateEarliestStartTimeWindowAtActLocations;
|
||||
import algorithms.StateUpdates.UpdateLoadAtAllLevels;
|
||||
import basics.Job;
|
||||
import basics.Service;
|
||||
import basics.costs.DefaultVehicleRoutingActivityCosts;
|
||||
|
|
@ -34,10 +58,6 @@ public class TestIterateRouteForwardInTime {
|
|||
|
||||
TourActivities anotherTour;
|
||||
|
||||
|
||||
|
||||
RouteStates states;
|
||||
|
||||
private VehicleRoute vehicleRoute;
|
||||
|
||||
private VehicleRoutingTransportCosts cost;
|
||||
|
|
@ -46,6 +66,8 @@ public class TestIterateRouteForwardInTime {
|
|||
|
||||
ServiceActivity secondAct;
|
||||
|
||||
StateManagerImpl stateManager;
|
||||
|
||||
@Before
|
||||
public void setUp(){
|
||||
cost = new VehicleRoutingTransportCosts() {
|
||||
|
|
@ -99,6 +121,8 @@ public class TestIterateRouteForwardInTime {
|
|||
tour.addActivity(secondAct);
|
||||
|
||||
vehicleRoute = VehicleRoute.newInstance(tour,DriverImpl.noDriver(),vehicle);
|
||||
|
||||
stateManager = new StateManagerImpl();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -129,12 +153,11 @@ public class TestIterateRouteForwardInTime {
|
|||
@Test
|
||||
public void whenIteratingWithLoadUpdateAtActLocations_itShouldUpdateLoad() {
|
||||
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
|
||||
StateManagerImpl states = new StateManagerImpl();
|
||||
forwardInTime.addListener(new UpdateLoadAtAllLevels(states));
|
||||
forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager));
|
||||
forwardInTime.iterate(vehicleRoute);
|
||||
|
||||
assertEquals(5.0, states.getActivityStates(firstAct).getState(StateTypes.LOAD).toDouble(), 0.01);
|
||||
assertEquals(10.0, states.getActivityStates(secondAct).getState(StateTypes.LOAD).toDouble(), 0.01);
|
||||
assertEquals(5.0, stateManager.getActivityState(firstAct,StateTypes.LOAD).toDouble(), 0.01);
|
||||
assertEquals(10.0, stateManager.getActivityState(secondAct,StateTypes.LOAD).toDouble(), 0.01);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -153,42 +176,41 @@ public class TestIterateRouteForwardInTime {
|
|||
@Test
|
||||
public void testStatesOfAct1(){
|
||||
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
|
||||
StateManagerImpl states = new StateManagerImpl();
|
||||
forwardInTime.addListener(new UpdateLoadAtAllLevels(states));
|
||||
forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(states));
|
||||
forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, states));
|
||||
forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager));
|
||||
forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(stateManager));
|
||||
forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
|
||||
forwardInTime.iterate(vehicleRoute);
|
||||
|
||||
assertEquals(10.0, states.getActivityStates(firstAct).getState(StateTypes.COSTS).toDouble(),0.05);
|
||||
assertEquals(5.0, states.getActivityStates(firstAct).getState(StateTypes.LOAD).toDouble(),0.05);
|
||||
assertEquals(10.0, states.getActivityStates(firstAct).getState(StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05);
|
||||
assertEquals(10.0, stateManager.getActivityState(firstAct, StateTypes.COSTS).toDouble(),0.05);
|
||||
assertEquals(5.0, stateManager.getActivityState(firstAct, StateTypes.LOAD).toDouble(),0.05);
|
||||
assertEquals(10.0, stateManager.getActivityState(firstAct, StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05);
|
||||
// assertEquals(20.0, states.getState(tour.getActivities().get(0)).getLatestOperationStart(),0.05);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatesOfAct2(){
|
||||
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
|
||||
StateManagerImpl states = new StateManagerImpl();
|
||||
forwardInTime.addListener(new UpdateLoadAtAllLevels(states));
|
||||
forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(states));
|
||||
forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, states));
|
||||
|
||||
forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager));
|
||||
forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(stateManager));
|
||||
forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
|
||||
forwardInTime.iterate(vehicleRoute);
|
||||
|
||||
assertEquals(30.0, states.getActivityStates(secondAct).getState(StateTypes.COSTS).toDouble(),0.05);
|
||||
assertEquals(10.0, states.getActivityStates(secondAct).getState(StateTypes.LOAD).toDouble(),0.05);
|
||||
assertEquals(30.0, states.getActivityStates(secondAct).getState(StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05);
|
||||
assertEquals(30.0, stateManager.getActivityState(secondAct, StateTypes.COSTS).toDouble(),0.05);
|
||||
assertEquals(10.0, stateManager.getActivityState(secondAct, StateTypes.LOAD).toDouble(),0.05);
|
||||
assertEquals(30.0, stateManager.getActivityState(secondAct, StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05);
|
||||
// assertEquals(40.0, states.getState(tour.getActivities().get(1)).getLatestOperationStart(),0.05);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatesOfAct3(){
|
||||
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
|
||||
StateManagerImpl states = new StateManagerImpl();
|
||||
|
||||
forwardInTime.addListener(new UpdateActivityTimes());
|
||||
forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, states));
|
||||
forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
|
||||
forwardInTime.iterate(vehicleRoute);
|
||||
|
||||
assertEquals(40.0, states.getRouteStates(vehicleRoute).getState(StateTypes.COSTS).toDouble(), 0.05);
|
||||
assertEquals(40.0, stateManager.getRouteState(vehicleRoute,StateTypes.COSTS).toDouble(), 0.05);
|
||||
assertEquals(40.0, vehicleRoute.getEnd().getArrTime(),0.05);
|
||||
assertEquals(50.0, vehicleRoute.getEnd().getTheoreticalLatestOperationStartTime(),0.05);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributors:
|
||||
* Stefan Schroeder - initial API and implementation
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import org.junit.Test;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import org.junit.Test;
|
|||
|
||||
import util.Coordinate;
|
||||
import util.ManhattanDistanceCalculator;
|
||||
import algorithms.StateUpdates.UpdateStates;
|
||||
import basics.Job;
|
||||
import basics.Service;
|
||||
import basics.costs.VehicleRoutingTransportCosts;
|
||||
|
|
@ -38,7 +39,6 @@ import basics.route.TourActivities;
|
|||
import basics.route.Vehicle;
|
||||
import basics.route.VehicleImpl;
|
||||
import basics.route.VehicleRoute;
|
||||
import basics.route.VehicleType;
|
||||
import basics.route.VehicleTypeImpl;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ public class VrpReaderV2Test {
|
|||
new VrpXMLReader(builder, null).read(inFileName);
|
||||
VehicleRoutingProblem vrp = builder.build();
|
||||
Service s1 = (Service) vrp.getJobs().get("1");
|
||||
assertEquals("delivery",s1.getType());
|
||||
assertEquals("service",s1.getType());
|
||||
assertEquals(1,s1.getCapacityDemand());
|
||||
assertEquals(0.0,s1.getServiceDuration(),0.01);
|
||||
assertEquals(2, vrp.getJobs().size());
|
||||
|
|
|
|||
|
|
@ -130,8 +130,8 @@ public class VrpWriterV2Test {
|
|||
builder.addVehicle(v1);
|
||||
builder.addVehicle(v2);
|
||||
|
||||
Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setName("delivery").setServiceTime(2.0).build();
|
||||
Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setName("delivery").setServiceTime(4.0).build();
|
||||
Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setServiceTime(2.0).build();
|
||||
Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setServiceTime(4.0).build();
|
||||
|
||||
VehicleRoutingProblem vrp = builder.addService(s1).addService(s2).build();
|
||||
new VrpXMLWriter(vrp, null).write(infileName);
|
||||
|
|
@ -144,7 +144,7 @@ public class VrpWriterV2Test {
|
|||
Service s1_read = (Service) vrp.getJobs().get("1");
|
||||
assertEquals("1", s1_read.getId());
|
||||
assertEquals("loc", s1_read.getLocationId());
|
||||
assertEquals("delivery", s1_read.getType());
|
||||
assertEquals("service", s1_read.getType());
|
||||
assertEquals(2.0,s1_read.getServiceDuration(),0.01);
|
||||
}
|
||||
|
||||
|
|
@ -162,8 +162,8 @@ public class VrpWriterV2Test {
|
|||
builder.addVehicle(v1);
|
||||
builder.addVehicle(v2);
|
||||
|
||||
Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setName("delivery").setServiceTime(2.0).build();
|
||||
Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setName("delivery").setServiceTime(4.0).build();
|
||||
Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setServiceTime(2.0).build();
|
||||
Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setServiceTime(4.0).build();
|
||||
builder.addService(s1).addService(s2);
|
||||
|
||||
VehicleRoutingProblem vrp = builder.build();
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@
|
|||
******************************************************************************/
|
||||
package basics.io;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
|
@ -31,19 +29,15 @@ import org.junit.Test;
|
|||
|
||||
import basics.Service;
|
||||
import basics.VehicleRoutingProblem;
|
||||
import basics.VehicleRoutingProblemSolution;
|
||||
import basics.Service.Builder;
|
||||
import basics.VehicleRoutingProblem.FleetComposition;
|
||||
import basics.VehicleRoutingProblem.FleetSize;
|
||||
import basics.io.VrpXMLReader;
|
||||
import basics.io.VrpXMLWriter;
|
||||
import basics.VehicleRoutingProblemSolution;
|
||||
import basics.route.End;
|
||||
import basics.route.ServiceActivity;
|
||||
import basics.route.Start;
|
||||
import basics.route.Vehicle;
|
||||
import basics.route.VehicleImpl;
|
||||
import basics.route.VehicleRoute;
|
||||
import basics.route.VehicleType;
|
||||
import basics.route.VehicleTypeImpl;
|
||||
|
||||
public class VrpWriterV3Test {
|
||||
|
|
@ -69,8 +63,8 @@ public class VrpWriterV3Test {
|
|||
builder.addVehicle(v1);
|
||||
builder.addVehicle(v2);
|
||||
|
||||
Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setName("delivery").setServiceTime(2.0).build();
|
||||
Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setName("delivery").setServiceTime(4.0).build();
|
||||
Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setServiceTime(2.0).build();
|
||||
Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setServiceTime(4.0).build();
|
||||
builder.addService(s1).addService(s2);
|
||||
|
||||
VehicleRoutingProblem vrp = builder.build();
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@
|
|||
</vehicleTypes>
|
||||
|
||||
<services>
|
||||
<service id="1" type="delivery">
|
||||
<service id="1" type="service">
|
||||
<locationId>j(1,5)</locationId>
|
||||
<coord x="10.0" y="10.0"/>
|
||||
<capacity-demand>1</capacity-demand>
|
||||
|
|
@ -88,7 +88,7 @@
|
|||
</timeWindows>
|
||||
</service>
|
||||
|
||||
<service id="2" type="delivery">
|
||||
<service id="2" type="service">
|
||||
<locationId>i(3,9)</locationId>
|
||||
<coord x="10.0" y="10.0"/>
|
||||
<capacity-demand>1</capacity-demand>
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
</type>
|
||||
</vehicleTypes>
|
||||
<services>
|
||||
<service id="2" type="delivery">
|
||||
<service id="2" type="service">
|
||||
<locationId>loc2</locationId>
|
||||
<capacity-demand>1</capacity-demand>
|
||||
<duration>4.0</duration>
|
||||
|
|
@ -61,7 +61,7 @@
|
|||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="1" type="delivery">
|
||||
<service id="1" type="service">
|
||||
<locationId>loc</locationId>
|
||||
<capacity-demand>1</capacity-demand>
|
||||
<duration>2.0</duration>
|
||||
|
|
@ -82,12 +82,12 @@
|
|||
<driverId>noDriver</driverId>
|
||||
<vehicleId>v1</vehicleId>
|
||||
<start>10.0</start>
|
||||
<act type="delivery">
|
||||
<act type="service">
|
||||
<serviceId>1</serviceId>
|
||||
<arrTime>20.0</arrTime>
|
||||
<endTime>30.0</endTime>
|
||||
</act>
|
||||
<act type="delivery">
|
||||
<act type="service">
|
||||
<serviceId>2</serviceId>
|
||||
<arrTime>40.0</arrTime>
|
||||
<endTime>80.0</endTime>
|
||||
|
|
|
|||
635
jsprit-core/src/test/resources/pdVRP_vrpnc1_jsprit.xml
Normal file
635
jsprit-core/src/test/resources/pdVRP_vrpnc1_jsprit.xml
Normal file
|
|
@ -0,0 +1,635 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problem xmlns="http://www.w3schools.com"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com vrp_xml_schema.xsd">
|
||||
<problemType>
|
||||
<fleetSize>INFINITE</fleetSize>
|
||||
<fleetComposition>HOMOGENEOUS</fleetComposition>
|
||||
</problemType>
|
||||
<vehicles>
|
||||
<vehicle>
|
||||
<id>christophidesVehicle</id>
|
||||
<typeId>christophidesType</typeId>
|
||||
<location>
|
||||
<id>[x=30.0][y=40.0]</id>
|
||||
<coord x="30.0" y="40.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
</vehicles>
|
||||
<vehicleTypes>
|
||||
<type>
|
||||
<id>christophidesType</id>
|
||||
<capacity>50</capacity>
|
||||
<costs>
|
||||
<fixed>0.0</fixed>
|
||||
<distance>1.0</distance>
|
||||
<time>0.0</time>
|
||||
</costs>
|
||||
</type>
|
||||
</vehicleTypes>
|
||||
<services>
|
||||
<service id="35" type="delivery">
|
||||
<locationId>[x=62.0][y=63.0]</locationId>
|
||||
<coord x="62.0" y="63.0"/>
|
||||
<capacity-demand>17</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="36" type="pickup">
|
||||
<locationId>[x=63.0][y=69.0]</locationId>
|
||||
<coord x="63.0" y="69.0"/>
|
||||
<capacity-demand>6</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="33" type="pickup">
|
||||
<locationId>[x=46.0][y=10.0]</locationId>
|
||||
<coord x="46.0" y="10.0"/>
|
||||
<capacity-demand>23</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="34" type="pickup">
|
||||
<locationId>[x=61.0][y=33.0]</locationId>
|
||||
<coord x="61.0" y="33.0"/>
|
||||
<capacity-demand>26</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="39" type="pickup">
|
||||
<locationId>[x=59.0][y=15.0]</locationId>
|
||||
<coord x="59.0" y="15.0"/>
|
||||
<capacity-demand>14</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="37" type="delivery">
|
||||
<locationId>[x=32.0][y=22.0]</locationId>
|
||||
<coord x="32.0" y="22.0"/>
|
||||
<capacity-demand>9</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="38" type="delivery">
|
||||
<locationId>[x=45.0][y=35.0]</locationId>
|
||||
<coord x="45.0" y="35.0"/>
|
||||
<capacity-demand>15</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="43" type="delivery">
|
||||
<locationId>[x=5.0][y=64.0]</locationId>
|
||||
<coord x="5.0" y="64.0"/>
|
||||
<capacity-demand>11</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="42" type="delivery">
|
||||
<locationId>[x=21.0][y=10.0]</locationId>
|
||||
<coord x="21.0" y="10.0"/>
|
||||
<capacity-demand>13</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="41" type="delivery">
|
||||
<locationId>[x=10.0][y=17.0]</locationId>
|
||||
<coord x="10.0" y="17.0"/>
|
||||
<capacity-demand>27</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="40" type="delivery">
|
||||
<locationId>[x=5.0][y=6.0]</locationId>
|
||||
<coord x="5.0" y="6.0"/>
|
||||
<capacity-demand>7</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="22" type="pickup">
|
||||
<locationId>[x=42.0][y=57.0]</locationId>
|
||||
<coord x="42.0" y="57.0"/>
|
||||
<capacity-demand>8</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="23" type="delivery">
|
||||
<locationId>[x=16.0][y=57.0]</locationId>
|
||||
<coord x="16.0" y="57.0"/>
|
||||
<capacity-demand>16</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="24" type="delivery">
|
||||
<locationId>[x=8.0][y=52.0]</locationId>
|
||||
<coord x="8.0" y="52.0"/>
|
||||
<capacity-demand>10</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="25" type="pickup">
|
||||
<locationId>[x=7.0][y=38.0]</locationId>
|
||||
<coord x="7.0" y="38.0"/>
|
||||
<capacity-demand>28</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="26" type="delivery">
|
||||
<locationId>[x=27.0][y=68.0]</locationId>
|
||||
<coord x="27.0" y="68.0"/>
|
||||
<capacity-demand>7</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="27" type="pickup">
|
||||
<locationId>[x=30.0][y=48.0]</locationId>
|
||||
<coord x="30.0" y="48.0"/>
|
||||
<capacity-demand>15</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="28" type="pickup">
|
||||
<locationId>[x=43.0][y=67.0]</locationId>
|
||||
<coord x="43.0" y="67.0"/>
|
||||
<capacity-demand>14</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="29" type="delivery">
|
||||
<locationId>[x=58.0][y=48.0]</locationId>
|
||||
<coord x="58.0" y="48.0"/>
|
||||
<capacity-demand>6</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="3" type="delivery">
|
||||
<locationId>[x=52.0][y=64.0]</locationId>
|
||||
<coord x="52.0" y="64.0"/>
|
||||
<capacity-demand>16</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="2" type="delivery">
|
||||
<locationId>[x=49.0][y=49.0]</locationId>
|
||||
<coord x="49.0" y="49.0"/>
|
||||
<capacity-demand>30</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="1" type="delivery">
|
||||
<locationId>[x=37.0][y=52.0]</locationId>
|
||||
<coord x="37.0" y="52.0"/>
|
||||
<capacity-demand>7</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="7" type="pickup">
|
||||
<locationId>[x=17.0][y=63.0]</locationId>
|
||||
<coord x="17.0" y="63.0"/>
|
||||
<capacity-demand>19</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="30" type="delivery">
|
||||
<locationId>[x=58.0][y=27.0]</locationId>
|
||||
<coord x="58.0" y="27.0"/>
|
||||
<capacity-demand>19</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="6" type="pickup">
|
||||
<locationId>[x=21.0][y=47.0]</locationId>
|
||||
<coord x="21.0" y="47.0"/>
|
||||
<capacity-demand>15</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="5" type="delivery">
|
||||
<locationId>[x=40.0][y=30.0]</locationId>
|
||||
<coord x="40.0" y="30.0"/>
|
||||
<capacity-demand>21</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="32" type="pickup">
|
||||
<locationId>[x=38.0][y=46.0]</locationId>
|
||||
<coord x="38.0" y="46.0"/>
|
||||
<capacity-demand>12</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="4" type="delivery">
|
||||
<locationId>[x=20.0][y=26.0]</locationId>
|
||||
<coord x="20.0" y="26.0"/>
|
||||
<capacity-demand>9</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="31" type="delivery">
|
||||
<locationId>[x=37.0][y=69.0]</locationId>
|
||||
<coord x="37.0" y="69.0"/>
|
||||
<capacity-demand>11</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="9" type="pickup">
|
||||
<locationId>[x=52.0][y=33.0]</locationId>
|
||||
<coord x="52.0" y="33.0"/>
|
||||
<capacity-demand>11</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="8" type="pickup">
|
||||
<locationId>[x=31.0][y=62.0]</locationId>
|
||||
<coord x="31.0" y="62.0"/>
|
||||
<capacity-demand>23</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="19" type="delivery">
|
||||
<locationId>[x=13.0][y=13.0]</locationId>
|
||||
<coord x="13.0" y="13.0"/>
|
||||
<capacity-demand>9</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="17" type="pickup">
|
||||
<locationId>[x=27.0][y=23.0]</locationId>
|
||||
<coord x="27.0" y="23.0"/>
|
||||
<capacity-demand>3</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="18" type="delivery">
|
||||
<locationId>[x=17.0][y=33.0]</locationId>
|
||||
<coord x="17.0" y="33.0"/>
|
||||
<capacity-demand>41</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="15" type="pickup">
|
||||
<locationId>[x=36.0][y=16.0]</locationId>
|
||||
<coord x="36.0" y="16.0"/>
|
||||
<capacity-demand>10</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="16" type="delivery">
|
||||
<locationId>[x=52.0][y=41.0]</locationId>
|
||||
<coord x="52.0" y="41.0"/>
|
||||
<capacity-demand>15</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="13" type="delivery">
|
||||
<locationId>[x=5.0][y=25.0]</locationId>
|
||||
<coord x="5.0" y="25.0"/>
|
||||
<capacity-demand>23</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="14" type="pickup">
|
||||
<locationId>[x=12.0][y=42.0]</locationId>
|
||||
<coord x="12.0" y="42.0"/>
|
||||
<capacity-demand>21</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="11" type="delivery">
|
||||
<locationId>[x=42.0][y=41.0]</locationId>
|
||||
<coord x="42.0" y="41.0"/>
|
||||
<capacity-demand>19</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="12" type="pickup">
|
||||
<locationId>[x=31.0][y=32.0]</locationId>
|
||||
<coord x="31.0" y="32.0"/>
|
||||
<capacity-demand>29</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="21" type="delivery">
|
||||
<locationId>[x=62.0][y=42.0]</locationId>
|
||||
<coord x="62.0" y="42.0"/>
|
||||
<capacity-demand>8</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="20" type="delivery">
|
||||
<locationId>[x=57.0][y=58.0]</locationId>
|
||||
<coord x="57.0" y="58.0"/>
|
||||
<capacity-demand>28</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="49" type="pickup">
|
||||
<locationId>[x=48.0][y=28.0]</locationId>
|
||||
<coord x="48.0" y="28.0"/>
|
||||
<capacity-demand>18</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="48" type="pickup">
|
||||
<locationId>[x=25.0][y=55.0]</locationId>
|
||||
<coord x="25.0" y="55.0"/>
|
||||
<capacity-demand>17</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="45" type="pickup">
|
||||
<locationId>[x=39.0][y=10.0]</locationId>
|
||||
<coord x="39.0" y="10.0"/>
|
||||
<capacity-demand>10</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="44" type="pickup">
|
||||
<locationId>[x=30.0][y=15.0]</locationId>
|
||||
<coord x="30.0" y="15.0"/>
|
||||
<capacity-demand>16</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="47" type="pickup">
|
||||
<locationId>[x=25.0][y=32.0]</locationId>
|
||||
<coord x="25.0" y="32.0"/>
|
||||
<capacity-demand>25</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="46" type="pickup">
|
||||
<locationId>[x=32.0][y=39.0]</locationId>
|
||||
<coord x="32.0" y="39.0"/>
|
||||
<capacity-demand>5</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="10" type="delivery">
|
||||
<locationId>[x=51.0][y=21.0]</locationId>
|
||||
<coord x="51.0" y="21.0"/>
|
||||
<capacity-demand>5</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="50" type="pickup">
|
||||
<locationId>[x=56.0][y=37.0]</locationId>
|
||||
<coord x="56.0" y="37.0"/>
|
||||
<capacity-demand>10</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
</services>
|
||||
</problem>
|
||||
1235
jsprit-core/src/test/resources/pd_solomon_r101.xml
Normal file
1235
jsprit-core/src/test/resources/pd_solomon_r101.xml
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue