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

RandomInsertionAdded (#46)

* RandomInsertionAdded

* fix

* oops

* wrong algorithm name

* add breaks too

* test added

* containAlll

* if
This commit is contained in:
kandelirina 2018-05-01 13:34:59 +03:00 committed by kobyb
parent 5b0efb61e7
commit 8fa3c81983
9 changed files with 544 additions and 3 deletions

View file

@ -42,7 +42,7 @@ class InsertionFactory {
if (config.containsKey("[@name]")) {
String insertionName = config.getString("[@name]");
if (!insertionName.equals("bestInsertion") && !insertionName.equals("regretInsertion")) {
if (!insertionName.equals("bestInsertion") && !insertionName.equals("regretInsertion") && !insertionName.equals("randomInsertion")) {
throw new IllegalStateException(insertionName + " is not supported. use either \"bestInsertion\" or \"regretInsertion\"");
}
@ -104,6 +104,8 @@ class InsertionFactory {
if (fastRegret != null) {
iBuilder.setFastRegret(Boolean.parseBoolean(fastRegret));
}
} else if (insertionName.equals("randomInsertion")) {
iBuilder.setInsertionStrategy(InsertionBuilder.Strategy.RANDOM);
}
return iBuilder.build();
} else throw new IllegalStateException("cannot create insertionStrategy, since it has no name.");

View file

@ -886,7 +886,7 @@ public class VehicleRoutingAlgorithms {
String insertionName = moduleConfig.getString("insertion[@name]");
if (insertionName == null)
throw new IllegalStateException("module.insertion[@name] is missing. set it to \"regretInsertion\" or \"bestInsertion\"");
throw new IllegalStateException("module.insertion[@name] is missing. set it to \"regretInsertion\" or \"bestInsertion\" or \"randomInsertion\"");
String insertionId = moduleConfig.getString("insertion[@id]");
if (insertionId == null) insertionId = "noId";
ModKey insertionKey = makeKey(insertionName, insertionId);

View file

@ -275,6 +275,7 @@
<xs:restriction base="xs:string">
<xs:enumeration value="bestInsertion"/>
<xs:enumeration value="regretInsertion"/>
<xs:enumeration value="randomInsertion"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>

View file

@ -0,0 +1,123 @@
package com.graphhopper.jsprit.io.algorithm;
import com.graphhopper.jsprit.core.algorithm.VariablePlusFixedSolutionCostCalculatorFactory;
import com.graphhopper.jsprit.core.algorithm.VehicleRoutingAlgorithm;
import com.graphhopper.jsprit.core.algorithm.state.StateManager;
import com.graphhopper.jsprit.core.problem.Location;
import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem;
import com.graphhopper.jsprit.core.problem.constraint.ConstraintManager;
import com.graphhopper.jsprit.core.problem.cost.VehicleRoutingTransportCosts;
import com.graphhopper.jsprit.core.problem.driver.Driver;
import com.graphhopper.jsprit.core.problem.job.Delivery;
import com.graphhopper.jsprit.core.problem.job.Service;
import com.graphhopper.jsprit.core.problem.job.Shipment;
import com.graphhopper.jsprit.core.problem.solution.SolutionCostCalculator;
import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow;
import com.graphhopper.jsprit.core.problem.vehicle.Vehicle;
import com.graphhopper.jsprit.core.problem.vehicle.VehicleImpl;
import com.graphhopper.jsprit.core.problem.vehicle.VehicleTypeImpl;
import com.graphhopper.jsprit.core.util.Solutions;
import org.junit.Test;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class SkillsTest {
@Test
public void skillsAdded() {
final HashSet<String> first = new HashSet<>(); first.add("C");
final HashSet<String> second = new HashSet<>(); second.add("A");second.add("B");
final VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance().setFleetSize(VehicleRoutingProblem.FleetSize.FINITE)
.addVehicle(getVehicle("v1", Location.newInstance(0, 0), 0, 100, 20, first, false, 1, 1))
.addVehicle(getVehicle("v2", Location.newInstance(0, 14), 0, 100, 20, second, false, 1, 1))
.addJob(getService(Location.newInstance(0, 5), 0, 20, new HashSet<String>(), 1))
.addJob(getService(Location.newInstance(0, 6), 0, 20, new HashSet<String>(), 1))
.addJob(getShipment(Location.newInstance(10, 10), Location.newInstance(10, 12), 10, 20, 10, 50, first, 10));
builder.setRoutingCost(getTransportCosts());
VehicleRoutingProblem vrp = builder.build();
VehicleRoutingProblemSolution bestSolution = getVehicleRoutingProblemSolution(vrp, "com/graphhopper/jsprit/io/algorithm/algorithmConfig.xml");
assertEquals(bestSolution.getRoutes().size(), 1);
assertFalse(bestSolution.getUnassignedJobs().isEmpty());
bestSolution = getVehicleRoutingProblemSolution(vrp, "com/graphhopper/jsprit/io/algorithm/configWithRandomInsert.xml");
assertEquals(bestSolution.getRoutes().size(), 2);
assertTrue(bestSolution.getUnassignedJobs().isEmpty());
}
private VehicleRoutingProblemSolution getVehicleRoutingProblemSolution(VehicleRoutingProblem vrp, String config) {
StateManager stateManager = new StateManager(vrp);
final SolutionCostCalculator calculator = new VariablePlusFixedSolutionCostCalculatorFactory(stateManager).createCalculator();
SolutionCostCalculator solutionCostCalculator = new SolutionCostCalculator() {
@Override
public double getCosts(VehicleRoutingProblemSolution solution) {
return calculator.getCosts(solution) + solution.getUnassignedJobs().size() * 100;
}
};
final VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, 1, config, stateManager, new ConstraintManager(vrp, stateManager), solutionCostCalculator);
return Solutions.bestOf(algorithm.searchSolutions());
}
private static VehicleRoutingTransportCosts getTransportCosts() {
return new VehicleRoutingTransportCosts() {
@Override
public double getBackwardTransportCost(Location from, Location to, double arrivalTime, Driver driver, Vehicle vehicle) { return getDistance(from, to, arrivalTime, vehicle); }
@Override
public double getBackwardTransportTime(Location from, Location to, double arrivalTime, Driver driver, Vehicle vehicle) { return getDistance(from, to, arrivalTime, vehicle); }
@Override
public double getTransportCost(Location from, Location to, double departureTime, Driver driver, Vehicle vehicle) { return getDistance(from, to, departureTime, vehicle); }
@Override
public double getTransportTime(Location from, Location to, double departureTime, Driver driver, Vehicle vehicle) { return getDistance(from, to, departureTime, vehicle); }
@Override
public double getDistance(Location from, Location to, double departureTime, Vehicle vehicle) {
return Math.abs(from.getCoordinate().getX() - to.getCoordinate().getX()) + Math.abs(from.getCoordinate().getY() - to.getCoordinate().getY());
}
};
}
private static Vehicle getVehicle(String id, Location location, int start, int end, int capacity, Set<String> skills, boolean returnToDepot, int fixedCost, int costPerDistance) {
return VehicleImpl.Builder.newInstance(id)
.setStartLocation(location).setLatestArrival(end).setEarliestStart(start).setType(
VehicleTypeImpl.Builder.newInstance(UUID.randomUUID().toString()).setFixedCost(fixedCost).setCostPerDistance(costPerDistance).addCapacityDimension(0, capacity).build()
)
.addAllSkills(skills).setReturnToDepot(returnToDepot).build();
}
private static Service getService(Location location, int start, int end, Set<String> requiredSkills, int priority) {
return Delivery.Builder.newInstance("service_" + UUID.randomUUID().toString().substring(0,5))
.setLocation(location)
.setServiceTime(1)
.addTimeWindow(new TimeWindow(start, end))
.addSizeDimension(0, 1)
.addAllRequiredSkills(requiredSkills)
.setPriority(priority)
.setName(UUID.randomUUID().toString()).build();
}
private static Shipment getShipment(Location pickupLocation, Location dropoffLocation, int pickupStart, int pickupEnd, int dropoffStart, int dropoffEnd, Set<String> skills, int priority) {
return Shipment.Builder.newInstance("shipment_" + UUID.randomUUID().toString().substring(0,5))
.setPickupLocation(pickupLocation).setDeliveryLocation(dropoffLocation)
.setDeliveryServiceTime(1).setPickupServiceTime(1)
.addSizeDimension(0, 1)
.setPickupTimeWindow(new TimeWindow(pickupStart, pickupEnd))
.setDeliveryTimeWindow(new TimeWindow(dropoffStart, dropoffEnd))
.addAllRequiredSkills(skills)
.setPriority(priority)
.build();
}
}

View file

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<algorithm xmlns="http://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3schools.com algorithm_schema.xsd">
<iterations>2000</iterations>
<construction>
<insertion name="regretInsertion">
</insertion>
</construction>
<strategy>
<memory>1</memory>
<searchStrategies>
<searchStrategy name="randomRR">
<selector name="selectBest"/>
<acceptor name="schrimpfAcceptance">
<alpha>0.2</alpha>
<warmup>20</warmup>
</acceptor>
<modules>
<module name="ruin_and_recreate">
<ruin name="randomRuin">
<share>0.9</share>
</ruin>
<insertion name="randomInsertion"/>
</module>
</modules>
<probability>0.1</probability>
</searchStrategy>
<searchStrategy name="radialRR">
<selector name="selectBest"/>
<acceptor name="schrimpfAcceptance"/>
<modules>
<module name="ruin_and_recreate">
<ruin id="1" name="radialRuin">
<share>0.3</share>
</ruin>
<insertion name="regretInsertion"/>
</module>
</modules>
<probability>0.4</probability>
</searchStrategy>
<searchStrategy name="smallRadialRR">
<selector name="selectBest"/>
<acceptor name="schrimpfAcceptance"/>
<modules>
<module name="ruin_and_recreate">
<ruin id="2" name="radialRuin">
<share>0.05</share>
</ruin>
<insertion name="regretInsertion"/>
</module>
</modules>
<probability>0.2</probability>
</searchStrategy>
</searchStrategies>
</strategy>
</algorithm>