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

add and test FastTransportCostMatrix based array

This commit is contained in:
oblonski 2014-12-17 22:20:01 +01:00
parent 0a196f0abd
commit 56f170e593
6 changed files with 231 additions and 21 deletions

View file

@ -114,4 +114,9 @@ public final class Location implements HasIndex, HasId{
result = 31 * result + (id != null ? id.hashCode() : 0); result = 31 * result + (id != null ? id.hashCode() : 0);
return result; return result;
} }
@Override
public String toString() {
return "[id="+id+"][index="+index+"][coordinate="+coordinate+"]";
}
} }

View file

@ -299,7 +299,7 @@ public class VehicleRoute {
} }
if(!vehicle.isReturnToDepot()){ if(!vehicle.isReturnToDepot()){
if(!tourActivities.isEmpty()){ if(!tourActivities.isEmpty()){
end.setLocationId(tourActivities.getActivities().get(tourActivities.getActivities().size()-1).getLocationId()); end.setLocation(tourActivities.getActivities().get(tourActivities.getActivities().size() - 1).getLocation());
} }
} }
return new VehicleRoute(this); return new VehicleRoute(this);
@ -407,8 +407,8 @@ public class VehicleRoute {
start.setEndTime(Math.max(vehicleDepTime, vehicle.getEarliestDeparture())); start.setEndTime(Math.max(vehicleDepTime, vehicle.getEarliestDeparture()));
start.setTheoreticalEarliestOperationStartTime(vehicle.getEarliestDeparture()); start.setTheoreticalEarliestOperationStartTime(vehicle.getEarliestDeparture());
start.setTheoreticalLatestOperationStartTime(vehicle.getLatestArrival()); start.setTheoreticalLatestOperationStartTime(vehicle.getLatestArrival());
start.setLocationId(vehicle.getStartLocationId()); start.setLocation(vehicle.getStartLocation());
end.setLocationId(vehicle.getEndLocationId()); end.setLocation(vehicle.getEndLocation());
end.setTheoreticalEarliestOperationStartTime(vehicle.getEarliestDeparture()); end.setTheoreticalEarliestOperationStartTime(vehicle.getEarliestDeparture());
end.setTheoreticalLatestOperationStartTime(vehicle.getLatestArrival()); end.setTheoreticalLatestOperationStartTime(vehicle.getLatestArrival());
} }

View file

@ -114,6 +114,7 @@ public class FastVehicleRoutingTransportCostsMatrix extends AbstractForwardVehic
@Override @Override
public double getTransportTime(Location from, Location to, double departureTime, Driver driver, Vehicle vehicle) { public double getTransportTime(Location from, Location to, double departureTime, Driver driver, Vehicle vehicle) {
if(from.getIndex() < 0 || to.getIndex() < 0) throw new IllegalArgumentException("index of from " + from + " to " + to + " < 0 ");
return get(from.getIndex(),to.getIndex(),1); return get(from.getIndex(),to.getIndex(),1);
} }
@ -142,7 +143,8 @@ public class FastVehicleRoutingTransportCostsMatrix extends AbstractForwardVehic
@Override @Override
public double getTransportCost(Location from, Location to, double departureTime, Driver driver, Vehicle vehicle) { public double getTransportCost(Location from, Location to, double departureTime, Driver driver, Vehicle vehicle) {
if(vehicle == null) return getDistance(from.getIndex(), to.getIndex()); if(from.getIndex() < 0 || to.getIndex() < 0) throw new IllegalArgumentException("index of from " + from + " to " + to + " < 0 ");
if(vehicle == null) return getDistance(from.getIndex(), to.getIndex());
VehicleCostParams costParams = vehicle.getType().getVehicleCostParams(); VehicleCostParams costParams = vehicle.getType().getVehicleCostParams();
return costParams.perDistanceUnit * getDistance(from.getIndex(), to.getIndex()) + costParams.perTimeUnit * getTransportTime(from, to, departureTime, driver, vehicle); return costParams.perDistanceUnit * getDistance(from.getIndex(), to.getIndex()) + costParams.perTimeUnit * getTransportTime(from, to, departureTime, driver, vehicle);
} }

View file

@ -20,6 +20,7 @@ import jsprit.core.algorithm.recreate.listener.InsertionListeners;
import jsprit.core.algorithm.state.UpdateEndLocationIfRouteIsOpen; import jsprit.core.algorithm.state.UpdateEndLocationIfRouteIsOpen;
import jsprit.core.problem.AbstractActivity; import jsprit.core.problem.AbstractActivity;
import jsprit.core.problem.Capacity; import jsprit.core.problem.Capacity;
import jsprit.core.problem.Location;
import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.driver.Driver; import jsprit.core.problem.driver.Driver;
import jsprit.core.problem.job.Service; import jsprit.core.problem.job.Service;
@ -48,15 +49,15 @@ public class TestInserter {
public void whenInsertingServiceAndRouteIsClosed_itInsertsCorrectly(){ public void whenInsertingServiceAndRouteIsClosed_itInsertsCorrectly(){
Service service = mock(Service.class); Service service = mock(Service.class);
Vehicle vehicle = mock(Vehicle.class); Vehicle vehicle = mock(Vehicle.class);
when(vehicle.getStartLocationId()).thenReturn("vehLoc"); when(vehicle.getStartLocation()).thenReturn(loc("vehLoc"));
when(vehicle.getEndLocationId()).thenReturn("vehLoc"); when(vehicle.getEndLocation()).thenReturn(loc("vehLoc"));
when(vehicle.isReturnToDepot()).thenReturn(true); when(vehicle.isReturnToDepot()).thenReturn(true);
when(vehicle.getId()).thenReturn("vehId"); when(vehicle.getId()).thenReturn("vehId");
VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addService(service).build(); VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addService(service).build();
//start - pick(shipment) - del(shipment) - end //start - pick(shipment) - del(shipment) - end
Service serviceToInsert = mock(Service.class); Service serviceToInsert = mock(Service.class);
when(serviceToInsert.getLocationId()).thenReturn("delLoc"); when(serviceToInsert.getLocation()).thenReturn(loc("delLoc"));
InsertionData iData = mock(InsertionData.class); InsertionData iData = mock(InsertionData.class);
when(iData.getDeliveryInsertionIndex()).thenReturn(1); when(iData.getDeliveryInsertionIndex()).thenReturn(1);
@ -71,11 +72,15 @@ public class TestInserter {
inserter.insertJob(serviceToInsert, iData, route); inserter.insertJob(serviceToInsert, iData, route);
assertEquals(2,route.getTourActivities().getActivities().size()); assertEquals(2,route.getTourActivities().getActivities().size());
assertEquals(route.getTourActivities().getActivities().get(1).getLocationId(),serviceToInsert.getLocationId()); assertEquals(route.getTourActivities().getActivities().get(1).getLocation().getId(),serviceToInsert.getLocation().getId());
assertEquals(route.getEnd().getLocationId(),vehicle.getEndLocationId()); assertEquals(route.getEnd().getLocation().getId(),vehicle.getEndLocation().getId());
} }
@Test private Location loc(String vehLoc) {
return Location.Builder.newInstance().setId(vehLoc).build();
}
@Test
public void whenInsertingServiceAndRouteIsOpen_itInsertsCorrectlyAndSwitchesEndLocation(){ public void whenInsertingServiceAndRouteIsOpen_itInsertsCorrectlyAndSwitchesEndLocation(){
Service service = mock(Service.class); Service service = mock(Service.class);
Vehicle vehicle = mock(Vehicle.class); Vehicle vehicle = mock(Vehicle.class);
@ -116,8 +121,8 @@ public class TestInserter {
Capacity capacity = Capacity.Builder.newInstance().build(); Capacity capacity = Capacity.Builder.newInstance().build();
when(shipment.getSize()).thenReturn(capacity); when(shipment.getSize()).thenReturn(capacity);
Vehicle vehicle = mock(Vehicle.class); Vehicle vehicle = mock(Vehicle.class);
when(vehicle.getStartLocationId()).thenReturn("vehLoc"); when(vehicle.getStartLocation()).thenReturn(loc("vehLoc"));
when(vehicle.getEndLocationId()).thenReturn("vehLoc"); when(vehicle.getEndLocation()).thenReturn(loc("vehLoc"));
when(vehicle.isReturnToDepot()).thenReturn(true); when(vehicle.isReturnToDepot()).thenReturn(true);
when(vehicle.getId()).thenReturn("vehId"); when(vehicle.getId()).thenReturn("vehId");
@ -136,9 +141,9 @@ public class TestInserter {
inserter.insertJob(shipmentToInsert, iData, route); inserter.insertJob(shipmentToInsert, iData, route);
assertEquals(4,route.getTourActivities().getActivities().size()); assertEquals(4,route.getTourActivities().getActivities().size());
assertEquals(route.getTourActivities().getActivities().get(2).getLocationId(),shipmentToInsert.getPickupLocationId()); assertEquals(route.getTourActivities().getActivities().get(2).getLocation().getId(),shipmentToInsert.getPickupLocation().getId());
assertEquals(route.getTourActivities().getActivities().get(3).getLocationId(),shipmentToInsert.getDeliveryLocationId()); assertEquals(route.getTourActivities().getActivities().get(3).getLocation().getId(),shipmentToInsert.getDeliveryLocation().getId());
assertEquals(route.getEnd().getLocationId(),vehicle.getEndLocationId()); assertEquals(route.getEnd().getLocation().getId(),vehicle.getEndLocation().getId());
} }
private List<AbstractActivity> getTourActivities(Shipment shipmentToInsert) { private List<AbstractActivity> getTourActivities(Shipment shipmentToInsert) {

View file

@ -17,6 +17,7 @@
package jsprit.core.problem.solution.route; package jsprit.core.problem.solution.route;
import jsprit.core.problem.Capacity; import jsprit.core.problem.Capacity;
import jsprit.core.problem.Location;
import jsprit.core.problem.driver.Driver; import jsprit.core.problem.driver.Driver;
import jsprit.core.problem.job.Shipment; import jsprit.core.problem.job.Shipment;
import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.Vehicle;
@ -113,20 +114,24 @@ public class VehicleRouteBuilderTest {
Capacity capacity = Capacity.Builder.newInstance().build(); Capacity capacity = Capacity.Builder.newInstance().build();
when(s.getSize()).thenReturn(capacity); when(s.getSize()).thenReturn(capacity);
when(s2.getSize()).thenReturn(capacity); when(s2.getSize()).thenReturn(capacity);
when(s2.getDeliveryLocationId()).thenReturn("delLoc"); when(s2.getDeliveryLocation()).thenReturn(loc("delLoc"));
Vehicle vehicle = mock(Vehicle.class); Vehicle vehicle = mock(Vehicle.class);
when(vehicle.isReturnToDepot()).thenReturn(false); when(vehicle.isReturnToDepot()).thenReturn(false);
when(vehicle.getStartLocationId()).thenReturn("vehLoc"); when(vehicle.getStartLocation()).thenReturn(loc("vehLoc"));
VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)); VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class));
builder.addPickup(s); builder.addPickup(s);
builder.addPickup(s2); builder.addPickup(s2);
builder.addDelivery(s); builder.addDelivery(s);
builder.addDelivery(s2); builder.addDelivery(s2);
VehicleRoute route = builder.build(); VehicleRoute route = builder.build();
assertEquals(route.getEnd().getLocationId(), s2.getDeliveryLocationId()); assertEquals(route.getEnd().getLocationId(), s2.getDeliveryLocation().getId());
} }
@Test private Location loc(String delLoc) {
return Location.Builder.newInstance().setId(delLoc).build();
}
@Test
public void whenSettingDepartureTime(){ public void whenSettingDepartureTime(){
Shipment s = mock(Shipment.class); Shipment s = mock(Shipment.class);
Shipment s2 = mock(Shipment.class); Shipment s2 = mock(Shipment.class);

View file

@ -0,0 +1,193 @@
/*******************************************************************************
* Copyright (C) 2014 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.examples;
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
import jsprit.core.algorithm.box.GreedySchrimpfFactory;
import jsprit.core.algorithm.termination.IterationWithoutImprovementTermination;
import jsprit.core.problem.Location;
import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.VehicleRoutingProblem.FleetSize;
import jsprit.core.problem.io.VrpXMLWriter;
import jsprit.core.problem.job.Service;
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import jsprit.core.problem.vehicle.VehicleImpl;
import jsprit.core.problem.vehicle.VehicleTypeImpl;
import jsprit.core.reporting.SolutionPrinter;
import jsprit.core.util.FastVehicleRoutingTransportCostsMatrix;
import jsprit.core.util.Solutions;
import jsprit.util.Examples;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collection;
/**
* This example is base on
* http://web.mit.edu/urban_or_book/www/book/chapter6/6.4.12.html
*
* @author stefan schroeder
*
*/
public class RefuseCollectionWithFastMatrixExample {
static class RelationKey {
final String from;
final String to;
public RelationKey(String from, String to) {
super();
this.from = from;
this.to = to;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((from == null) ? 0 : from.hashCode());
result = prime * result + ((to == null) ? 0 : to.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RelationKey other = (RelationKey) obj;
if (from == null) {
if (other.from != null)
return false;
} else if (!from.equals(other.from))
return false;
if (to == null) {
if (other.to != null)
return false;
} else if (!to.equals(other.to))
return false;
return true;
}
}
public static void main(String[] args) throws IOException {
/*
* some preparation - create output folder
*/
Examples.createOutputFolder();
/*
* create vehicle-type and vehicle
*/
VehicleTypeImpl.Builder typeBuilder = VehicleTypeImpl.Builder.newInstance("vehicle-type").addCapacityDimension(0, 23);
typeBuilder.setCostPerDistance(1.0);
VehicleTypeImpl bigType = typeBuilder.build();
VehicleImpl.Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle");
vehicleBuilder.setStartLocation(Location.Builder.newInstance().setIndex(1).build());
vehicleBuilder.setType(bigType);
VehicleImpl bigVehicle = vehicleBuilder.build();
/*
* start building the problem
*/
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
vrpBuilder.setFleetSize(FleetSize.INFINITE);
vrpBuilder.addVehicle(bigVehicle);
/*
* read demand quantities
*/
readDemandQuantities(vrpBuilder);
/*
* create cost-matrix
*/
FastVehicleRoutingTransportCostsMatrix.Builder matrixBuilder = FastVehicleRoutingTransportCostsMatrix.Builder.newInstance(11,true);
readDistances(matrixBuilder);
vrpBuilder.setRoutingCost(matrixBuilder.build());
VehicleRoutingProblem vrp = vrpBuilder.build();
VehicleRoutingAlgorithm vra = new GreedySchrimpfFactory().createAlgorithm(vrp);
vra.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(100));
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
SolutionPrinter.print(Solutions.bestOf(solutions));
new VrpXMLWriter(vrp, solutions).write("output/refuseCollectionExampleSolution.xml");
}
private static void readDemandQuantities(VehicleRoutingProblem.Builder vrpBuilder) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(new File("input/RefuseCollectionExample_Quantities")));
String line;
boolean firstLine = true;
while((line = reader.readLine()) != null){
if(firstLine) {
firstLine = false;
continue;
}
String[] lineTokens = line.split(",");
/*
* build service
*/
Service service = Service.Builder.newInstance(lineTokens[0])
.addSizeDimension(0, Integer.parseInt(lineTokens[1]))
.setLocation(Location.Builder.newInstance().setIndex(Integer.parseInt(lineTokens[0])).build())
.build();
/*
* and add it to problem
*/
vrpBuilder.addJob(service);
}
reader.close();
}
private static void readDistances(FastVehicleRoutingTransportCostsMatrix.Builder matrixBuilder) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(new File("input/RefuseCollectionExample_Distances")));
String line;
boolean firstLine = true;
while((line = reader.readLine()) != null){
if(firstLine) {
firstLine = false;
continue;
}
String[] lineTokens = line.split(",");
matrixBuilder.addTransportDistance(Integer.parseInt(lineTokens[0]),Integer.parseInt(lineTokens[1]), Integer.parseInt(lineTokens[2]));
}
reader.close();
}
}