mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
adjusted algorithm.recreate.JobInsertionConsideringFixCostsCalculator to
deal with multiple capacities
This commit is contained in:
parent
24f044993c
commit
0e42ac31b8
4 changed files with 92 additions and 9 deletions
|
|
@ -17,6 +17,7 @@
|
||||||
package jsprit.core.algorithm.recreate;
|
package jsprit.core.algorithm.recreate;
|
||||||
|
|
||||||
import jsprit.core.algorithm.recreate.InsertionData.NoInsertionFound;
|
import jsprit.core.algorithm.recreate.InsertionData.NoInsertionFound;
|
||||||
|
import jsprit.core.problem.Capacity;
|
||||||
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;
|
||||||
|
|
@ -83,37 +84,40 @@ final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCos
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getDeltaAbsoluteFixCost(VehicleRoute route, Vehicle newVehicle, Job job) {
|
private double getDeltaAbsoluteFixCost(VehicleRoute route, Vehicle newVehicle, Job job) {
|
||||||
double load = getCurrentMaxLoadInRoute(route) + job.getCapacityDemand();
|
Capacity load = Capacity.addup(getCurrentMaxLoadInRoute(route), job.getSize());
|
||||||
|
// double load = getCurrentMaxLoadInRoute(route) + job.getCapacityDemand();
|
||||||
double currentFix = 0.0;
|
double currentFix = 0.0;
|
||||||
if(route.getVehicle() != null){
|
if(route.getVehicle() != null){
|
||||||
if(!(route.getVehicle() instanceof NoVehicle)){
|
if(!(route.getVehicle() instanceof NoVehicle)){
|
||||||
currentFix += route.getVehicle().getType().getVehicleCostParams().fix;
|
currentFix += route.getVehicle().getType().getVehicleCostParams().fix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(newVehicle.getCapacity() < load){
|
if(!newVehicle.getType().getCapacityDimensions().isGreaterOrEqual(load)){
|
||||||
return Double.MAX_VALUE;
|
return Double.MAX_VALUE;
|
||||||
}
|
}
|
||||||
return newVehicle.getType().getVehicleCostParams().fix - currentFix;
|
return newVehicle.getType().getVehicleCostParams().fix - currentFix;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getDeltaRelativeFixCost(VehicleRoute route, Vehicle newVehicle, Job job) {
|
private double getDeltaRelativeFixCost(VehicleRoute route, Vehicle newVehicle, Job job) {
|
||||||
int currentLoad = getCurrentMaxLoadInRoute(route);
|
Capacity currentLoad = getCurrentMaxLoadInRoute(route);
|
||||||
double load = currentLoad + job.getCapacityDemand();
|
// int currentLoad = getCurrentMaxLoadInRoute(route);
|
||||||
|
Capacity load = Capacity.addup(currentLoad, job.getSize());
|
||||||
|
// double load = currentLoad + job.getCapacityDemand();
|
||||||
double currentRelFix = 0.0;
|
double currentRelFix = 0.0;
|
||||||
if(route.getVehicle() != null){
|
if(route.getVehicle() != null){
|
||||||
if(!(route.getVehicle() instanceof NoVehicle)){
|
if(!(route.getVehicle() instanceof NoVehicle)){
|
||||||
currentRelFix += route.getVehicle().getType().getVehicleCostParams().fix*currentLoad/route.getVehicle().getCapacity();
|
currentRelFix += route.getVehicle().getType().getVehicleCostParams().fix * Capacity.divide(currentLoad, route.getVehicle().getType().getCapacityDimensions());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(newVehicle.getCapacity() < load){
|
if(!newVehicle.getType().getCapacityDimensions().isGreaterOrEqual(load)){
|
||||||
return Double.MAX_VALUE;
|
return Double.MAX_VALUE;
|
||||||
}
|
}
|
||||||
double relativeFixCost = newVehicle.getType().getVehicleCostParams().fix*(load/newVehicle.getCapacity()) - currentRelFix;
|
double relativeFixCost = newVehicle.getType().getVehicleCostParams().fix* (Capacity.divide(load, newVehicle.getType().getCapacityDimensions())) - currentRelFix;
|
||||||
return relativeFixCost;
|
return relativeFixCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getCurrentMaxLoadInRoute(VehicleRoute route) {
|
private Capacity getCurrentMaxLoadInRoute(VehicleRoute route) {
|
||||||
return (int) stateGetter.getRouteState(route, StateFactory.MAXLOAD).toDouble();
|
return stateGetter.getRouteState(route, StateFactory.MAXLOAD, Capacity.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,36 @@ public class Capacity {
|
||||||
return capacityBuilder.build();
|
return capacityBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divides every dimension of numerator capacity by the corresponding dimension of denominator capacity,
|
||||||
|
* , and averages each quotient.
|
||||||
|
*
|
||||||
|
* <p>If both nominator.get(i) and denominator.get(i) equal to 0, dimension i is ignored.
|
||||||
|
* <p>If both capacities are have only dimensions with dimensionVal=0, it returns 0.0
|
||||||
|
* @param numerator
|
||||||
|
* @param denominator
|
||||||
|
* @return
|
||||||
|
* @throws IllegalStateException if numerator.get(i) != 0 and denominator.get(i) == 0
|
||||||
|
*/
|
||||||
|
public static double divide(Capacity numerator, Capacity denominator){
|
||||||
|
int nuOfDimensions = 0;
|
||||||
|
double sumQuotients = 0.0;
|
||||||
|
for(int index=0;index<Math.max(numerator.getNuOfDimensions(), denominator.getNuOfDimensions());index++){
|
||||||
|
if(numerator.get(index) != 0 && denominator.get(index) == 0){
|
||||||
|
throw new IllegalStateException("numerator > 0 and denominator = 0. cannot divide by 0");
|
||||||
|
}
|
||||||
|
else if(numerator.get(index) == 0 && denominator.get(index) == 0){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
nuOfDimensions++;
|
||||||
|
sumQuotients += (double)numerator.get(index)/(double)denominator.get(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(nuOfDimensions > 0) return sumQuotients/(double)nuOfDimensions;
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a deep copy of Capacity.
|
* Makes a deep copy of Capacity.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package jsprit.core.algorithm.recreate;
|
||||||
|
|
||||||
|
public class JobInsertionConsideringFixCostsCalculatorTest {
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
// public void
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -314,4 +314,45 @@ public class CapacityTest {
|
||||||
assertEquals(3,Capacity.max(cap1,cap2).get(2));
|
assertEquals(3,Capacity.max(cap1,cap2).get(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDividingTwoCapacities_itShouldReturn05(){
|
||||||
|
Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).build();
|
||||||
|
Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 4).build();
|
||||||
|
assertEquals(0.5,Capacity.divide(cap1, cap2),0.001);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDividingTwoEqualCapacities_itShouldReturn10(){
|
||||||
|
Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 4).build();
|
||||||
|
Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 4).build();
|
||||||
|
assertEquals(1.0,Capacity.divide(cap1, cap2),0.001);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDividingTwoCapacities_itShouldReturn00(){
|
||||||
|
Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 0).addDimension(1, 0).build();
|
||||||
|
Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 4).build();
|
||||||
|
assertEquals(0.0,Capacity.divide(cap1, cap2),0.001);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=IllegalStateException.class)
|
||||||
|
public void whenDividingByAZeroDim_itShouldThrowException(){
|
||||||
|
Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).build();
|
||||||
|
Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 0).build();
|
||||||
|
Capacity.divide(cap1, cap2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenBothDimOfNominatorAndDenominatorAreZero_divisionShouldIgnoreThisDim(){
|
||||||
|
Capacity cap1 = Capacity.Builder.newInstance().addDimension(0, 1).addDimension(1, 2).addDimension(3, 0).build();
|
||||||
|
Capacity cap2 = Capacity.Builder.newInstance().addDimension(0, 2).addDimension(1, 4).addDimension(3, 0).build();
|
||||||
|
assertEquals(0.5,Capacity.divide(cap1, cap2),0.001);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDividingZeroCaps_itShouldReturnZero(){
|
||||||
|
Capacity cap1 = Capacity.Builder.newInstance().build();
|
||||||
|
Capacity cap2 = Capacity.Builder.newInstance().build();
|
||||||
|
assertEquals(0.0,Capacity.divide(cap1, cap2),0.001);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue