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

split fix cost calculation - related to #286

This commit is contained in:
oblonski 2017-01-11 20:08:31 +01:00
parent f924293520
commit 0becec2ce8
No known key found for this signature in database
GPG key ID: 179DE487285680D1
9 changed files with 402 additions and 338 deletions

View file

@ -368,6 +368,14 @@ public class Jsprit {
}
}
double fixedCostParam = toDouble(getProperty(Parameter.FIXED_COST_PARAM.toString()));
IncreasingAbsoluteFixedCosts increasingAbsoluteFixedCosts = null;
if (fixedCostParam > 0d) {
increasingAbsoluteFixedCosts = new IncreasingAbsoluteFixedCosts(vrp.getJobs().size());
increasingAbsoluteFixedCosts.setWeightOfFixCost(fixedCostParam);
constraintManager.addConstraint(increasingAbsoluteFixedCosts);
}
double noiseLevel = toDouble(getProperty(Parameter.INSERTION_NOISE_LEVEL.toString()));
double noiseProbability = toDouble(getProperty(Parameter.INSERTION_NOISE_PROB.toString()));
@ -598,6 +606,7 @@ public class Jsprit {
vra.addListener(noiseConfigurator);
vra.addListener(noise);
vra.addListener(clusters);
if (increasingAbsoluteFixedCosts != null) vra.addListener(increasingAbsoluteFixedCosts);
if(toBoolean(getProperty(Parameter.BREAK_SCHEDULING.toString()))) {
vra.addListener(new BreakScheduling(vrp, stateManager, constraintManager));

View file

@ -0,0 +1,77 @@
/*
* Licensed to GraphHopper GmbH under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*
* GraphHopper GmbH licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.graphhopper.jsprit.core.algorithm.recreate;
import com.graphhopper.jsprit.core.algorithm.state.InternalStates;
import com.graphhopper.jsprit.core.problem.Capacity;
import com.graphhopper.jsprit.core.problem.constraint.SoftRouteConstraint;
import com.graphhopper.jsprit.core.problem.misc.JobInsertionContext;
import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute;
import com.graphhopper.jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter;
import com.graphhopper.jsprit.core.problem.vehicle.VehicleImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class DecreasingRelativeFixedCosts extends SolutionCompletenessRatio implements SoftRouteConstraint {
private static final Logger logger = LoggerFactory.getLogger(DecreasingRelativeFixedCosts.class);
private double weightDeltaFixCost = 0.5;
private RouteAndActivityStateGetter stateGetter;
public DecreasingRelativeFixedCosts(RouteAndActivityStateGetter stateGetter, int noJobs) {
super(noJobs);
this.stateGetter = stateGetter;
logger.debug("initialise {}", this);
}
public void setWeightOfFixCost(double weight) {
weightDeltaFixCost = weight;
logger.debug("set weightOfFixCostSaving to {}", weight);
}
@Override
public String toString() {
return "[name=calculatesServiceInsertionConsideringFixCost][weightOfFixedCostSavings=" + weightDeltaFixCost + "]";
}
private Capacity getCurrentMaxLoadInRoute(VehicleRoute route) {
Capacity maxLoad = stateGetter.getRouteState(route, InternalStates.MAXLOAD, Capacity.class);
if (maxLoad == null) maxLoad = Capacity.Builder.newInstance().build();
return maxLoad;
}
@Override
public double getCosts(JobInsertionContext insertionContext) {
VehicleRoute route = insertionContext.getRoute();
Capacity currentLoad = getCurrentMaxLoadInRoute(route);
Capacity load = Capacity.addup(currentLoad, insertionContext.getJob().getSize());
double currentRelFix = 0d;
if (route.getVehicle() != null && !(route.getVehicle() instanceof VehicleImpl.NoVehicle)) {
currentRelFix = route.getVehicle().getType().getVehicleCostParams().fix * Capacity.divide(currentLoad, route.getVehicle().getType().getCapacityDimensions());
}
double newRelFix = insertionContext.getNewVehicle().getType().getVehicleCostParams().fix * (Capacity.divide(load, insertionContext.getNewVehicle().getType().getCapacityDimensions()));
double decreasingRelativeFixedCosts = (1 - solutionCompletenessRatio) * (newRelFix - currentRelFix);
return weightDeltaFixCost * solutionCompletenessRatio * decreasingRelativeFixedCosts;
}
}

View file

@ -31,14 +31,14 @@ public class DellAmicoFixCostCalculator implements SoftRouteConstraint, Insertio
private int nuOfJobsToRecreate;
private final JobInsertionConsideringFixCostsCalculator calculator;
private final IncreasingAbsoluteFixedCosts calculator;
private final int nuOfJobs;
public DellAmicoFixCostCalculator(final int nuOfJobs, final RouteAndActivityStateGetter stateGetter) {
super();
this.nuOfJobs = nuOfJobs;
calculator = new JobInsertionConsideringFixCostsCalculator(null, stateGetter);
calculator = new IncreasingAbsoluteFixedCosts(nuOfJobs);
}
@Override

View file

@ -0,0 +1,61 @@
/*
* Licensed to GraphHopper GmbH under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*
* GraphHopper GmbH licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.graphhopper.jsprit.core.algorithm.recreate;
import com.graphhopper.jsprit.core.problem.constraint.SoftRouteConstraint;
import com.graphhopper.jsprit.core.problem.misc.JobInsertionContext;
import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute;
import com.graphhopper.jsprit.core.problem.vehicle.VehicleImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class IncreasingAbsoluteFixedCosts extends SolutionCompletenessRatio implements SoftRouteConstraint {
private static final Logger logger = LoggerFactory.getLogger(IncreasingAbsoluteFixedCosts.class);
private double weightDeltaFixCost = 0.5;
public IncreasingAbsoluteFixedCosts(int noJobs) {
super(noJobs);
logger.debug("initialise {}", this);
}
public void setWeightOfFixCost(double weight) {
weightDeltaFixCost = weight;
logger.debug("set weightOfFixCostSaving to {}", weight);
}
@Override
public String toString() {
return "[name=calculatesServiceInsertionConsideringFixCost][weightOfFixedCostSavings=" + weightDeltaFixCost + "]";
}
@Override
public double getCosts(JobInsertionContext insertionContext) {
final VehicleRoute currentRoute = insertionContext.getRoute();
double currentFix = 0d;
if (currentRoute.getVehicle() != null && !(currentRoute.getVehicle() instanceof VehicleImpl.NoVehicle)) {
currentFix = currentRoute.getVehicle().getType().getVehicleCostParams().fix;
}
double increasingAbsoluteFixedCosts = solutionCompletenessRatio * (insertionContext.getNewVehicle().getType().getVehicleCostParams().fix - currentFix);
return weightDeltaFixCost * solutionCompletenessRatio * increasingAbsoluteFixedCosts;
}
}

View file

@ -1,122 +0,0 @@
/*
* Licensed to GraphHopper GmbH under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*
* GraphHopper GmbH licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.graphhopper.jsprit.core.algorithm.recreate;
import com.graphhopper.jsprit.core.algorithm.state.InternalStates;
import com.graphhopper.jsprit.core.problem.Capacity;
import com.graphhopper.jsprit.core.problem.constraint.SoftRouteConstraint;
import com.graphhopper.jsprit.core.problem.driver.Driver;
import com.graphhopper.jsprit.core.problem.job.Job;
import com.graphhopper.jsprit.core.problem.misc.JobInsertionContext;
import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute;
import com.graphhopper.jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter;
import com.graphhopper.jsprit.core.problem.vehicle.Vehicle;
import com.graphhopper.jsprit.core.problem.vehicle.VehicleImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final class JobInsertionConsideringFixCostsCalculator implements JobInsertionCostsCalculator, SoftRouteConstraint {
private static final Logger logger = LoggerFactory.getLogger(JobInsertionConsideringFixCostsCalculator.class);
private final JobInsertionCostsCalculator standardInsertion;
private double weightDeltaFixCost = 0.5;
private double solutionCompletenessRatio = 0.5;
private RouteAndActivityStateGetter stateGetter;
public JobInsertionConsideringFixCostsCalculator(final JobInsertionCostsCalculator standardCalculator, RouteAndActivityStateGetter stateGetter) {
super();
this.standardInsertion = standardCalculator;
this.stateGetter = stateGetter;
logger.debug("initialise {}", this);
}
@Override
public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownPrice) {
double fixedCostContribution = getFixCostContribution(currentRoute, jobToInsert, newVehicle);
if (fixedCostContribution > bestKnownPrice) {
return InsertionData.createEmptyInsertionData();
}
InsertionData iData = standardInsertion.getInsertionData(currentRoute, jobToInsert, newVehicle, newVehicleDepartureTime, newDriver, bestKnownPrice);
if (iData instanceof InsertionData.NoInsertionFound) {
return iData;
}
double totalInsertionCost = iData.getInsertionCost() + fixedCostContribution;
InsertionData insertionData = new InsertionData(totalInsertionCost, iData.getPickupInsertionIndex(), iData.getDeliveryInsertionIndex(), newVehicle, newDriver);
insertionData.setVehicleDepartureTime(newVehicleDepartureTime);
insertionData.getEvents().addAll(iData.getEvents());
return insertionData;
}
private double getFixCostContribution(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle) {
Capacity currentMaxLoadInRoute = getCurrentMaxLoadInRoute(currentRoute);
double relFixCost = getDeltaRelativeFixCost(currentRoute, newVehicle, jobToInsert,currentMaxLoadInRoute);
double absFixCost = getDeltaAbsoluteFixCost(currentRoute, newVehicle);
double deltaFixCost = (1 - solutionCompletenessRatio) * relFixCost + solutionCompletenessRatio * absFixCost;
return weightDeltaFixCost * solutionCompletenessRatio * deltaFixCost;
}
public void setWeightOfFixCost(double weight) {
weightDeltaFixCost = weight;
logger.debug("set weightOfFixCostSaving to {}", weight);
}
@Override
public String toString() {
return "[name=calculatesServiceInsertionConsideringFixCost][weightOfFixedCostSavings=" + weightDeltaFixCost + "]";
}
public void setSolutionCompletenessRatio(double ratio) {
solutionCompletenessRatio = ratio;
}
public double getSolutionCompletenessRatio() { return solutionCompletenessRatio; }
private double getDeltaAbsoluteFixCost(VehicleRoute route, Vehicle newVehicle) {
double currentFix = 0d;
if (route.getVehicle() != null && !(route.getVehicle() instanceof VehicleImpl.NoVehicle)) {
currentFix = route.getVehicle().getType().getVehicleCostParams().fix;
}
return newVehicle.getType().getVehicleCostParams().fix - currentFix;
}
private double getDeltaRelativeFixCost(VehicleRoute route, Vehicle newVehicle, Job job, Capacity currentLoad) {
Capacity load = Capacity.addup(currentLoad, job.getSize());
double currentRelFix = 0d;
if (route.getVehicle() != null && !(route.getVehicle() instanceof VehicleImpl.NoVehicle)) {
currentRelFix = route.getVehicle().getType().getVehicleCostParams().fix * Capacity.divide(currentLoad, route.getVehicle().getType().getCapacityDimensions());
}
return newVehicle.getType().getVehicleCostParams().fix * (Capacity.divide(load, newVehicle.getType().getCapacityDimensions())) - currentRelFix;
}
private Capacity getCurrentMaxLoadInRoute(VehicleRoute route) {
Capacity maxLoad = stateGetter.getRouteState(route, InternalStates.MAXLOAD, Capacity.class);
if (maxLoad == null) maxLoad = Capacity.Builder.newInstance().build();
return maxLoad;
}
@Override
public double getCosts(JobInsertionContext insertionContext) {
return getFixCostContribution(insertionContext.getRoute(), insertionContext.getJob(), insertionContext.getNewVehicle());
}
}

View file

@ -218,10 +218,10 @@ public class JobInsertionCostsCalculatorBuilder {
addAlgorithmListeners(standardLocal.getAlgorithmListener());
addInsertionListeners(standardLocal.getInsertionListener());
if (considerFixedCost) {
CalculatorPlusListeners withFixed = createCalculatorConsideringFixedCosts(vrp, baseCalculator, states, weightOfFixedCost);
baseCalculator = withFixed.getCalculator();
addAlgorithmListeners(withFixed.getAlgorithmListener());
addInsertionListeners(withFixed.getInsertionListener());
// CalculatorPlusListeners withFixed = createCalculatorConsideringFixedCosts(vrp, baseCalculator, states, weightOfFixedCost);
// baseCalculator = withFixed.getCalculator();
// addAlgorithmListeners(withFixed.getAlgorithmListener());
// addInsertionListeners(withFixed.getInsertionListener());
}
if (timeScheduling) {
// baseCalculator = new CalculatesServiceInsertionWithTimeSchedulingInSlices(baseCalculator,timeSlice,neighbors);
@ -309,14 +309,6 @@ public class JobInsertionCostsCalculatorBuilder {
return calculatorPlusListeners;
}
private CalculatorPlusListeners createCalculatorConsideringFixedCosts(VehicleRoutingProblem vrp, JobInsertionCostsCalculator baseCalculator, RouteAndActivityStateGetter activityStates2, double weightOfFixedCosts) {
final JobInsertionConsideringFixCostsCalculator withFixCost = new JobInsertionConsideringFixCostsCalculator(baseCalculator, activityStates2);
withFixCost.setWeightOfFixCost(weightOfFixedCosts);
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(withFixCost);
calcPlusListeners.getInsertionListener().add(new ConfigureFixCostCalculator(vrp, withFixCost));
return calcPlusListeners;
}
private CalculatorPlusListeners createStandardRoute(final VehicleRoutingProblem vrp, RouteAndActivityStateGetter activityStates2, int forwardLooking, int solutionMemory) {
ActivityInsertionCostsCalculator routeLevelCostEstimator;
if (activityInsertionCostCalculator == null && addDefaultCostCalc) {

View file

@ -15,50 +15,48 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.graphhopper.jsprit.core.algorithm.recreate;
package com.graphhopper.jsprit.core.algorithm.recreate;
import com.graphhopper.jsprit.core.algorithm.recreate.listener.InsertionStartsListener;
import com.graphhopper.jsprit.core.algorithm.recreate.listener.JobInsertedListener;
import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem;
import com.graphhopper.jsprit.core.problem.job.Job;
import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute;
import java.util.Collection;
/**
* Created by schroeder on 11/01/17.
*/
class SolutionCompletenessRatio implements InsertionStartsListener, JobInsertedListener {
final class ConfigureFixCostCalculator implements InsertionStartsListener, JobInsertedListener {
protected double solutionCompletenessRatio = 0.5;
private final VehicleRoutingProblem vrp;
private final JobInsertionConsideringFixCostsCalculator calcConsideringFix;
private final double minRatio = 0.5;
private final int nuOfJobs;
private int nuOfJobsToRecreate;
public ConfigureFixCostCalculator(VehicleRoutingProblem vrp, JobInsertionConsideringFixCostsCalculator calcConsideringFix) {
super();
this.vrp = vrp;
this.calcConsideringFix = calcConsideringFix;
public SolutionCompletenessRatio(int nuOfJobs) {
this.nuOfJobs = nuOfJobs;
}
@Override
public String toString() {
return "[name=configureFixCostCalculator]";
public void setSolutionCompletenessRatio(double ratio) {
solutionCompletenessRatio = ratio;
}
public double getSolutionCompletenessRatio() {
return solutionCompletenessRatio;
}
@Override
public void informInsertionStarts(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) {
this.nuOfJobsToRecreate = unassignedJobs.size();
double completenessRatio = (1 - ((double) nuOfJobsToRecreate / (double) vrp.getJobs().values().size()));
calcConsideringFix.setSolutionCompletenessRatio(Math.max(minRatio,completenessRatio));
solutionCompletenessRatio = (1 - ((double) nuOfJobsToRecreate / (double) nuOfJobs));
}
@Override
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
nuOfJobsToRecreate--;
double completenessRatio = (1 - ((double) nuOfJobsToRecreate / (double) vrp.getJobs().values().size()));
calcConsideringFix.setSolutionCompletenessRatio(Math.max(minRatio,completenessRatio));
solutionCompletenessRatio = (1 - ((double) nuOfJobsToRecreate / (double) nuOfJobs));
}
}

View file

@ -1,95 +0,0 @@
/*
* Licensed to GraphHopper GmbH under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*
* GraphHopper GmbH licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.graphhopper.jsprit.core.algorithm.recreate;
import com.graphhopper.jsprit.core.algorithm.state.StateManager;
import com.graphhopper.jsprit.core.problem.AbstractJob;
import com.graphhopper.jsprit.core.problem.Location;
import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem;
import com.graphhopper.jsprit.core.problem.job.Job;
import com.graphhopper.jsprit.core.problem.job.Service;
import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.mockito.Mockito.mock;
/**
* Created by schroeder on 15/08/16.
*/
public class ConfigureFixCostCalculatorTest {
VehicleRoutingProblem vrp;
@Before
public void before(){
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
for(int i=0;i<100;i++){
Service service = Service.Builder.newInstance("" + i).setLocation(Location.newInstance(0)).build();
vrpBuilder.addJob(service);
}
vrp = vrpBuilder.build();
}
@Test
public void shouldCalculateCorrectly(){
List<Job> unassigned = new ArrayList<>();
int count = 1;
for(String key : vrp.getJobs().keySet()) {
if(count <= 25) {
unassigned.add(vrp.getJobs().get(key));
}
count++;
}
JobInsertionConsideringFixCostsCalculator jicc = new JobInsertionConsideringFixCostsCalculator(mock(JobInsertionCostsCalculator.class),mock(StateManager.class));
ConfigureFixCostCalculator c = new ConfigureFixCostCalculator(vrp,jicc);
c.informInsertionStarts(new ArrayList<VehicleRoute>(), unassigned);
Assert.assertEquals(0.75, jicc.getSolutionCompletenessRatio(), 0.001);
}
@Test
public void shouldBeMinRatio(){
List<Job> unassigned = new ArrayList<>();
int count = 1;
for(String key : vrp.getJobs().keySet()) {
if(count <= 75) {
unassigned.add(vrp.getJobs().get(key));
}
count++;
}
JobInsertionConsideringFixCostsCalculator jicc = new JobInsertionConsideringFixCostsCalculator(mock(JobInsertionCostsCalculator.class),mock(StateManager.class));
ConfigureFixCostCalculator c = new ConfigureFixCostCalculator(vrp,jicc);
c.informInsertionStarts(new ArrayList<VehicleRoute>(), unassigned);
Assert.assertEquals(0.5, jicc.getSolutionCompletenessRatio(), 0.001);
}
@Test
public void shouldBeOne(){
List<Job> unassigned = new ArrayList<>();
JobInsertionConsideringFixCostsCalculator jicc = new JobInsertionConsideringFixCostsCalculator(mock(JobInsertionCostsCalculator.class),mock(StateManager.class));
ConfigureFixCostCalculator c = new ConfigureFixCostCalculator(vrp,jicc);
c.informInsertionStarts(new ArrayList<VehicleRoute>(), unassigned);
Assert.assertEquals(1.0, jicc.getSolutionCompletenessRatio(), 0.001);
}
}

View file

@ -20,6 +20,7 @@ package com.graphhopper.jsprit.core.algorithm.recreate;
import com.graphhopper.jsprit.core.algorithm.state.InternalStates;
import com.graphhopper.jsprit.core.problem.Capacity;
import com.graphhopper.jsprit.core.problem.job.Job;
import com.graphhopper.jsprit.core.problem.misc.JobInsertionContext;
import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute;
import com.graphhopper.jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter;
import com.graphhopper.jsprit.core.problem.vehicle.Vehicle;
@ -34,7 +35,9 @@ import static org.mockito.Mockito.when;
public class JobInsertionConsideringFixCostsCalculatorTest {
private JobInsertionConsideringFixCostsCalculator calc;
private IncreasingAbsoluteFixedCosts absFixedCosts;
private DecreasingRelativeFixedCosts relFixedCosts;
private Vehicle small;
@ -75,168 +78,270 @@ public class JobInsertionConsideringFixCostsCalculatorTest {
stateGetter = mock(RouteAndActivityStateGetter.class);
when(stateGetter.getRouteState(route, InternalStates.MAXLOAD, Capacity.class)).thenReturn(Capacity.Builder.newInstance().build());
calc = new JobInsertionConsideringFixCostsCalculator(jobInsertionCosts, stateGetter);
absFixedCosts = new IncreasingAbsoluteFixedCosts(10);
relFixedCosts = new DecreasingRelativeFixedCosts(stateGetter, 10);
}
@Test
public void whenOldVehicleIsNullAndSolutionComplete_itShouldReturnFixedCostsOfNewVehicle() {
calc.setSolutionCompletenessRatio(1.0);
calc.setWeightOfFixCost(1.0);
absFixedCosts.setSolutionCompletenessRatio(1.0);
absFixedCosts.setWeightOfFixCost(1.0);
relFixedCosts.setSolutionCompletenessRatio(1.0);
relFixedCosts.setWeightOfFixCost(1.0);
//(1.*absFix + 0.*relFix) * completeness * weight = (1.*100. + 0.*50.) * 1. * 1. = 100.
assertEquals(100., calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
assertEquals(100., absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNullAndSolutionIs0PercentComplete_itShouldReturnNoFixedCosts() {
calc.setSolutionCompletenessRatio(0.0);
calc.setWeightOfFixCost(1.0);
absFixedCosts.setSolutionCompletenessRatio(0.0);
absFixedCosts.setWeightOfFixCost(1.0);
relFixedCosts.setSolutionCompletenessRatio(0.0);
relFixedCosts.setWeightOfFixCost(1.0);
//(0.*absFix + 1.*relFix) * completeness * weight = 0.
assertEquals(0., calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
assertEquals(0., absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.1);
}
@Test
public void whenOldVehicleIsNullAndSolutionIs50PercentComplete_itShouldReturnAvgOfRelFixedAndAbsFixedCostOfNewVehicle() {
calc.setSolutionCompletenessRatio(0.5);
calc.setWeightOfFixCost(1.0);
absFixedCosts.setSolutionCompletenessRatio(0.5);
absFixedCosts.setWeightOfFixCost(1.0);
relFixedCosts.setSolutionCompletenessRatio(0.5);
relFixedCosts.setWeightOfFixCost(1.0);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(0.5*absFix + 0.5*relFix) * 0.5 * 1. = (0.5*100+0.5*50)*0.5*1. = 37.5
assertEquals(37.5, calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(37.5, absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNullAndSolutionIs75PercentComplete_itShouldReturnAvgOfRelFixedAndAbsFixedCostOfNewVehicle() {
calc.setSolutionCompletenessRatio(0.75);
calc.setWeightOfFixCost(1.0);
absFixedCosts.setSolutionCompletenessRatio(0.75);
absFixedCosts.setWeightOfFixCost(1.0);
relFixedCosts.setSolutionCompletenessRatio(0.75);
relFixedCosts.setWeightOfFixCost(1.0);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(0.75*absFix + 0.25*relFix) * 0.75 * 1.= (0.75*100.+0.25*50.)*0.75*1. = 65.625
assertEquals(65.625, calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(65.625, absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNullAndSolutionCompleteAndWeightIs05_itShouldReturnHalfOfFixedCostsOfNewVehicle() {
calc.setSolutionCompletenessRatio(1.0);
calc.setWeightOfFixCost(.5);
absFixedCosts.setSolutionCompletenessRatio(1.0);
absFixedCosts.setWeightOfFixCost(.5);
relFixedCosts.setSolutionCompletenessRatio(1.0);
relFixedCosts.setWeightOfFixCost(.5);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(1.*absFix + 0.*relFix) * 1. * 0.5 = (1.*100. + 0.*50.) * 1. * 0.5 = 5.
assertEquals(50., calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(50., absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNullAndSolutionIs0PercentCompleteAndWeightIs05_itShouldReturnHalfOfNoFixedCosts() {
calc.setSolutionCompletenessRatio(0.0);
calc.setWeightOfFixCost(.5);
absFixedCosts.setSolutionCompletenessRatio(0.0);
absFixedCosts.setWeightOfFixCost(.5);
relFixedCosts.setSolutionCompletenessRatio(0.0);
relFixedCosts.setWeightOfFixCost(.5);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(0.*absFix + 1.*relFix) * 0. * .5 = 0.
assertEquals(0., calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(0., absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNullAndSolutionIs50PercentCompleteAndWeightIs05_itShouldReturnHalfOfAvgOfRelFixedAndAbsFixedCostOfNewVehicle() {
calc.setSolutionCompletenessRatio(0.5);
calc.setWeightOfFixCost(.5);
absFixedCosts.setSolutionCompletenessRatio(0.5);
absFixedCosts.setWeightOfFixCost(.5);
relFixedCosts.setSolutionCompletenessRatio(0.5);
relFixedCosts.setWeightOfFixCost(.5);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(0.5*absFix + 0.5*relFix) * 0.5 * 0.= (0.5*100+0.5*50)*0.5*0.5 = 18.75
assertEquals(18.75, calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(18.75, absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNullAndSolutionIs75PercentCompleteAndWeightIs05_itShouldReturnHalfOfAvgOfRelFixedAndAbsFixedCostOfNewVehicle() {
calc.setSolutionCompletenessRatio(0.75);
calc.setWeightOfFixCost(0.5);
absFixedCosts.setSolutionCompletenessRatio(0.75);
absFixedCosts.setWeightOfFixCost(0.5);
relFixedCosts.setSolutionCompletenessRatio(0.75);
relFixedCosts.setWeightOfFixCost(0.5);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(0.75*absFix + 0.25*relFix) * 0.75 * 0.5 = (0.75*100.+0.25*50.)*0.75*0.5 = 32.8125
assertEquals(32.8125, calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(32.8125, absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNotNullAndSolutionComplete_itShouldReturnHalfOfFixedCostsOfNewVehicle() {
calc.setSolutionCompletenessRatio(1.0);
calc.setWeightOfFixCost(1.0);
absFixedCosts.setSolutionCompletenessRatio(1.0);
absFixedCosts.setWeightOfFixCost(1.0);
relFixedCosts.setSolutionCompletenessRatio(1.0);
relFixedCosts.setWeightOfFixCost(1.0);
when(route.getVehicle()).thenReturn(small);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(1.*absFix + 0.*relFix) * completeness * weight = (1.*(100.-50.) + 0.*(50.-0.)) * 1. * 1. = 50.
assertEquals(50., calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(50., absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNotNullAndSolutionIs0PercentComplete_itShouldReturnNoFixedCosts() {
calc.setSolutionCompletenessRatio(0.0);
calc.setWeightOfFixCost(1.0);
absFixedCosts.setSolutionCompletenessRatio(0.0);
absFixedCosts.setWeightOfFixCost(1.0);
relFixedCosts.setSolutionCompletenessRatio(0.0);
relFixedCosts.setWeightOfFixCost(1.0);
when(route.getVehicle()).thenReturn(small);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(0.*absFix + 1.*relFix) * completeness * weight = 0.
assertEquals(0., calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(0., absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNotNullAndSolutionIs50PercentComplete_itShouldCorrectVal() {
calc.setSolutionCompletenessRatio(0.5);
calc.setWeightOfFixCost(1.0);
absFixedCosts.setSolutionCompletenessRatio(0.5);
absFixedCosts.setWeightOfFixCost(1.0);
relFixedCosts.setSolutionCompletenessRatio(0.5);
relFixedCosts.setWeightOfFixCost(1.0);
when(route.getVehicle()).thenReturn(small);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(0.5*absFix + 0.5*relFix) * 0.5 * 1. = (0.5*(100-50)+0.5*(50-0))*0.5*1. = 25.
assertEquals(25., calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(25., absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNotNullAndSolutionIs75PercentComplete_itShouldReturnCorrectVal() {
calc.setSolutionCompletenessRatio(0.75);
calc.setWeightOfFixCost(1.0);
absFixedCosts.setSolutionCompletenessRatio(0.75);
absFixedCosts.setWeightOfFixCost(1.0);
relFixedCosts.setSolutionCompletenessRatio(0.75);
relFixedCosts.setWeightOfFixCost(1.0);
when(route.getVehicle()).thenReturn(small);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(0.75*absFix + 0.25*relFix) * 0.75 * 1.= (0.75*(100.-50.)+0.25*(50.-0.))*0.75*1. = 37.5
assertEquals(37.5, calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(37.5, absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNotNullAndSolutionCompleteAndWeightIs05_itShouldReturnCorrectVal() {
calc.setSolutionCompletenessRatio(1.0);
calc.setWeightOfFixCost(.5);
absFixedCosts.setSolutionCompletenessRatio(1.0);
absFixedCosts.setWeightOfFixCost(.5);
relFixedCosts.setSolutionCompletenessRatio(1.0);
relFixedCosts.setWeightOfFixCost(.5);
when(route.getVehicle()).thenReturn(small);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(1.*absFix + 0.*relFix) * 1. * 0.5 = (1.*(100.-50.) + 0.*(50.-0.)) * 1. * 0.5 = 25.
assertEquals(25., calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(25., absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNotNullAndSolutionIs0PercentCompleteAndWeightIs05_itShouldReturnCorrectVal() {
calc.setSolutionCompletenessRatio(0.0);
calc.setWeightOfFixCost(.5);
absFixedCosts.setSolutionCompletenessRatio(0.0);
absFixedCosts.setWeightOfFixCost(.5);
relFixedCosts.setSolutionCompletenessRatio(0.0);
relFixedCosts.setWeightOfFixCost(.5);
when(route.getVehicle()).thenReturn(small);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(0.*absFix + 1.*relFix) * 0. * .5 = 0.
assertEquals(0., calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(0., absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNotNullAndSolutionIs50PercentCompleteAndWeightIs05_itShouldReturnCorrectVal() {
calc.setSolutionCompletenessRatio(0.5);
calc.setWeightOfFixCost(.5);
absFixedCosts.setSolutionCompletenessRatio(0.5);
absFixedCosts.setWeightOfFixCost(.5);
relFixedCosts.setSolutionCompletenessRatio(0.5);
relFixedCosts.setWeightOfFixCost(.5);
when(route.getVehicle()).thenReturn(small);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(0.5*absFix + 0.5*relFix) * 0.5 * 0.= (0.5*(100-50)+0.5*(50-0))*0.5*0.5 = 12.5
assertEquals(12.5, calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(12.5, absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNotNullAndSolutionIs75PercentCompleteAndWeightIs05_itShouldReturnCorrectVal() {
calc.setSolutionCompletenessRatio(0.75);
calc.setWeightOfFixCost(0.5);
absFixedCosts.setSolutionCompletenessRatio(0.75);
absFixedCosts.setWeightOfFixCost(0.5);
relFixedCosts.setSolutionCompletenessRatio(0.75);
relFixedCosts.setWeightOfFixCost(0.5);
when(route.getVehicle()).thenReturn(small);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(0.75*absFix + 0.25*relFix) * 0.75 * 0.5 = (0.75*(100.-50.)+0.25*(50.-0.))*0.75*0.5 = 18.75
assertEquals(18.75, calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(18.75, absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNotNullAndCurrentLoadIs25AndSolutionIs50PercentCompleteAndWeightIs05_itShouldReturnCorrectVal() {
calc.setSolutionCompletenessRatio(0.5);
calc.setWeightOfFixCost(.5);
absFixedCosts.setSolutionCompletenessRatio(0.5);
absFixedCosts.setWeightOfFixCost(.5);
relFixedCosts.setSolutionCompletenessRatio(0.5);
relFixedCosts.setWeightOfFixCost(.5);
when(route.getVehicle()).thenReturn(small);
when(stateGetter.getRouteState(route, InternalStates.MAXLOAD, Capacity.class)).thenReturn(Capacity.Builder.newInstance().addDimension(0, 25).build());
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(0.5*absFix + 0.5*relFix) * 0.5 * 0.= (0.5*(100-50)+0.5*(75-25))*0.5*0.5 = 12.5
assertEquals(12.5, calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(12.5, absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNotNullAndCurrentLoadIs25AndSolutionIs75PercentCompleteAndWeightIs05_itShouldReturnCorrectVal() {
calc.setSolutionCompletenessRatio(0.75);
calc.setWeightOfFixCost(0.5);
absFixedCosts.setSolutionCompletenessRatio(0.75);
absFixedCosts.setWeightOfFixCost(0.5);
relFixedCosts.setSolutionCompletenessRatio(0.75);
relFixedCosts.setWeightOfFixCost(0.5);
when(route.getVehicle()).thenReturn(small);
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(0.75*absFix + 0.25*relFix) * 0.75 * 0.5 = (0.75*(100.-50.)+0.25*(75.-25.))*0.75*0.5 = 18.75
assertEquals(18.75, calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(18.75, absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsNotNullAndCurrentLoadIs25AndSolutionIs50PercentCompleteAndWeightIs05WithMultipleCapDims_itShouldReturnCorrectVal() {
calc.setSolutionCompletenessRatio(.5);
calc.setWeightOfFixCost(.5);
absFixedCosts.setSolutionCompletenessRatio(.5);
absFixedCosts.setWeightOfFixCost(.5);
relFixedCosts.setSolutionCompletenessRatio(.5);
relFixedCosts.setWeightOfFixCost(.5);
when(job.getSize()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 50).addDimension(1, 0).build());
@ -248,6 +353,8 @@ public class JobInsertionConsideringFixCostsCalculatorTest {
when(route.getVehicle()).thenReturn(small);
when(stateGetter.getRouteState(route, InternalStates.MAXLOAD, Capacity.class)).thenReturn(Capacity.Builder.newInstance().addDimension(0, 25).addDimension(1, 100).build());
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(0.5*absFix + 0.5*relFix) * 0.5 * 0.= (0.5*(100-50)+0.5*(75-25))*0.5*0.5 = 12.5
/*
* (0.5*(100-50)+0.5*(
@ -256,13 +363,16 @@ public class JobInsertionConsideringFixCostsCalculatorTest {
* = (0.5*(100-50)+0.5*((75/100+100/400)/2.*100 - ((25/50+100/100)/2.*50.)))*0.5*0.5
* = (0.5*(100-50)+0.5*12.5)*0.5*0.5 = 7.8125
*/
assertEquals(7.8125, calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(7.8125, absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}
@Test
public void whenOldVehicleIsMoreExpensive() {
calc.setSolutionCompletenessRatio(1);
calc.setWeightOfFixCost(1);
absFixedCosts.setSolutionCompletenessRatio(1);
absFixedCosts.setWeightOfFixCost(1);
relFixedCosts.setSolutionCompletenessRatio(1);
relFixedCosts.setWeightOfFixCost(1);
when(job.getSize()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 50).addDimension(1, 0).build());
@ -283,50 +393,77 @@ public class JobInsertionConsideringFixCostsCalculatorTest {
* = (0.5*(100-50)+0.5*((75/100+100/400)/2.*100 - ((25/50+100/100)/2.*50.)))*0.5*0.5
* = (0.5*(100-50)+0.5*12.5)*0.5*0.5 = 7.8125
*/
double insertionCost = calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost();
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
double insertionCost = absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context);
assertEquals(-50d, insertionCost, 0.01);
}
@Test
public void smallVSMediumAbsCosts() {
calc.setSolutionCompletenessRatio(1);
calc.setWeightOfFixCost(1);
absFixedCosts.setSolutionCompletenessRatio(1);
absFixedCosts.setWeightOfFixCost(1);
relFixedCosts.setSolutionCompletenessRatio(1);
relFixedCosts.setWeightOfFixCost(1);
when(route.getVehicle()).thenReturn(small);
double insertionCost = calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost();
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
double insertionCost = absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context);
assertEquals(50d, insertionCost, 0.01);
}
@Test
public void smallVSLargeAbsCosts() {
calc.setSolutionCompletenessRatio(1);
calc.setWeightOfFixCost(1);
absFixedCosts.setSolutionCompletenessRatio(1);
absFixedCosts.setWeightOfFixCost(1);
relFixedCosts.setSolutionCompletenessRatio(1);
relFixedCosts.setWeightOfFixCost(1);
when(route.getVehicle()).thenReturn(small);
double insertionCost = calc.getInsertionData(route, job, large, 0.0, null, Double.MAX_VALUE).getInsertionCost();
JobInsertionContext context = new JobInsertionContext(route, job, large, null, 0d);
double insertionCost = absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context);
assertEquals(150d, insertionCost, 0.01);
}
@Test
public void largeVSMediumAbsCosts() {
calc.setSolutionCompletenessRatio(1);
calc.setWeightOfFixCost(1);
absFixedCosts.setSolutionCompletenessRatio(1);
absFixedCosts.setWeightOfFixCost(1);
relFixedCosts.setSolutionCompletenessRatio(1);
relFixedCosts.setWeightOfFixCost(1);
when(route.getVehicle()).thenReturn(large);
double insertionCost = calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost();
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
double insertionCost = absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context);
assertEquals(-100d, insertionCost, 0.01);
}
@Test
public void mediumVSLargeAbsCosts() {
calc.setSolutionCompletenessRatio(1);
calc.setWeightOfFixCost(1);
absFixedCosts.setSolutionCompletenessRatio(1);
absFixedCosts.setWeightOfFixCost(1);
relFixedCosts.setSolutionCompletenessRatio(1);
relFixedCosts.setWeightOfFixCost(1);
when(route.getVehicle()).thenReturn(medium);
double insertionCost = calc.getInsertionData(route, job, large, 0.0, null, Double.MAX_VALUE).getInsertionCost();
JobInsertionContext context = new JobInsertionContext(route, job, large, null, 0d);
double insertionCost = absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context);
assertEquals(100d, insertionCost, 0.01);
}
@Test
public void whenOldVehicleIsMoreExpensive2() {
calc.setSolutionCompletenessRatio(0.1);
calc.setWeightOfFixCost(1);
absFixedCosts.setSolutionCompletenessRatio(0.1);
absFixedCosts.setWeightOfFixCost(1);
relFixedCosts.setSolutionCompletenessRatio(0.1);
relFixedCosts.setWeightOfFixCost(1);
when(job.getSize()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 50).addDimension(1, 0).build());
@ -339,22 +476,27 @@ public class JobInsertionConsideringFixCostsCalculatorTest {
when(route.getVehicle()).thenReturn(small);
when(stateGetter.getRouteState(route, InternalStates.MAXLOAD, Capacity.class)).thenReturn(Capacity.Builder.newInstance().addDimension(0, 25).addDimension(1, 100).build());
//(0.5*absFix + 0.5*relFix) * 0.5 * 0.= (0.5*(100-50)+0.5*(75-25))*0.5*0.5 = 12.5
/*
* (0.5*(100-50)+0.5*(
* relFixNew - relFixOld = (75/100+100/400)/2.*100 - ((25/50+100/100)/2.*50.) =
* )*0.5*0.5
* = (0.5*(100-50)+0.5*((75/100+100/400)/2.*100 - ((25/50+100/100)/2.*50.)))*0.5*0.5
* = (0.5*(100-50)+0.5*12.5)*0.5*0.5 = 7.8125
*/
double insertionCost = calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost();
assertEquals(-50d, insertionCost, 0.01);
job = 50
abs = (50 - 100) * 0.1 * 0.1 * 1.0 = -0.5
rel = ( (75/50+100/100)/2 * 50 - (25/100 + 100/400)/2 * 100) * 0.9 * 0.1 = 3.375
c = -0.5 + 3.375 = 2.875
*/
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
double insertionCost = absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context);
assertEquals(2.875, insertionCost, 0.01);
}
@Test
public void whenOldVehicleIsNotNullAndCurrentLoadIs25AndSolutionIs75PercentCompleteAndWeightIs05WithMultipleCapDims_itShouldReturnCorrectVal() {
calc.setSolutionCompletenessRatio(0.75);
calc.setWeightOfFixCost(0.5);
absFixedCosts.setSolutionCompletenessRatio(0.75);
absFixedCosts.setWeightOfFixCost(0.5);
relFixedCosts.setSolutionCompletenessRatio(0.75);
relFixedCosts.setWeightOfFixCost(0.5);
when(job.getSize()).thenReturn(Capacity.Builder.newInstance().addDimension(0, 50).addDimension(1, 0).build());
VehicleType oType = VehicleTypeImpl.Builder.newInstance("otype").addCapacityDimension(0, 50).addCapacityDimension(1, 100).setFixedCost(50.0).build();
@ -365,9 +507,11 @@ public class JobInsertionConsideringFixCostsCalculatorTest {
when(route.getVehicle()).thenReturn(small);
when(stateGetter.getRouteState(route, InternalStates.MAXLOAD, Capacity.class)).thenReturn(Capacity.Builder.newInstance().addDimension(0, 25).addDimension(1, 100).build());
JobInsertionContext context = new JobInsertionContext(route, job, medium, null, 0d);
//(0.75*absFix + 0.25*relFix) * 0.75 * 0.5 = (0.75*(100.-50.)+0.25*12.5)*0.75*0.5 = 15.234375
assertEquals(15.234375, calc.getInsertionData(route, job, medium, 0.0, null, Double.MAX_VALUE).getInsertionCost(), 0.01);
assertEquals(15.234375, absFixedCosts.getCosts(context) + relFixedCosts.getCosts(context), 0.01);
}