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

some adaptations referring to time scheduling experiments

This commit is contained in:
Stefan Schroeder 2014-11-06 20:45:44 +01:00
parent dcfba5463d
commit 99d8cbed69
8 changed files with 209 additions and 125 deletions

View file

@ -117,9 +117,11 @@ final class BestInsertion implements InsertionStrategy{
} }
VehicleRoute newRoute = VehicleRoute.emptyRoute(); VehicleRoute newRoute = VehicleRoute.emptyRoute();
InsertionData newIData = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost); InsertionData newIData = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
if(newIData.getInsertionCost() < bestInsertionCost){ if(!(newIData instanceof NoInsertionFound)){
bestInsertion = new Insertion(newRoute,newIData); if(newIData.getInsertionCost() < bestInsertionCost){
vehicleRoutes.add(newRoute); bestInsertion = new Insertion(newRoute,newIData);
vehicleRoutes.add(newRoute);
}
} }
if(bestInsertion == null) badJobs.add(unassignedJob); if(bestInsertion == null) badJobs.add(unassignedJob);
else inserter.insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute()); else inserter.insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute());

View file

@ -1,93 +1,78 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package jsprit.core.algorithm.recreate; package jsprit.core.algorithm.recreate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import jsprit.core.algorithm.recreate.InsertionData.NoInsertionFound;
import jsprit.core.algorithm.recreate.listener.InsertionStartsListener;
import jsprit.core.problem.driver.Driver; import jsprit.core.problem.driver.Driver;
import jsprit.core.problem.job.Job; import jsprit.core.problem.job.Job;
import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.Vehicle;
import jsprit.core.util.RandomNumberGeneration;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
import java.util.List;
class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsCalculator{ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsCalculator{
private static Logger log = LogManager.getLogger(CalculatesServiceInsertionWithTimeScheduling.class); public static class KnowledgeInjection implements InsertionStartsListener {
private CalculatesServiceInsertionWithTimeScheduling c;
private JobInsertionCostsCalculator jic; public KnowledgeInjection(CalculatesServiceInsertionWithTimeScheduling c) {
super();
// private Random random = new Random(); this.c = c;
}
private int nOfDepartureTimes = 3; @Override
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes,Collection<Job> unassignedJobs) {
private double timeSlice = 900.0; List<Double> knowledge = new ArrayList<Double>();
if(vehicleRoutes.isEmpty()){
public CalculatesServiceInsertionWithTimeScheduling(JobInsertionCostsCalculator jic, double timeSlice, int neighbors) { // System.out.println("hmm");
super(); }
this.jic = jic; for(VehicleRoute route : vehicleRoutes){
this.timeSlice = timeSlice; // if(route.getDepartureTime() == 21600.){
this.nOfDepartureTimes = neighbors; // System.out.println("hu");
log.info("initialise " + this); // }
} knowledge.add(route.getDepartureTime());
}
@Override c.setDepartureTimeKnowledge(knowledge);
public String toString() { }
return "[name=calculatesServiceInsertionWithTimeScheduling][timeSlice="+timeSlice+"][#timeSlice="+nOfDepartureTimes+"]"; }
}
@Override private static Logger log = LogManager.getLogger(CalculatesServiceInsertionWithTimeScheduling.class);
public InsertionData getInsertionData(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore) {
List<Double> vehicleDepartureTimes = new ArrayList<Double>();
double currentStart;
if(currentRoute.getStart() == null){
currentStart = newVehicleDepartureTime;
}
else currentStart = currentRoute.getStart().getEndTime();
vehicleDepartureTimes.add(currentStart);
// double earliestDeparture = newVehicle.getEarliestDeparture();
// double latestEnd = newVehicle.getLatestArrival();
for(int i=0;i<nOfDepartureTimes;i++){
double neighborStartTime_earlier = currentStart - (i+1)*timeSlice;
// if(neighborStartTime_earlier > earliestDeparture) {
vehicleDepartureTimes.add(neighborStartTime_earlier);
// }
double neighborStartTime_later = currentStart + (i+1)*timeSlice;
// if(neighborStartTime_later < latestEnd) {
vehicleDepartureTimes.add(neighborStartTime_later);
// }
}
InsertionData bestIData = null;
for(Double departureTime : vehicleDepartureTimes){
InsertionData iData = jic.getInsertionData(currentRoute, jobToInsert, newVehicle, departureTime, newDriver, bestKnownScore);
if(bestIData == null) bestIData = iData;
else if(iData.getInsertionCost() < bestIData.getInsertionCost()){
iData.setVehicleDepartureTime(departureTime);
bestIData = iData;
}
}
// log.info(bestIData);
return bestIData;
}
private JobInsertionCostsCalculator jic;
private List<Double> departureTimeKnowledge = new ArrayList<Double>();
CalculatesServiceInsertionWithTimeScheduling(JobInsertionCostsCalculator jic, double t, double f) {
super();
this.jic = jic;
log.info("initialise " + this);
}
@Override
public String toString() {
return "[name="+this.getClass().toString()+"]";
}
@Override
public InsertionData getInsertionData(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore) {
double departureTime = newVehicleDepartureTime;
if(currentRoute.isEmpty()){
if(!departureTimeKnowledge.isEmpty()){
departureTime = departureTimeKnowledge.get(RandomNumberGeneration.getRandom().nextInt(departureTimeKnowledge.size()));
}
}
InsertionData insertionData = jic.getInsertionData(currentRoute, jobToInsert, newVehicle, departureTime, newDriver, bestKnownScore);
// if(!(insertionData instanceof NoInsertionFound) && insertionData.getVehicleDepartureTime() < 28000){
// System.out.println("hmm");
// }
return insertionData;
}
public void setDepartureTimeKnowledge(List<Double> departureTimes){
departureTimeKnowledge=departureTimes;
}
} }

View file

@ -0,0 +1,91 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package jsprit.core.algorithm.recreate;
import jsprit.core.problem.driver.Driver;
import jsprit.core.problem.job.Job;
import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.problem.vehicle.Vehicle;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
import java.util.List;
class CalculatesServiceInsertionWithTimeSchedulingInSlices implements JobInsertionCostsCalculator{
private static Logger log = LogManager.getLogger(CalculatesServiceInsertionWithTimeSchedulingInSlices.class);
private JobInsertionCostsCalculator jic;
private int nOfDepartureTimes = 3;
private double timeSlice = 900.0;
public CalculatesServiceInsertionWithTimeSchedulingInSlices(JobInsertionCostsCalculator jic, double timeSlice, int neighbors) {
super();
this.jic = jic;
this.timeSlice = timeSlice;
this.nOfDepartureTimes = neighbors;
log.info("initialise " + this);
}
@Override
public String toString() {
return "[name="+this.getClass().toString()+"][timeSlice="+timeSlice+"][#timeSlice="+nOfDepartureTimes+"]";
}
@Override
public InsertionData getInsertionData(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore) {
List<Double> vehicleDepartureTimes = new ArrayList<Double>();
double currentStart;
if(currentRoute.getStart() == null){
currentStart = newVehicleDepartureTime;
}
else currentStart = currentRoute.getStart().getEndTime();
vehicleDepartureTimes.add(currentStart);
// double earliestDeparture = newVehicle.getEarliestDeparture();
// double latestEnd = newVehicle.getLatestArrival();
for(int i=0;i<nOfDepartureTimes;i++){
double neighborStartTime_earlier = currentStart - (i+1)*timeSlice;
// if(neighborStartTime_earlier > earliestDeparture) {
vehicleDepartureTimes.add(neighborStartTime_earlier);
// }
double neighborStartTime_later = currentStart + (i+1)*timeSlice;
// if(neighborStartTime_later < latestEnd) {
vehicleDepartureTimes.add(neighborStartTime_later);
// }
}
InsertionData bestIData = null;
for(Double departureTime : vehicleDepartureTimes){
InsertionData iData = jic.getInsertionData(currentRoute, jobToInsert, newVehicle, departureTime, newDriver, bestKnownScore);
if(bestIData == null) bestIData = iData;
else if(iData.getInsertionCost() < bestIData.getInsertionCost()){
iData.setVehicleDepartureTime(departureTime);
bestIData = iData;
}
}
// log.info(bestIData);
return bestIData;
}
}

View file

@ -217,7 +217,12 @@ class CalculatorBuilder {
addInsertionListeners(withFixed.getInsertionListener()); addInsertionListeners(withFixed.getInsertionListener());
} }
if(timeScheduling){ if(timeScheduling){
baseCalculator = new CalculatesServiceInsertionWithTimeScheduling(baseCalculator,timeSlice,neighbors); // baseCalculator = new CalculatesServiceInsertionWithTimeSchedulingInSlices(baseCalculator,timeSlice,neighbors);
CalculatesServiceInsertionWithTimeScheduling wts = new CalculatesServiceInsertionWithTimeScheduling(baseCalculator,timeSlice,neighbors);
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(wts);
calcPlusListeners.getInsertionListener().add(new CalculatesServiceInsertionWithTimeScheduling.KnowledgeInjection(wts));
addInsertionListeners(calcPlusListeners.getInsertionListener());
baseCalculator = calcPlusListeners.getCalculator();
} }
return createFinalInsertion(fleetManager, baseCalculator, states); return createFinalInsertion(fleetManager, baseCalculator, states);
} }

View file

@ -114,8 +114,7 @@ final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCo
else depTime = v.getEarliestDeparture(); else depTime = v.getEarliestDeparture();
InsertionData iData = insertionCalculator.getInsertionData(currentRoute, jobToInsert, v, depTime, selectedDriver, bestKnownCost_); InsertionData iData = insertionCalculator.getInsertionData(currentRoute, jobToInsert, v, depTime, selectedDriver, bestKnownCost_);
if(iData instanceof NoInsertionFound) { if(iData instanceof NoInsertionFound) {
if(bestIData instanceof NoInsertionFound) bestIData = iData; continue;
continue;
} }
if(iData.getInsertionCost() < bestKnownCost_){ if(iData.getInsertionCost() < bestKnownCost_){
bestIData = iData; bestIData = iData;

View file

@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals;
import java.util.Collection; import java.util.Collection;
import jsprit.core.algorithm.VehicleRoutingAlgorithm; import jsprit.core.algorithm.VehicleRoutingAlgorithm;
import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; import jsprit.core.algorithm.io.VehicleRoutingAlgorithms;
import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.VehicleRoutingProblem;
@ -36,9 +37,10 @@ import jsprit.core.problem.vehicle.VehicleTypeImpl;
import jsprit.core.util.Coordinate; import jsprit.core.util.Coordinate;
import jsprit.core.util.Solutions; import jsprit.core.util.Solutions;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
@Ignore
public class TestDepartureTimeOpt { public class TestDepartureTimeOpt {
@Test @Test

View file

@ -5,23 +5,6 @@
<fleetSize>FINITE</fleetSize> <fleetSize>FINITE</fleetSize>
</problemType> </problemType>
<vehicles> <vehicles>
<vehicle>
<id>v2</id>
<typeId>vehType2</typeId>
<startLocation>
<id>depotLoc</id>
<coord x="10.0" y="100.0"/>
</startLocation>
<endLocation>
<id>depotLoc</id>
<coord x="10.0" y="100.0"/>
</endLocation>
<timeSchedule>
<start>0.0</start>
<end>1000.0</end>
</timeSchedule>
<returnToDepot>false</returnToDepot>
</vehicle>
<vehicle> <vehicle>
<id>v3</id> <id>v3</id>
<typeId>vehType2</typeId> <typeId>vehType2</typeId>
@ -40,8 +23,25 @@
<returnToDepot>true</returnToDepot> <returnToDepot>true</returnToDepot>
</vehicle> </vehicle>
<vehicle> <vehicle>
<id>v5</id> <id>v2</id>
<typeId>vehType3</typeId> <typeId>vehType2</typeId>
<startLocation>
<id>depotLoc</id>
<coord x="10.0" y="100.0"/>
</startLocation>
<endLocation>
<id>depotLoc</id>
<coord x="10.0" y="100.0"/>
</endLocation>
<timeSchedule>
<start>0.0</start>
<end>1000.0</end>
</timeSchedule>
<returnToDepot>false</returnToDepot>
</vehicle>
<vehicle>
<id>v4</id>
<typeId>vehType2</typeId>
<startLocation> <startLocation>
<id>startLoc</id> <id>startLoc</id>
<coord x="10.0" y="100.0"/> <coord x="10.0" y="100.0"/>
@ -57,8 +57,8 @@
<returnToDepot>true</returnToDepot> <returnToDepot>true</returnToDepot>
</vehicle> </vehicle>
<vehicle> <vehicle>
<id>v4</id> <id>v5</id>
<typeId>vehType2</typeId> <typeId>vehType3</typeId>
<startLocation> <startLocation>
<id>startLoc</id> <id>startLoc</id>
<coord x="10.0" y="100.0"/> <coord x="10.0" y="100.0"/>
@ -137,20 +137,6 @@
</type> </type>
</vehicleTypes> </vehicleTypes>
<services> <services>
<service id="2" type="service">
<locationId>i(3,9)</locationId>
<coord x="10.0" y="10.0"/>
<capacity-dimensions>
<dimension index="0">1</dimension>
</capacity-dimensions>
<duration>0.0</duration>
<timeWindows>
<timeWindow>
<start>0.0</start>
<end>4000.0</end>
</timeWindow>
</timeWindows>
</service>
<service id="1" type="service"> <service id="1" type="service">
<locationId>j(1,5)</locationId> <locationId>j(1,5)</locationId>
<coord x="10.0" y="10.0"/> <coord x="10.0" y="10.0"/>
@ -165,6 +151,20 @@
</timeWindow> </timeWindow>
</timeWindows> </timeWindows>
</service> </service>
<service id="2" type="service">
<locationId>i(3,9)</locationId>
<coord x="10.0" y="10.0"/>
<capacity-dimensions>
<dimension index="0">1</dimension>
</capacity-dimensions>
<duration>0.0</duration>
<timeWindows>
<timeWindow>
<start>0.0</start>
<end>4000.0</end>
</timeWindow>
</timeWindows>
</service>
</services> </services>
<shipments> <shipments>
<shipment id="3"> <shipment id="3">

View file

@ -35,12 +35,12 @@
</type> </type>
</vehicleTypes> </vehicleTypes>
<services> <services>
<service id="2" type="service"> <service id="1" type="service">
<locationId>loc2</locationId> <locationId>loc</locationId>
<capacity-dimensions> <capacity-dimensions>
<dimension index="0">1</dimension> <dimension index="0">1</dimension>
</capacity-dimensions> </capacity-dimensions>
<duration>4.0</duration> <duration>2.0</duration>
<timeWindows> <timeWindows>
<timeWindow> <timeWindow>
<start>0.0</start> <start>0.0</start>
@ -48,12 +48,12 @@
</timeWindow> </timeWindow>
</timeWindows> </timeWindows>
</service> </service>
<service id="1" type="service"> <service id="2" type="service">
<locationId>loc</locationId> <locationId>loc2</locationId>
<capacity-dimensions> <capacity-dimensions>
<dimension index="0">1</dimension> <dimension index="0">1</dimension>
</capacity-dimensions> </capacity-dimensions>
<duration>2.0</duration> <duration>4.0</duration>
<timeWindows> <timeWindows>
<timeWindow> <timeWindow>
<start>0.0</start> <start>0.0</start>