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:
parent
7ea5c5d650
commit
0a196f0abd
2 changed files with 249 additions and 0 deletions
|
|
@ -0,0 +1,150 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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.core.util;
|
||||||
|
|
||||||
|
import jsprit.core.problem.Location;
|
||||||
|
import jsprit.core.problem.cost.AbstractForwardVehicleRoutingTransportCosts;
|
||||||
|
import jsprit.core.problem.driver.Driver;
|
||||||
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
|
import jsprit.core.problem.vehicle.VehicleTypeImpl.VehicleCostParams;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CostMatrix that allows pre-compiled time and distance-matrices to be considered as {@link jsprit.core.problem.cost.VehicleRoutingTransportCosts}
|
||||||
|
* in the {@link jsprit.core.problem.VehicleRoutingProblem}.
|
||||||
|
* <p>Note that you can also use it with distance matrix only (or time matrix).
|
||||||
|
* @author schroeder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FastVehicleRoutingTransportCostsMatrix extends AbstractForwardVehicleRoutingTransportCosts {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder that builds the matrix.
|
||||||
|
*
|
||||||
|
* @author schroeder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
private boolean isSymmetric;
|
||||||
|
|
||||||
|
private double[][][] matrix;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new builder returning the matrix-builder.
|
||||||
|
* <p>If you want to consider symmetric matrices, set isSymmetric to true.
|
||||||
|
* @param isSymmetric true if matrix is symmetric, false otherwise
|
||||||
|
* @return builder
|
||||||
|
*/
|
||||||
|
public static Builder newInstance(int noLocations, boolean isSymmetric){
|
||||||
|
return new Builder(noLocations, isSymmetric);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder(int noLocations, boolean isSymmetric){
|
||||||
|
this.isSymmetric = isSymmetric;
|
||||||
|
matrix = new double[noLocations][noLocations][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a transport-distance for a particular relation.
|
||||||
|
* @param fromIndex from location index
|
||||||
|
* @param toIndex to location index
|
||||||
|
* @param distance the distance to be added
|
||||||
|
* @return builder
|
||||||
|
*/
|
||||||
|
public Builder addTransportDistance(int fromIndex, int toIndex, double distance){
|
||||||
|
add(fromIndex,toIndex,0,distance);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void add(int fromIndex, int toIndex, int indicatorIndex, double distance){
|
||||||
|
if(isSymmetric){
|
||||||
|
if(fromIndex < toIndex) matrix[fromIndex][toIndex][indicatorIndex] = distance;
|
||||||
|
else matrix[toIndex][fromIndex][indicatorIndex] = distance;
|
||||||
|
}
|
||||||
|
else matrix[fromIndex][toIndex][indicatorIndex] = distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds transport-time for a particular relation.
|
||||||
|
* @param fromIndex from location index
|
||||||
|
* @param toIndex to location index
|
||||||
|
* @param time the time to be added
|
||||||
|
* @return builder
|
||||||
|
*/
|
||||||
|
public Builder addTransportTime(int fromIndex, int toIndex, double time){
|
||||||
|
add(fromIndex,toIndex,1,time);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the matrix.
|
||||||
|
* @return matrix
|
||||||
|
*/
|
||||||
|
public FastVehicleRoutingTransportCostsMatrix build(){
|
||||||
|
return new FastVehicleRoutingTransportCostsMatrix(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final boolean isSymmetric;
|
||||||
|
|
||||||
|
private final double[][][] matrix;
|
||||||
|
|
||||||
|
private FastVehicleRoutingTransportCostsMatrix(Builder builder){
|
||||||
|
this.isSymmetric = builder.isSymmetric;
|
||||||
|
matrix = builder.matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getTransportTime(Location from, Location to, double departureTime, Driver driver, Vehicle vehicle) {
|
||||||
|
return get(from.getIndex(),to.getIndex(),1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double get(int from, int to, int indicatorIndex){
|
||||||
|
double value;
|
||||||
|
if(isSymmetric){
|
||||||
|
if(from < to) value = matrix[from][to][indicatorIndex];
|
||||||
|
else value = matrix[to][from][indicatorIndex];
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
value = matrix[from][to][indicatorIndex];
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the distance from to to.
|
||||||
|
*
|
||||||
|
* @param fromIndex from location index
|
||||||
|
* @param toIndex to location index
|
||||||
|
* @return the distance
|
||||||
|
*/
|
||||||
|
public double getDistance(int fromIndex, int toIndex) {
|
||||||
|
return get(fromIndex,toIndex,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getTransportCost(Location from, Location to, double departureTime, Driver driver, Vehicle vehicle) {
|
||||||
|
if(vehicle == null) return getDistance(from.getIndex(), to.getIndex());
|
||||||
|
VehicleCostParams costParams = vehicle.getType().getVehicleCostParams();
|
||||||
|
return costParams.perDistanceUnit * getDistance(from.getIndex(), to.getIndex()) + costParams.perTimeUnit * getTransportTime(from, to, departureTime, driver, vehicle);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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.core.util;
|
||||||
|
|
||||||
|
import jsprit.core.problem.Location;
|
||||||
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
|
import jsprit.core.problem.vehicle.VehicleType;
|
||||||
|
import jsprit.core.problem.vehicle.VehicleTypeImpl;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class FastVehicleRoutingTransportCostsMatrixTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddingDistanceToSymmetricMatrix_itShouldReturnCorrectValues(){
|
||||||
|
FastVehicleRoutingTransportCostsMatrix.Builder matrixBuilder = FastVehicleRoutingTransportCostsMatrix.Builder.newInstance(3,true);
|
||||||
|
matrixBuilder.addTransportDistance(1, 2, 2.);
|
||||||
|
FastVehicleRoutingTransportCostsMatrix matrix = matrixBuilder.build();
|
||||||
|
assertEquals(2.,matrix.getTransportCost(loc(1), loc(2), 0.0, null, null),0.1);
|
||||||
|
assertEquals(2.,matrix.getDistance(1, 2),0.1);
|
||||||
|
assertEquals(2.,matrix.getTransportCost(loc(2), loc(1), 0.0, null, null),0.1);
|
||||||
|
assertEquals(2.,matrix.getDistance(2, 1),0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddingDistanceToAsymmetricMatrix_itShouldReturnCorrectValues(){
|
||||||
|
FastVehicleRoutingTransportCostsMatrix.Builder matrixBuilder = FastVehicleRoutingTransportCostsMatrix.Builder.newInstance(3,false);
|
||||||
|
matrixBuilder.addTransportDistance(1, 2, 2.);
|
||||||
|
FastVehicleRoutingTransportCostsMatrix matrix = matrixBuilder.build();
|
||||||
|
assertEquals(2.,matrix.getTransportCost(loc(1), loc(2), 0.0, null, null),0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Location loc(int index) {
|
||||||
|
return Location.Builder.newInstance().setIndex(index).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddingTimeToSymmetricMatrix_itShouldReturnCorrectValues(){
|
||||||
|
FastVehicleRoutingTransportCostsMatrix.Builder matrixBuilder = FastVehicleRoutingTransportCostsMatrix.Builder.newInstance(3,true);
|
||||||
|
matrixBuilder.addTransportTime(1, 2, 2.);
|
||||||
|
FastVehicleRoutingTransportCostsMatrix matrix = matrixBuilder.build();
|
||||||
|
assertEquals(2.,matrix.getTransportTime(loc(1), loc(2), 0.0, null, null),0.1);
|
||||||
|
assertEquals(2.,matrix.getTransportTime(loc(2), loc(1), 0.0, null, null),0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddingTimeToAsymmetricMatrix_itShouldReturnCorrectValues(){
|
||||||
|
FastVehicleRoutingTransportCostsMatrix.Builder matrixBuilder = FastVehicleRoutingTransportCostsMatrix.Builder.newInstance(3,false);
|
||||||
|
matrixBuilder.addTransportTime(1, 2, 2.);
|
||||||
|
FastVehicleRoutingTransportCostsMatrix matrix = matrixBuilder.build();
|
||||||
|
assertEquals(2.,matrix.getTransportTime(loc(1), loc(2), 0.0, null, null),0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddingTimeAndDistanceToSymmetricMatrix_itShouldReturnCorrectValues(){
|
||||||
|
FastVehicleRoutingTransportCostsMatrix.Builder matrixBuilder = FastVehicleRoutingTransportCostsMatrix.Builder.newInstance(3,true);
|
||||||
|
matrixBuilder.addTransportDistance(1, 2, 20.);
|
||||||
|
matrixBuilder.addTransportTime(1, 2, 2.);
|
||||||
|
FastVehicleRoutingTransportCostsMatrix matrix = matrixBuilder.build();
|
||||||
|
Vehicle vehicle = mock(Vehicle.class);
|
||||||
|
VehicleType type = VehicleTypeImpl.Builder.newInstance("t").setCostPerDistance(1.).setCostPerTime(2.).build();
|
||||||
|
when(vehicle.getType()).thenReturn(type);
|
||||||
|
assertEquals(24.,matrix.getTransportCost(loc(1), loc(2), 0.0, null, vehicle),0.1);
|
||||||
|
assertEquals(24.,matrix.getTransportCost(loc(2), loc(1), 0.0, null, vehicle),0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddingTimeAndDistanceToAsymmetricMatrix_itShouldReturnCorrectValues(){
|
||||||
|
FastVehicleRoutingTransportCostsMatrix.Builder matrixBuilder = FastVehicleRoutingTransportCostsMatrix.Builder.newInstance(3,false);
|
||||||
|
matrixBuilder.addTransportTime(1, 2, 2.);
|
||||||
|
matrixBuilder.addTransportTime(2, 1, 8.);
|
||||||
|
FastVehicleRoutingTransportCostsMatrix matrix = matrixBuilder.build();
|
||||||
|
Vehicle vehicle = mock(Vehicle.class);
|
||||||
|
VehicleType type = VehicleTypeImpl.Builder.newInstance("t").setCostPerDistance(1.).setCostPerTime(2.).build();
|
||||||
|
when(vehicle.getType()).thenReturn(type);
|
||||||
|
assertEquals(4.,matrix.getTransportCost(loc(1), loc(2), 0.0, null, vehicle),0.1);
|
||||||
|
assertEquals(16.,matrix.getTransportCost(loc(2), loc(1), 0.0, null, vehicle),0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue