mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
add MultipleProductsWithLoadConstraint example
This commit is contained in:
parent
7be8a408f1
commit
2abf5f5c9d
3 changed files with 234 additions and 3 deletions
|
|
@ -1,5 +1,22 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
~ 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/>.
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
|
||||||
|
|
||||||
<algorithm xmlns="http://www.w3schools.com"
|
<algorithm xmlns="http://www.w3schools.com"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com algorithm_schema.xsd">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com algorithm_schema.xsd">
|
||||||
|
|
||||||
|
|
@ -23,7 +40,7 @@
|
||||||
<modules>
|
<modules>
|
||||||
<module name="ruin_and_recreate">
|
<module name="ruin_and_recreate">
|
||||||
<ruin name="randomRuin">
|
<ruin name="randomRuin">
|
||||||
<share>0.4</share>
|
<share>0.5</share>
|
||||||
</ruin>
|
</ruin>
|
||||||
<insertion name="bestInsertion"/>
|
<insertion name="bestInsertion"/>
|
||||||
</module>
|
</module>
|
||||||
|
|
@ -39,7 +56,7 @@
|
||||||
<modules>
|
<modules>
|
||||||
<module name="ruin_and_recreate">
|
<module name="ruin_and_recreate">
|
||||||
<ruin id="1" name="radialRuin">
|
<ruin id="1" name="radialRuin">
|
||||||
<share>0.2</share>
|
<share>0.3</share>
|
||||||
</ruin>
|
</ruin>
|
||||||
<insertion name="bestInsertion"/>
|
<insertion name="bestInsertion"/>
|
||||||
</module>
|
</module>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,195 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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.analysis.toolbox.GraphStreamViewer;
|
||||||
|
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
||||||
|
import jsprit.core.algorithm.VehicleRoutingAlgorithmBuilder;
|
||||||
|
import jsprit.core.algorithm.state.InternalStates;
|
||||||
|
import jsprit.core.algorithm.state.StateManager;
|
||||||
|
import jsprit.core.problem.Capacity;
|
||||||
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
|
import jsprit.core.problem.constraint.ConstraintManager;
|
||||||
|
import jsprit.core.problem.constraint.HardActivityStateLevelConstraint;
|
||||||
|
import jsprit.core.problem.job.Shipment;
|
||||||
|
import jsprit.core.problem.misc.JobInsertionContext;
|
||||||
|
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||||
|
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||||
|
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||||
|
import jsprit.core.problem.vehicle.VehicleType;
|
||||||
|
import jsprit.core.problem.vehicle.VehicleTypeImpl;
|
||||||
|
import jsprit.core.reporting.SolutionPrinter;
|
||||||
|
import jsprit.core.util.Coordinate;
|
||||||
|
import jsprit.core.util.Solutions;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
//import jsprit.core.problem.solution.route.state.StateFactory; //v1.3.1
|
||||||
|
|
||||||
|
public class MultipleProductsWithLoadConstraintExample {
|
||||||
|
|
||||||
|
static final int BANANAS_DIMENSION_INDEX = 0;
|
||||||
|
|
||||||
|
static final int APPLES_DIMENSION_INDEX = 1;
|
||||||
|
|
||||||
|
static class BananasFirst implements HardActivityStateLevelConstraint {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConstraintsStatus fulfilled(JobInsertionContext jobInsertionContext, TourActivity prevActivity, TourActivity newActivity, TourActivity nextActivity, double departureTimeAtPrevActivity) {
|
||||||
|
if(isBananaPickup(newActivity) && isApplePickup(prevActivity)) return ConstraintsStatus.NOT_FULFILLED_BREAK;
|
||||||
|
if(isBananaPickup(nextActivity) && isApplePickup(newActivity)) return ConstraintsStatus.NOT_FULFILLED;
|
||||||
|
return ConstraintsStatus.FULFILLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isApplePickup(TourActivity act){
|
||||||
|
return act.getSize().get(APPLES_DIMENSION_INDEX) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isBananaPickup(TourActivity act){
|
||||||
|
return act.getSize().get(BANANAS_DIMENSION_INDEX) > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class NoBananasANDApplesConstraint implements HardActivityStateLevelConstraint {
|
||||||
|
|
||||||
|
private StateManager stateManager;
|
||||||
|
|
||||||
|
NoBananasANDApplesConstraint(StateManager stateManager) {
|
||||||
|
this.stateManager = stateManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConstraintsStatus fulfilled(JobInsertionContext jobInsertionContext, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double departureTimeAtPrevAct) {
|
||||||
|
Capacity loadAtPrevAct = getLoadAtPreviousAct(prevAct);
|
||||||
|
|
||||||
|
if( isPickup(newAct) ){
|
||||||
|
if( ( isApplePickup(newAct) && hasBananasInVehicle(loadAtPrevAct) ) ||
|
||||||
|
( isBananaPickup(newAct) && hasApplesInVehicle(loadAtPrevAct) ) ){
|
||||||
|
return ConstraintsStatus.NOT_FULFILLED;
|
||||||
|
}
|
||||||
|
if( ( isApplePickup(newAct) && isBananaPickup(nextAct) ) ||
|
||||||
|
( isBananaPickup(newAct) && isApplePickup(nextAct) ) ){
|
||||||
|
return ConstraintsStatus.NOT_FULFILLED;
|
||||||
|
}
|
||||||
|
return ConstraintsStatus.FULFILLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isDelivery(newAct) ){
|
||||||
|
if( ( isAppleDelivery(newAct) && hasBananasInVehicle(loadAtPrevAct) ) ||
|
||||||
|
( isBananaDelivery(newAct) && hasApplesInVehicle(loadAtPrevAct) ) ){
|
||||||
|
return ConstraintsStatus.NOT_FULFILLED_BREAK; // if so constraint is broken forever -> break here
|
||||||
|
}
|
||||||
|
return ConstraintsStatus.FULFILLED;
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("can only constraint shipments");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasApplesInVehicle(Capacity loadAtPrevAct) {
|
||||||
|
return loadAtPrevAct.get(APPLES_DIMENSION_INDEX) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasBananasInVehicle(Capacity loadAtPrevAct){
|
||||||
|
return loadAtPrevAct.get(BANANAS_DIMENSION_INDEX) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isBananaPickup(TourActivity act){
|
||||||
|
return act.getSize().get(BANANAS_DIMENSION_INDEX) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isBananaDelivery(TourActivity act){
|
||||||
|
return act.getSize().get(BANANAS_DIMENSION_INDEX) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isApplePickup(TourActivity act){
|
||||||
|
return act.getSize().get(APPLES_DIMENSION_INDEX) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAppleDelivery(TourActivity act){
|
||||||
|
return act.getSize().get(APPLES_DIMENSION_INDEX) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isPickup(TourActivity newAct) {
|
||||||
|
return newAct.getName().equals("pickupShipment");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isDelivery(TourActivity newAct) {
|
||||||
|
return newAct.getName().equals("deliverShipment");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Capacity getLoadAtPreviousAct(TourActivity prevAct) {
|
||||||
|
// Capacity prevLoad = stateManager.getActivityState(prevAct, StateFactory.LOAD, Capacity.class); //v1.3.1
|
||||||
|
Capacity prevLoad = stateManager.getActivityState(prevAct, InternalStates.LOAD, Capacity.class); //1.3.2-SNAPSHOT & upcoming release v1.4
|
||||||
|
if(prevLoad != null) return prevLoad;
|
||||||
|
else return Capacity.Builder.newInstance().build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
|
||||||
|
VehicleType type = VehicleTypeImpl.Builder.newInstance("type").addCapacityDimension(BANANAS_DIMENSION_INDEX,10)
|
||||||
|
.addCapacityDimension(APPLES_DIMENSION_INDEX, 20).build();
|
||||||
|
VehicleImpl vehicle = VehicleImpl.Builder.newInstance("vehicle").setStartLocationCoordinate(Coordinate.newInstance(0, 0))
|
||||||
|
.setType(type).build();
|
||||||
|
|
||||||
|
Shipment bananas = Shipment.Builder.newInstance("bananas_1").addSizeDimension(BANANAS_DIMENSION_INDEX,1)
|
||||||
|
.setPickupCoord(Coordinate.newInstance(1, 8)).setDeliveryCoord(Coordinate.newInstance(10, 8)).build();
|
||||||
|
|
||||||
|
Shipment bananas_2 = Shipment.Builder.newInstance("bananas_2").addSizeDimension(BANANAS_DIMENSION_INDEX,1)
|
||||||
|
.setPickupCoord(Coordinate.newInstance(2, 8)).setDeliveryCoord(Coordinate.newInstance(11, 8)).build();
|
||||||
|
|
||||||
|
Shipment bananas_3 = Shipment.Builder.newInstance("bananas_3").addSizeDimension(BANANAS_DIMENSION_INDEX,1)
|
||||||
|
.setPickupCoord(Coordinate.newInstance(3, 8)).setDeliveryCoord(Coordinate.newInstance(12, 8)).build();
|
||||||
|
|
||||||
|
Shipment apples = Shipment.Builder.newInstance("apples_1").addSizeDimension(APPLES_DIMENSION_INDEX,1)
|
||||||
|
.setPickupCoord(Coordinate.newInstance(1, 6)).setDeliveryCoord(Coordinate.newInstance(10, 12)).build();
|
||||||
|
|
||||||
|
Shipment apples_2 = Shipment.Builder.newInstance("apples_2").addSizeDimension(APPLES_DIMENSION_INDEX,1)
|
||||||
|
.setPickupCoord(Coordinate.newInstance(1, 5)).setDeliveryCoord(Coordinate.newInstance(10, 11)).build();
|
||||||
|
|
||||||
|
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().setFleetSize(VehicleRoutingProblem.FleetSize.INFINITE)
|
||||||
|
.addVehicle(vehicle)
|
||||||
|
.addJob(bananas).addJob(apples).addJob(bananas_2).addJob(bananas_3).addJob(apples_2).build();
|
||||||
|
|
||||||
|
VehicleRoutingAlgorithmBuilder vraBuilder = new VehicleRoutingAlgorithmBuilder(vrp,"input/algorithmConfig.xml");
|
||||||
|
vraBuilder.addCoreConstraints();
|
||||||
|
vraBuilder.addDefaultCostCalculators();
|
||||||
|
|
||||||
|
StateManager stateManager = new StateManager(vrp); //1.3.2-SNAPSHOT & upcoming release v1.4
|
||||||
|
// StateManager stateManager = new StateManager(vrp.getTransportCosts()); //v1.3.1
|
||||||
|
|
||||||
|
ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager);
|
||||||
|
constraintManager.addConstraint(new NoBananasANDApplesConstraint(stateManager), ConstraintManager.Priority.CRITICAL);
|
||||||
|
// constraintManager.addConstraint(new BananasFirst(),ConstraintManager.Priority.CRITICAL);
|
||||||
|
|
||||||
|
vraBuilder.setStateAndConstraintManager(stateManager,constraintManager);
|
||||||
|
VehicleRoutingAlgorithm vra = vraBuilder.build();
|
||||||
|
// vra.setNuOfIterations(100); //1.3.2-SNAPSHOT
|
||||||
|
// vra.setMaxIterations(100);
|
||||||
|
|
||||||
|
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
||||||
|
|
||||||
|
SolutionPrinter.print(vrp, Solutions.bestOf(solutions), SolutionPrinter.Print.VERBOSE);
|
||||||
|
|
||||||
|
new GraphStreamViewer(vrp, Solutions.bestOf(solutions)).labelWith(GraphStreamViewer.Label.ID).setRenderShipments(true).display();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
21
pom.xml
21
pom.xml
|
|
@ -1,4 +1,21 @@
|
||||||
|
|
||||||
|
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
~ 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/>.
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
|
||||||
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
@ -238,7 +255,8 @@
|
||||||
<tagNameFormat>v@{project.version}</tagNameFormat>
|
<tagNameFormat>v@{project.version}</tagNameFormat>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
|
||||||
</plugins>
|
</plugins>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -251,6 +269,7 @@
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
<version>2.9.1</version>
|
<version>2.9.1</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</reporting>
|
</reporting>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue