mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
Merge branch 'routebuilder-break-location'
# Conflicts: # jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/solution/route/VehicleRoute.java
This commit is contained in:
commit
0fb7469d1f
7 changed files with 711 additions and 265 deletions
|
|
@ -82,7 +82,9 @@ public class Jsprit {
|
||||||
WORST_BEST("worst_best"),
|
WORST_BEST("worst_best"),
|
||||||
WORST_REGRET("worst_regret"),
|
WORST_REGRET("worst_regret"),
|
||||||
CLUSTER_BEST("cluster_best"),
|
CLUSTER_BEST("cluster_best"),
|
||||||
CLUSTER_REGRET("cluster_regret");
|
CLUSTER_REGRET("cluster_regret"),
|
||||||
|
STRING_BEST("string_best"),
|
||||||
|
STRING_REGRET("string_regret");
|
||||||
|
|
||||||
String strategyName;
|
String strategyName;
|
||||||
|
|
||||||
|
|
@ -119,7 +121,12 @@ public class Jsprit {
|
||||||
FAST_REGRET("regret.fast"),
|
FAST_REGRET("regret.fast"),
|
||||||
MAX_TRANSPORT_COSTS("max_transport_costs"),
|
MAX_TRANSPORT_COSTS("max_transport_costs"),
|
||||||
CONSTRUCTION("construction"),
|
CONSTRUCTION("construction"),
|
||||||
BREAK_SCHEDULING("break_scheduling");
|
BREAK_SCHEDULING("break_scheduling"),
|
||||||
|
STRING_KMIN("string_kmin"),
|
||||||
|
STRING_KMAX("string_kmax"),
|
||||||
|
STRING_LMIN("string_lmin"),
|
||||||
|
STRING_LMAX("string_lmax");
|
||||||
|
|
||||||
|
|
||||||
String paraName;
|
String paraName;
|
||||||
|
|
||||||
|
|
@ -178,10 +185,21 @@ public class Jsprit {
|
||||||
defaults.put(Strategy.RADIAL_REGRET.toString(), ".5");
|
defaults.put(Strategy.RADIAL_REGRET.toString(), ".5");
|
||||||
defaults.put(Strategy.RANDOM_BEST.toString(), ".5");
|
defaults.put(Strategy.RANDOM_BEST.toString(), ".5");
|
||||||
defaults.put(Strategy.RANDOM_REGRET.toString(), ".5");
|
defaults.put(Strategy.RANDOM_REGRET.toString(), ".5");
|
||||||
|
|
||||||
|
defaults.put(Strategy.STRING_BEST.toString(), "0.0");
|
||||||
|
defaults.put(Strategy.STRING_REGRET.toString(), "0.0");
|
||||||
|
|
||||||
|
defaults.put(Parameter.STRING_KMIN.toString(), "1");
|
||||||
|
defaults.put(Parameter.STRING_KMAX.toString(), "6");
|
||||||
|
defaults.put(Parameter.STRING_LMIN.toString(), "10");
|
||||||
|
defaults.put(Parameter.STRING_LMAX.toString(), "30");
|
||||||
|
|
||||||
defaults.put(Strategy.WORST_BEST.toString(), "0.");
|
defaults.put(Strategy.WORST_BEST.toString(), "0.");
|
||||||
defaults.put(Strategy.WORST_REGRET.toString(), "1.");
|
defaults.put(Strategy.WORST_REGRET.toString(), "1.");
|
||||||
defaults.put(Strategy.CLUSTER_BEST.toString(), "0.");
|
defaults.put(Strategy.CLUSTER_BEST.toString(), "0.");
|
||||||
defaults.put(Strategy.CLUSTER_REGRET.toString(), "1.");
|
defaults.put(Strategy.CLUSTER_REGRET.toString(), "1.");
|
||||||
|
|
||||||
|
|
||||||
defaults.put(Parameter.FIXED_COST_PARAM.toString(), "0.");
|
defaults.put(Parameter.FIXED_COST_PARAM.toString(), "0.");
|
||||||
defaults.put(Parameter.VEHICLE_SWITCH.toString(), "true");
|
defaults.put(Parameter.VEHICLE_SWITCH.toString(), "true");
|
||||||
defaults.put(Parameter.ITERATIONS.toString(), "2000");
|
defaults.put(Parameter.ITERATIONS.toString(), "2000");
|
||||||
|
|
@ -472,6 +490,16 @@ public class Jsprit {
|
||||||
random)
|
random)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
int kMin = toInteger(properties.getProperty(Parameter.STRING_KMIN.toString()));
|
||||||
|
int kMax = toInteger(properties.getProperty(Parameter.STRING_KMAX.toString()));
|
||||||
|
int lMin = toInteger(properties.getProperty(Parameter.STRING_LMIN.toString()));
|
||||||
|
int lMax = toInteger(properties.getProperty(Parameter.STRING_LMAX.toString()));
|
||||||
|
|
||||||
|
final RuinString stringRuin = new RuinString(vrp, jobNeighborhoods);
|
||||||
|
stringRuin.setNoRoutes(kMin, kMax);
|
||||||
|
stringRuin.setStringLength(lMin, lMax);
|
||||||
|
stringRuin.setRandom(random);
|
||||||
|
|
||||||
AbstractInsertionStrategy regret;
|
AbstractInsertionStrategy regret;
|
||||||
final ScoringFunction scorer;
|
final ScoringFunction scorer;
|
||||||
|
|
||||||
|
|
@ -592,6 +620,11 @@ public class Jsprit {
|
||||||
final SearchStrategy clusters_best = new SearchStrategy(Strategy.CLUSTER_BEST.toString(), new SelectBest(), acceptor, objectiveFunction);
|
final SearchStrategy clusters_best = new SearchStrategy(Strategy.CLUSTER_BEST.toString(), new SelectBest(), acceptor, objectiveFunction);
|
||||||
clusters_best.addModule(new RuinAndRecreateModule(Strategy.CLUSTER_BEST.toString(), best, clusters));
|
clusters_best.addModule(new RuinAndRecreateModule(Strategy.CLUSTER_BEST.toString(), best, clusters));
|
||||||
|
|
||||||
|
SearchStrategy stringRegret = new SearchStrategy(Strategy.STRING_REGRET.toString(), new SelectBest(), acceptor, objectiveFunction);
|
||||||
|
stringRegret.addModule(new RuinAndRecreateModule(Strategy.STRING_REGRET.toString(), regret, stringRuin));
|
||||||
|
|
||||||
|
SearchStrategy stringBest = new SearchStrategy(Strategy.STRING_BEST.toString(), new SelectBest(), acceptor, objectiveFunction);
|
||||||
|
stringBest.addModule(new RuinAndRecreateModule(Strategy.STRING_BEST.toString(), best, stringRuin));
|
||||||
|
|
||||||
PrettyAlgorithmBuilder prettyBuilder = PrettyAlgorithmBuilder.newInstance(vrp, fm, stateManager, constraintManager);
|
PrettyAlgorithmBuilder prettyBuilder = PrettyAlgorithmBuilder.newInstance(vrp, fm, stateManager, constraintManager);
|
||||||
prettyBuilder.setRandom(random);
|
prettyBuilder.setRandom(random);
|
||||||
|
|
@ -605,7 +638,10 @@ public class Jsprit {
|
||||||
.withStrategy(worst_best, toDouble(getProperty(Strategy.WORST_BEST.toString())))
|
.withStrategy(worst_best, toDouble(getProperty(Strategy.WORST_BEST.toString())))
|
||||||
.withStrategy(worst_regret, toDouble(getProperty(Strategy.WORST_REGRET.toString())))
|
.withStrategy(worst_regret, toDouble(getProperty(Strategy.WORST_REGRET.toString())))
|
||||||
.withStrategy(clusters_regret, toDouble(getProperty(Strategy.CLUSTER_REGRET.toString())))
|
.withStrategy(clusters_regret, toDouble(getProperty(Strategy.CLUSTER_REGRET.toString())))
|
||||||
.withStrategy(clusters_best, toDouble(getProperty(Strategy.CLUSTER_BEST.toString())));
|
.withStrategy(clusters_best, toDouble(getProperty(Strategy.CLUSTER_BEST.toString())))
|
||||||
|
.withStrategy(stringBest, toDouble(getProperty(Strategy.STRING_BEST.toString())))
|
||||||
|
.withStrategy(stringRegret, toDouble(getProperty(Strategy.STRING_REGRET.toString())));
|
||||||
|
|
||||||
if (getProperty(Parameter.CONSTRUCTION.toString()).equals(Construction.BEST_INSERTION.toString())) {
|
if (getProperty(Parameter.CONSTRUCTION.toString()).equals(Construction.BEST_INSERTION.toString())) {
|
||||||
prettyBuilder.constructInitialSolutionWith(best, objectiveFunction);
|
prettyBuilder.constructInitialSolutionWith(best, objectiveFunction);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
* 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.ruin;
|
||||||
|
|
||||||
|
import com.graphhopper.jsprit.core.problem.AbstractActivity;
|
||||||
|
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 com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivity;
|
||||||
|
import com.graphhopper.jsprit.core.util.RandomUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RuinString is adopted from
|
||||||
|
*
|
||||||
|
* Technical report 7.11.2016
|
||||||
|
* A Fresh Ruin & Recreate Implementation for the Capacitated Vehicle Routing Problem
|
||||||
|
* Jan Christiaens, Greet Vanden Berghe
|
||||||
|
* KU Leuven, Department of Computer Science, CODeS & iMinds-ITEC
|
||||||
|
* Gebr. De Smetstraat 1, 9000 Gent, Belgium, jan.christiaens@cs.kuleuven.be, greet.vandenberghe@cs.kuleuven.be
|
||||||
|
*
|
||||||
|
* https://lirias.kuleuven.be/bitstream/123456789/556398/1/asb_rr_2016.pdf
|
||||||
|
*
|
||||||
|
* @author stefan
|
||||||
|
*/
|
||||||
|
public final class RuinString extends AbstractRuinStrategy {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(RuinString.class);
|
||||||
|
|
||||||
|
private VehicleRoutingProblem vrp;
|
||||||
|
|
||||||
|
private JobNeighborhoods jobNeighborhoods;
|
||||||
|
|
||||||
|
private int kMin = 1;
|
||||||
|
|
||||||
|
private int kMax = 6;
|
||||||
|
|
||||||
|
private int lMin = 30;
|
||||||
|
|
||||||
|
private int lMax = 60;
|
||||||
|
|
||||||
|
public RuinString(VehicleRoutingProblem vrp, JobNeighborhoods jobNeighborhoods) {
|
||||||
|
super(vrp);
|
||||||
|
this.vrp = vrp;
|
||||||
|
this.jobNeighborhoods = jobNeighborhoods;
|
||||||
|
logger.debug("initialise {}", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNoRoutes(int kMin, int kMax) {
|
||||||
|
this.kMin = kMin;
|
||||||
|
this.kMax = kMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStringLength(int lMin, int lMax) {
|
||||||
|
this.lMin = lMin;
|
||||||
|
this.lMax = lMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[name=splitRuin]";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ruins the collection of vehicleRoutes, i.e. removes a share of jobs. First, it selects a job randomly. Second, it identifies its neighborhood. And finally, it removes
|
||||||
|
* the neighborhood plus the randomly selected job from the number of vehicleRoutes. All removed jobs are then returned as a collection.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes) {
|
||||||
|
if (vehicleRoutes.isEmpty() || vrp.getJobs().isEmpty()) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
int noStrings = kMin + random.nextInt((kMax - kMin));
|
||||||
|
noStrings = Math.min(noStrings, vehicleRoutes.size());
|
||||||
|
Set<Job> unassignedJobs = new HashSet<>();
|
||||||
|
Set<VehicleRoute> ruinedRoutes = new HashSet<>();
|
||||||
|
Job prevJob = RandomUtils.nextJob(vrp.getJobs().values(), random);
|
||||||
|
Iterator<Job> neighborhoodIterator = jobNeighborhoods.getNearestNeighborsIterator(kMax * lMax, prevJob);
|
||||||
|
while (neighborhoodIterator.hasNext() && ruinedRoutes.size() <= noStrings) {
|
||||||
|
if (!unassignedJobs.contains(prevJob)) {
|
||||||
|
VehicleRoute route = getRouteOf(prevJob, vehicleRoutes);
|
||||||
|
if (route != null && !ruinedRoutes.contains(route)) {
|
||||||
|
if (random.nextDouble() < .5) {
|
||||||
|
ruinRouteWithStringRuin(route, prevJob, unassignedJobs);
|
||||||
|
} else {
|
||||||
|
ruinRouteWithSplitStringRuin(route, prevJob, unassignedJobs);
|
||||||
|
}
|
||||||
|
ruinedRoutes.add(route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prevJob = neighborhoodIterator.next();
|
||||||
|
}
|
||||||
|
return unassignedJobs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private VehicleRoute getRouteOf(Job job, Collection<VehicleRoute> vehicleRoutes) {
|
||||||
|
for (VehicleRoute route : vehicleRoutes) {
|
||||||
|
if (route.getTourActivities().servesJob(job)) return route;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ruinRouteWithSplitStringRuin(VehicleRoute seedRoute, Job prevJob, Set<Job> unassignedJobs) {
|
||||||
|
int noActivities = seedRoute.getActivities().size();
|
||||||
|
int stringLength = lMin + random.nextInt(lMax - lMin);
|
||||||
|
stringLength = Math.min(stringLength, seedRoute.getActivities().size());
|
||||||
|
|
||||||
|
int preservedSubstringLength = StringUtil.determineSubstringLength(stringLength, noActivities, random);
|
||||||
|
|
||||||
|
List<AbstractActivity> acts = vrp.getActivities(prevJob);
|
||||||
|
AbstractActivity randomSeedAct = RandomUtils.nextItem(acts, random);
|
||||||
|
int seedIndex = 0;
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
for (TourActivity act : seedRoute.getActivities()) {
|
||||||
|
if (act.getIndex() == randomSeedAct.getIndex()) {
|
||||||
|
seedIndex = index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int totalStringLength = stringLength + preservedSubstringLength;
|
||||||
|
List<Integer> stringBounds = StringUtil.getLowerBoundsOfAllStrings(totalStringLength, seedIndex, noActivities);
|
||||||
|
if (stringBounds.isEmpty()) return;
|
||||||
|
int lowerBound = RandomUtils.nextItem(stringBounds, random);
|
||||||
|
|
||||||
|
List<Job> jobs2Remove = new ArrayList<>();
|
||||||
|
int startIndexOfPreservedSubstring = random.nextInt(stringLength);
|
||||||
|
int position = 0;
|
||||||
|
int noStringsInPreservedSubstring = 0;
|
||||||
|
boolean isPreservedSubstring = false;
|
||||||
|
for (int i = lowerBound; i < (lowerBound + totalStringLength); i++) {
|
||||||
|
if (position == startIndexOfPreservedSubstring) {
|
||||||
|
isPreservedSubstring = true;
|
||||||
|
}
|
||||||
|
if (noStringsInPreservedSubstring >= preservedSubstringLength) {
|
||||||
|
isPreservedSubstring = false;
|
||||||
|
}
|
||||||
|
if (!isPreservedSubstring) {
|
||||||
|
TourActivity act = seedRoute.getActivities().get(i);
|
||||||
|
if (act instanceof TourActivity.JobActivity) {
|
||||||
|
Job job = ((TourActivity.JobActivity) act).getJob();
|
||||||
|
if (vrp.getJobs().containsKey(job.getId())) {
|
||||||
|
jobs2Remove.add(job);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else noStringsInPreservedSubstring++;
|
||||||
|
position++;
|
||||||
|
}
|
||||||
|
for (Job job : jobs2Remove) {
|
||||||
|
removeJob(job, seedRoute);
|
||||||
|
unassignedJobs.add(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ruinRouteWithStringRuin(VehicleRoute seedRoute, Job prevJob, Set<Job> unassignedJobs) {
|
||||||
|
int stringLength = lMin + random.nextInt(lMax - lMin);
|
||||||
|
stringLength = Math.min(stringLength, seedRoute.getActivities().size());
|
||||||
|
List<AbstractActivity> acts = vrp.getActivities(prevJob);
|
||||||
|
AbstractActivity randomSeedAct = RandomUtils.nextItem(acts, random);
|
||||||
|
int seedIndex = 0;
|
||||||
|
int noActivities = seedRoute.getActivities().size();
|
||||||
|
int index = 0;
|
||||||
|
for (TourActivity act : seedRoute.getActivities()) {
|
||||||
|
if (act.getIndex() == randomSeedAct.getIndex()) {
|
||||||
|
seedIndex = index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
List<Integer> stringBounds = StringUtil.getLowerBoundsOfAllStrings(stringLength, seedIndex, noActivities);
|
||||||
|
if (stringBounds.isEmpty()) return;
|
||||||
|
int lowerBound = RandomUtils.nextItem(stringBounds, random);
|
||||||
|
List<Job> jobs2Remove = new ArrayList<>();
|
||||||
|
for (int i = lowerBound; i < (lowerBound + stringLength); i++) {
|
||||||
|
TourActivity act = seedRoute.getActivities().get(i);
|
||||||
|
if (act instanceof TourActivity.JobActivity) {
|
||||||
|
Job job = ((TourActivity.JobActivity) act).getJob();
|
||||||
|
if (vrp.getJobs().containsKey(job.getId())) {
|
||||||
|
jobs2Remove.add(job);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Job job : jobs2Remove) {
|
||||||
|
removeJob(job, seedRoute);
|
||||||
|
unassignedJobs.add(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* 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.ruin;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by schroeder on 13/01/17.
|
||||||
|
*/
|
||||||
|
class StringUtil {
|
||||||
|
|
||||||
|
static List<Integer> getLowerBoundsOfAllStrings(int length, int seedIndex, int routeLength) {
|
||||||
|
List<Integer> lowerBounds = new ArrayList<>();
|
||||||
|
for (int i = 1; i <= length; i++) {
|
||||||
|
int lower = seedIndex - (length - i);
|
||||||
|
int upper = seedIndex + (i - 1);
|
||||||
|
if (lower >= 0 && upper < routeLength) {
|
||||||
|
lowerBounds.add(lower);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lowerBounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int determineSubstringLength(int baseLength, int routeLength, Random random) {
|
||||||
|
if (baseLength == routeLength) return 0;
|
||||||
|
int substringLength = 1;
|
||||||
|
while (baseLength + substringLength < routeLength) {
|
||||||
|
if (random.nextDouble() < 0.01) {
|
||||||
|
return substringLength;
|
||||||
|
} else substringLength++;
|
||||||
|
}
|
||||||
|
return substringLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* 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.ruin;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by schroeder on 13/01/17.
|
||||||
|
*/
|
||||||
|
public class StringUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int stringLength = 4;
|
||||||
|
int seedIndex = 4;
|
||||||
|
int noActivities = 10;
|
||||||
|
List<Integer> bounds = StringUtil.getLowerBoundsOfAllStrings(stringLength, seedIndex, noActivities);
|
||||||
|
Assert.assertEquals(4, bounds.size());
|
||||||
|
Assert.assertEquals(1, (int) bounds.get(0));
|
||||||
|
Assert.assertEquals(2, (int) bounds.get(1));
|
||||||
|
Assert.assertEquals(3, (int) bounds.get(2));
|
||||||
|
Assert.assertEquals(4, (int) bounds.get(3));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
int stringLength = 4;
|
||||||
|
int seedIndex = 2;
|
||||||
|
int noActivities = 10;
|
||||||
|
List<Integer> bounds = StringUtil.getLowerBoundsOfAllStrings(stringLength, seedIndex, noActivities);
|
||||||
|
Assert.assertEquals(3, bounds.size());
|
||||||
|
Assert.assertEquals(0, (int) bounds.get(0));
|
||||||
|
Assert.assertEquals(1, (int) bounds.get(1));
|
||||||
|
Assert.assertEquals(2, (int) bounds.get(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test3() {
|
||||||
|
int stringLength = 4;
|
||||||
|
int seedIndex = 0;
|
||||||
|
int noActivities = 10;
|
||||||
|
List<Integer> bounds = StringUtil.getLowerBoundsOfAllStrings(stringLength, seedIndex, noActivities);
|
||||||
|
Assert.assertEquals(1, bounds.size());
|
||||||
|
Assert.assertEquals(0, (int) bounds.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test4() {
|
||||||
|
int stringLength = 4;
|
||||||
|
int seedIndex = 9;
|
||||||
|
int noActivities = 10;
|
||||||
|
List<Integer> bounds = StringUtil.getLowerBoundsOfAllStrings(stringLength, seedIndex, noActivities);
|
||||||
|
Assert.assertEquals(1, bounds.size());
|
||||||
|
Assert.assertEquals(6, (int) bounds.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test5() {
|
||||||
|
int stringLength = 4;
|
||||||
|
int seedIndex = 8;
|
||||||
|
int noActivities = 10;
|
||||||
|
List<Integer> bounds = StringUtil.getLowerBoundsOfAllStrings(stringLength, seedIndex, noActivities);
|
||||||
|
Assert.assertEquals(2, bounds.size());
|
||||||
|
Assert.assertEquals(5, (int) bounds.get(0));
|
||||||
|
Assert.assertEquals(6, (int) bounds.get(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
56
jsprit-examples/input/p01_mod
Normal file
56
jsprit-examples/input/p01_mod
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
2 4 50 4
|
||||||
|
0 2000
|
||||||
|
1 37 52 0 7 1 4 1 2 4 8
|
||||||
|
2 49 49 0 30 1 4 1 2 4 8
|
||||||
|
3 52 64 0 16 1 4 1 2 4 8
|
||||||
|
4 20 26 0 9 1 4 1 2 4 8
|
||||||
|
5 40 30 0 21 1 4 1 2 4 8
|
||||||
|
6 21 47 0 15 1 4 1 2 4 8
|
||||||
|
7 17 63 0 19 1 4 1 2 4 8
|
||||||
|
8 31 62 0 23 1 4 1 2 4 8
|
||||||
|
9 52 33 0 11 1 4 1 2 4 8
|
||||||
|
10 51 21 0 5 1 4 1 2 4 8
|
||||||
|
11 42 41 0 19 1 4 1 2 4 8
|
||||||
|
12 31 32 0 29 1 4 1 2 4 8
|
||||||
|
13 5 25 0 23 1 4 1 2 4 8
|
||||||
|
14 12 42 0 21 1 4 1 2 4 8
|
||||||
|
15 36 16 0 10 1 4 1 2 4 8
|
||||||
|
16 52 41 0 15 1 4 1 2 4 8
|
||||||
|
17 27 23 0 3 1 4 1 2 4 8
|
||||||
|
18 17 33 0 41 1 4 1 2 4 8
|
||||||
|
19 13 13 0 9 1 4 1 2 4 8
|
||||||
|
20 57 58 0 28 1 4 1 2 4 8
|
||||||
|
21 62 42 0 8 1 4 1 2 4 8
|
||||||
|
22 42 57 0 8 1 4 1 2 4 8
|
||||||
|
23 16 57 0 16 1 4 1 2 4 8
|
||||||
|
24 8 52 0 10 1 4 1 2 4 8
|
||||||
|
25 7 38 0 28 1 4 1 2 4 8
|
||||||
|
26 27 68 0 7 1 4 1 2 4 8
|
||||||
|
27 30 48 0 15 1 4 1 2 4 8
|
||||||
|
28 43 67 0 14 1 4 1 2 4 8
|
||||||
|
29 58 48 0 6 1 4 1 2 4 8
|
||||||
|
30 58 27 0 19 1 4 1 2 4 8
|
||||||
|
31 37 69 0 11 1 4 1 2 4 8
|
||||||
|
32 38 46 0 12 1 4 1 2 4 8
|
||||||
|
33 46 10 0 23 1 4 1 2 4 8
|
||||||
|
34 61 33 0 26 1 4 1 2 4 8
|
||||||
|
35 62 63 0 17 1 4 1 2 4 8
|
||||||
|
36 63 69 0 6 1 4 1 2 4 8
|
||||||
|
37 32 22 0 9 1 4 1 2 4 8
|
||||||
|
38 45 35 0 15 1 4 1 2 4 8
|
||||||
|
39 59 15 0 14 1 4 1 2 4 8
|
||||||
|
40 5 6 0 7 1 4 1 2 4 8
|
||||||
|
41 10 17 0 27 1 4 1 2 4 8
|
||||||
|
42 21 10 0 13 1 4 1 2 4 8
|
||||||
|
43 5 64 0 11 1 4 1 2 4 8
|
||||||
|
44 30 15 0 16 1 4 1 2 4 8
|
||||||
|
45 39 10 0 10 1 4 1 2 4 8
|
||||||
|
46 32 39 0 5 1 4 1 2 4 8
|
||||||
|
47 25 32 0 25 1 4 1 2 4 8
|
||||||
|
48 25 55 0 17 1 4 1 2 4 8
|
||||||
|
49 48 28 0 18 1 4 1 2 4 8
|
||||||
|
50 56 37 0 10 1 4 1 2 4 8
|
||||||
|
51 20 20 0 0 0 0
|
||||||
|
52 30 40 0 0 0 0
|
||||||
|
53 50 30 0 0 0 0
|
||||||
|
54 60 50 0 0 0 0
|
||||||
|
|
@ -20,7 +20,6 @@ package com.graphhopper.jsprit.examples;
|
||||||
|
|
||||||
|
|
||||||
import com.graphhopper.jsprit.analysis.toolbox.AlgorithmEventsRecorder;
|
import com.graphhopper.jsprit.analysis.toolbox.AlgorithmEventsRecorder;
|
||||||
import com.graphhopper.jsprit.analysis.toolbox.AlgorithmEventsViewer;
|
|
||||||
import com.graphhopper.jsprit.core.algorithm.PrettyAlgorithmBuilder;
|
import com.graphhopper.jsprit.core.algorithm.PrettyAlgorithmBuilder;
|
||||||
import com.graphhopper.jsprit.core.algorithm.SearchStrategy;
|
import com.graphhopper.jsprit.core.algorithm.SearchStrategy;
|
||||||
import com.graphhopper.jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
import com.graphhopper.jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
||||||
|
|
@ -116,17 +115,18 @@ public class BuildAlgorithmFromScratch {
|
||||||
final VehicleRoutingProblem vrp = vrpBuilder.build();
|
final VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
|
|
||||||
VehicleRoutingAlgorithm vra = createAlgorithm(vrp);
|
VehicleRoutingAlgorithm vra = createAlgorithm(vrp);
|
||||||
vra.setMaxIterations(100);
|
vra.setMaxIterations(2000);
|
||||||
AlgorithmEventsRecorder eventsRecorder = new AlgorithmEventsRecorder(vrp, "output/events.dgs.gz");
|
AlgorithmEventsRecorder eventsRecorder = new AlgorithmEventsRecorder(vrp, "output/events.dgs.gz");
|
||||||
eventsRecorder.setRecordingRange(90, 100);
|
eventsRecorder.setRecordingRange(90, 100);
|
||||||
vra.addListener(eventsRecorder);
|
vra.addListener(eventsRecorder);
|
||||||
|
|
||||||
VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions());
|
VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions());
|
||||||
SolutionPrinter.print(vrp, solution, SolutionPrinter.Print.VERBOSE);
|
SolutionPrinter.print(vrp, solution, SolutionPrinter.Print.VERBOSE);
|
||||||
AlgorithmEventsViewer viewer = new AlgorithmEventsViewer();
|
|
||||||
viewer.setRuinDelay(3);
|
// AlgorithmEventsViewer viewer = new AlgorithmEventsViewer();
|
||||||
viewer.setRecreationDelay(1);
|
// viewer.setRuinDelay(3);
|
||||||
viewer.display("output/events.dgs.gz");
|
// viewer.setRecreationDelay(1);
|
||||||
|
// viewer.display("output/events.dgs.gz");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,10 +146,11 @@ public class BuildAlgorithmFromScratch {
|
||||||
//regret insertion
|
//regret insertion
|
||||||
InsertionBuilder iBuilder = new InsertionBuilder(vrp, fleetManager, stateManager, constraintManager);
|
InsertionBuilder iBuilder = new InsertionBuilder(vrp, fleetManager, stateManager, constraintManager);
|
||||||
iBuilder.setInsertionStrategy(InsertionBuilder.Strategy.REGRET);
|
iBuilder.setInsertionStrategy(InsertionBuilder.Strategy.REGRET);
|
||||||
|
iBuilder.setFastRegret(true);
|
||||||
RegretInsertionFast regret = (RegretInsertionFast) iBuilder.build();
|
RegretInsertionFast regret = (RegretInsertionFast) iBuilder.build();
|
||||||
DefaultScorer scoringFunction = new DefaultScorer(vrp);
|
DefaultScorer scoringFunction = new DefaultScorer(vrp);
|
||||||
scoringFunction.setDepotDistanceParam(0.2);
|
scoringFunction.setDepotDistanceParam(0.0);
|
||||||
scoringFunction.setTimeWindowParam(-.2);
|
scoringFunction.setTimeWindowParam(0.0);
|
||||||
regret.setScoringFunction(scoringFunction);
|
regret.setScoringFunction(scoringFunction);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue