mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
refine string removal
This commit is contained in:
parent
142c3beff6
commit
25fe083809
8 changed files with 960 additions and 264 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;
|
||||||
|
|
||||||
|
|
@ -178,6 +180,10 @@ 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(), ".5");
|
||||||
|
defaults.put(Strategy.STRING_REGRET.toString(), ".5");
|
||||||
|
|
||||||
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.");
|
||||||
|
|
@ -472,6 +478,9 @@ public class Jsprit {
|
||||||
random)
|
random)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final RuinString stringRuin = new RuinString(vrp, jobNeighborhoods);
|
||||||
|
stringRuin.setRandom(random);
|
||||||
|
|
||||||
AbstractInsertionStrategy regret;
|
AbstractInsertionStrategy regret;
|
||||||
final ScoringFunction scorer;
|
final ScoringFunction scorer;
|
||||||
|
|
||||||
|
|
@ -592,6 +601,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 +619,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,231 @@
|
||||||
|
/*
|
||||||
|
* 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.algorithm.ruin.distance.JobDistance;
|
||||||
|
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.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RuinStrategy that ruins the neighborhood of a randomly selected job. The size and the structure of the neighborhood is defined by
|
||||||
|
* the share of jobs to be removed and the distance between jobs (where distance not necessarily mean Euclidean distance but an arbitrary
|
||||||
|
* measure).
|
||||||
|
*
|
||||||
|
* @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 = 1;
|
||||||
|
|
||||||
|
private int Lmax = 40;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs RuinRadial.
|
||||||
|
*
|
||||||
|
* @param vrp
|
||||||
|
* @param jobDistance i.e. a measure to define the distance between two jobs and whether they are located close or distant to eachother
|
||||||
|
* @param Kmin
|
||||||
|
* @param Kmax
|
||||||
|
* @param Lmin
|
||||||
|
* @param Lmax
|
||||||
|
*/
|
||||||
|
public RuinString(VehicleRoutingProblem vrp, JobDistance jobDistance, int Kmin, int Kmax, int Lmin, int Lmax) {
|
||||||
|
super(vrp);
|
||||||
|
this.vrp = vrp;
|
||||||
|
JobNeighborhoodsImplWithCapRestriction jobNeighborhoodsImpl = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, Kmax * Lmax);
|
||||||
|
jobNeighborhoodsImpl.initialise();
|
||||||
|
jobNeighborhoods = jobNeighborhoodsImpl;
|
||||||
|
this.Kmin = Kmin;
|
||||||
|
this.Kmax = Kmax;
|
||||||
|
this.Lmin = Lmin;
|
||||||
|
this.Lmax = Lmax;
|
||||||
|
logger.debug("initialise {}", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RuinString(VehicleRoutingProblem vrp, JobDistance jobDistance) {
|
||||||
|
super(vrp);
|
||||||
|
this.vrp = vrp;
|
||||||
|
JobNeighborhoodsImplWithCapRestriction jobNeighborhoodsImpl = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, Kmax * Lmax);
|
||||||
|
jobNeighborhoodsImpl.initialise();
|
||||||
|
jobNeighborhoods = jobNeighborhoodsImpl;
|
||||||
|
logger.debug("initialise {}", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RuinString(VehicleRoutingProblem vrp, JobNeighborhoods jobNeighborhoods) {
|
||||||
|
super(vrp);
|
||||||
|
this.vrp = vrp;
|
||||||
|
this.jobNeighborhoods = jobNeighborhoods;
|
||||||
|
logger.debug("initialise {}", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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
|
||||||
|
|
@ -1,254 +1,254 @@
|
||||||
2 14 249 2
|
2 14 249 2
|
||||||
310 500
|
310 500
|
||||||
310 500
|
310 500
|
||||||
1 -99 -97 0 6 1 2 1 2
|
1 -99 -97 0 6 1 2 1 2
|
||||||
2 -59 50 0 72 1 2 1 2
|
2 -59 50 0 72 1 2 1 2
|
||||||
3 0 14 0 93 1 2 1 2
|
3 0 14 0 93 1 2 1 2
|
||||||
4 -17 -66 0 28 1 2 1 2
|
4 -17 -66 0 28 1 2 1 2
|
||||||
5 -69 -19 0 5 1 2 1 2
|
5 -69 -19 0 5 1 2 1 2
|
||||||
6 31 12 0 43 1 2 1 2
|
6 31 12 0 43 1 2 1 2
|
||||||
7 5 -41 0 1 1 2 1 2
|
7 5 -41 0 1 1 2 1 2
|
||||||
8 -12 10 0 36 1 2 1 2
|
8 -12 10 0 36 1 2 1 2
|
||||||
9 -64 70 0 53 1 2 1 2
|
9 -64 70 0 53 1 2 1 2
|
||||||
10 -12 85 0 63 1 2 1 2
|
10 -12 85 0 63 1 2 1 2
|
||||||
11 -18 64 0 25 1 2 1 2
|
11 -18 64 0 25 1 2 1 2
|
||||||
12 -77 -16 0 50 1 2 1 2
|
12 -77 -16 0 50 1 2 1 2
|
||||||
13 -53 88 0 57 1 2 1 2
|
13 -53 88 0 57 1 2 1 2
|
||||||
14 83 -24 0 1 1 2 1 2
|
14 83 -24 0 1 1 2 1 2
|
||||||
15 24 41 0 66 1 2 1 2
|
15 24 41 0 66 1 2 1 2
|
||||||
16 17 21 0 37 1 2 1 2
|
16 17 21 0 37 1 2 1 2
|
||||||
17 42 96 0 51 1 2 1 2
|
17 42 96 0 51 1 2 1 2
|
||||||
18 -65 0 0 47 1 2 1 2
|
18 -65 0 0 47 1 2 1 2
|
||||||
19 -47 -26 0 88 1 2 1 2
|
19 -47 -26 0 88 1 2 1 2
|
||||||
20 85 36 0 75 1 2 1 2
|
20 85 36 0 75 1 2 1 2
|
||||||
21 -35 -54 0 48 1 2 1 2
|
21 -35 -54 0 48 1 2 1 2
|
||||||
22 54 -21 0 40 1 2 1 2
|
22 54 -21 0 40 1 2 1 2
|
||||||
23 64 -17 0 8 1 2 1 2
|
23 64 -17 0 8 1 2 1 2
|
||||||
24 55 89 0 69 1 2 1 2
|
24 55 89 0 69 1 2 1 2
|
||||||
25 17 -25 0 93 1 2 1 2
|
25 17 -25 0 93 1 2 1 2
|
||||||
26 -61 66 0 29 1 2 1 2
|
26 -61 66 0 29 1 2 1 2
|
||||||
27 -61 26 0 5 1 2 1 2
|
27 -61 26 0 5 1 2 1 2
|
||||||
28 17 -72 0 53 1 2 1 2
|
28 17 -72 0 53 1 2 1 2
|
||||||
29 79 38 0 8 1 2 1 2
|
29 79 38 0 8 1 2 1 2
|
||||||
30 -62 -2 0 24 1 2 1 2
|
30 -62 -2 0 24 1 2 1 2
|
||||||
31 -90 -68 0 53 1 2 1 2
|
31 -90 -68 0 53 1 2 1 2
|
||||||
32 52 66 0 13 1 2 1 2
|
32 52 66 0 13 1 2 1 2
|
||||||
33 -54 -50 0 47 1 2 1 2
|
33 -54 -50 0 47 1 2 1 2
|
||||||
34 8 -84 0 57 1 2 1 2
|
34 8 -84 0 57 1 2 1 2
|
||||||
35 37 -90 0 9 1 2 1 2
|
35 37 -90 0 9 1 2 1 2
|
||||||
36 -83 49 0 74 1 2 1 2
|
36 -83 49 0 74 1 2 1 2
|
||||||
37 35 -1 0 83 1 2 1 2
|
37 35 -1 0 83 1 2 1 2
|
||||||
38 7 59 0 96 1 2 1 2
|
38 7 59 0 96 1 2 1 2
|
||||||
39 12 48 0 42 1 2 1 2
|
39 12 48 0 42 1 2 1 2
|
||||||
40 57 95 0 80 1 2 1 2
|
40 57 95 0 80 1 2 1 2
|
||||||
41 92 28 0 22 1 2 1 2
|
41 92 28 0 22 1 2 1 2
|
||||||
42 -3 97 0 56 1 2 1 2
|
42 -3 97 0 56 1 2 1 2
|
||||||
43 -7 52 0 43 1 2 1 2
|
43 -7 52 0 43 1 2 1 2
|
||||||
44 42 -15 0 12 1 2 1 2
|
44 42 -15 0 12 1 2 1 2
|
||||||
45 77 -43 0 73 1 2 1 2
|
45 77 -43 0 73 1 2 1 2
|
||||||
46 59 -49 0 32 1 2 1 2
|
46 59 -49 0 32 1 2 1 2
|
||||||
47 25 91 0 8 1 2 1 2
|
47 25 91 0 8 1 2 1 2
|
||||||
48 69 -19 0 79 1 2 1 2
|
48 69 -19 0 79 1 2 1 2
|
||||||
49 -82 -14 0 79 1 2 1 2
|
49 -82 -14 0 79 1 2 1 2
|
||||||
50 74 -70 0 4 1 2 1 2
|
50 74 -70 0 4 1 2 1 2
|
||||||
51 69 59 0 14 1 2 1 2
|
51 69 59 0 14 1 2 1 2
|
||||||
52 29 33 0 17 1 2 1 2
|
52 29 33 0 17 1 2 1 2
|
||||||
53 -97 9 0 19 1 2 1 2
|
53 -97 9 0 19 1 2 1 2
|
||||||
54 -58 9 0 44 1 2 1 2
|
54 -58 9 0 44 1 2 1 2
|
||||||
55 28 93 0 5 1 2 1 2
|
55 28 93 0 5 1 2 1 2
|
||||||
56 7 73 0 37 1 2 1 2
|
56 7 73 0 37 1 2 1 2
|
||||||
57 -28 73 0 100 1 2 1 2
|
57 -28 73 0 100 1 2 1 2
|
||||||
58 -76 55 0 62 1 2 1 2
|
58 -76 55 0 62 1 2 1 2
|
||||||
59 41 42 0 90 1 2 1 2
|
59 41 42 0 90 1 2 1 2
|
||||||
60 92 40 0 57 1 2 1 2
|
60 92 40 0 57 1 2 1 2
|
||||||
61 -84 -29 0 44 1 2 1 2
|
61 -84 -29 0 44 1 2 1 2
|
||||||
62 -12 42 0 37 1 2 1 2
|
62 -12 42 0 37 1 2 1 2
|
||||||
63 51 -45 0 80 1 2 1 2
|
63 51 -45 0 80 1 2 1 2
|
||||||
64 -37 46 0 60 1 2 1 2
|
64 -37 46 0 60 1 2 1 2
|
||||||
65 -97 35 0 95 1 2 1 2
|
65 -97 35 0 95 1 2 1 2
|
||||||
66 14 89 0 56 1 2 1 2
|
66 14 89 0 56 1 2 1 2
|
||||||
67 60 58 0 56 1 2 1 2
|
67 60 58 0 56 1 2 1 2
|
||||||
68 -63 -75 0 9 1 2 1 2
|
68 -63 -75 0 9 1 2 1 2
|
||||||
69 -18 34 0 39 1 2 1 2
|
69 -18 34 0 39 1 2 1 2
|
||||||
70 -46 -82 0 15 1 2 1 2
|
70 -46 -82 0 15 1 2 1 2
|
||||||
71 -86 -79 0 4 1 2 1 2
|
71 -86 -79 0 4 1 2 1 2
|
||||||
72 -43 -30 0 58 1 2 1 2
|
72 -43 -30 0 58 1 2 1 2
|
||||||
73 -44 7 0 73 1 2 1 2
|
73 -44 7 0 73 1 2 1 2
|
||||||
74 -3 -20 0 5 1 2 1 2
|
74 -3 -20 0 5 1 2 1 2
|
||||||
75 36 41 0 12 1 2 1 2
|
75 36 41 0 12 1 2 1 2
|
||||||
76 -30 -94 0 3 1 2 1 2
|
76 -30 -94 0 3 1 2 1 2
|
||||||
77 79 -62 0 8 1 2 1 2
|
77 79 -62 0 8 1 2 1 2
|
||||||
78 51 70 0 31 1 2 1 2
|
78 51 70 0 31 1 2 1 2
|
||||||
79 -61 -26 0 48 1 2 1 2
|
79 -61 -26 0 48 1 2 1 2
|
||||||
80 6 94 0 3 1 2 1 2
|
80 6 94 0 3 1 2 1 2
|
||||||
81 -19 -62 0 52 1 2 1 2
|
81 -19 -62 0 52 1 2 1 2
|
||||||
82 -20 51 0 99 1 2 1 2
|
82 -20 51 0 99 1 2 1 2
|
||||||
83 -81 37 0 29 1 2 1 2
|
83 -81 37 0 29 1 2 1 2
|
||||||
84 7 31 0 12 1 2 1 2
|
84 7 31 0 12 1 2 1 2
|
||||||
85 52 12 0 50 1 2 1 2
|
85 52 12 0 50 1 2 1 2
|
||||||
86 83 -91 0 98 1 2 1 2
|
86 83 -91 0 98 1 2 1 2
|
||||||
87 -7 -92 0 4 1 2 1 2
|
87 -7 -92 0 4 1 2 1 2
|
||||||
88 82 -74 0 56 1 2 1 2
|
88 82 -74 0 56 1 2 1 2
|
||||||
89 -70 85 0 24 1 2 1 2
|
89 -70 85 0 24 1 2 1 2
|
||||||
90 -83 -30 0 33 1 2 1 2
|
90 -83 -30 0 33 1 2 1 2
|
||||||
91 71 -61 0 45 1 2 1 2
|
91 71 -61 0 45 1 2 1 2
|
||||||
92 85 11 0 98 1 2 1 2
|
92 85 11 0 98 1 2 1 2
|
||||||
93 66 -48 0 4 1 2 1 2
|
93 66 -48 0 4 1 2 1 2
|
||||||
94 78 -87 0 36 1 2 1 2
|
94 78 -87 0 36 1 2 1 2
|
||||||
95 9 -79 0 72 1 2 1 2
|
95 9 -79 0 72 1 2 1 2
|
||||||
96 -36 4 0 26 1 2 1 2
|
96 -36 4 0 26 1 2 1 2
|
||||||
97 66 39 0 71 1 2 1 2
|
97 66 39 0 71 1 2 1 2
|
||||||
98 92 -17 0 84 1 2 1 2
|
98 92 -17 0 84 1 2 1 2
|
||||||
99 -46 -79 0 21 1 2 1 2
|
99 -46 -79 0 21 1 2 1 2
|
||||||
100 -30 -63 0 99 1 2 1 2
|
100 -30 -63 0 99 1 2 1 2
|
||||||
101 -42 63 0 33 1 2 1 2
|
101 -42 63 0 33 1 2 1 2
|
||||||
102 20 42 0 84 1 2 1 2
|
102 20 42 0 84 1 2 1 2
|
||||||
103 15 98 0 74 1 2 1 2
|
103 15 98 0 74 1 2 1 2
|
||||||
104 1 -17 0 93 1 2 1 2
|
104 1 -17 0 93 1 2 1 2
|
||||||
105 64 20 0 25 1 2 1 2
|
105 64 20 0 25 1 2 1 2
|
||||||
106 -96 85 0 39 1 2 1 2
|
106 -96 85 0 39 1 2 1 2
|
||||||
107 93 -29 0 42 1 2 1 2
|
107 93 -29 0 42 1 2 1 2
|
||||||
108 -40 -84 0 77 1 2 1 2
|
108 -40 -84 0 77 1 2 1 2
|
||||||
109 86 35 0 68 1 2 1 2
|
109 86 35 0 68 1 2 1 2
|
||||||
110 91 36 0 50 1 2 1 2
|
110 91 36 0 50 1 2 1 2
|
||||||
111 62 -8 0 42 1 2 1 2
|
111 62 -8 0 42 1 2 1 2
|
||||||
112 -24 4 0 71 1 2 1 2
|
112 -24 4 0 71 1 2 1 2
|
||||||
113 11 96 0 85 1 2 1 2
|
113 11 96 0 85 1 2 1 2
|
||||||
114 -53 62 0 78 1 2 1 2
|
114 -53 62 0 78 1 2 1 2
|
||||||
115 -28 -71 0 64 1 2 1 2
|
115 -28 -71 0 64 1 2 1 2
|
||||||
116 7 -4 0 5 1 2 1 2
|
116 7 -4 0 5 1 2 1 2
|
||||||
117 95 -9 0 93 1 2 1 2
|
117 95 -9 0 93 1 2 1 2
|
||||||
118 -3 17 0 18 1 2 1 2
|
118 -3 17 0 18 1 2 1 2
|
||||||
119 53 -90 0 38 1 2 1 2
|
119 53 -90 0 38 1 2 1 2
|
||||||
120 58 -19 0 29 1 2 1 2
|
120 58 -19 0 29 1 2 1 2
|
||||||
121 -83 84 0 81 1 2 1 2
|
121 -83 84 0 81 1 2 1 2
|
||||||
122 -1 49 0 4 1 2 1 2
|
122 -1 49 0 4 1 2 1 2
|
||||||
123 -4 17 0 23 1 2 1 2
|
123 -4 17 0 23 1 2 1 2
|
||||||
124 -82 -3 0 11 1 2 1 2
|
124 -82 -3 0 11 1 2 1 2
|
||||||
125 -43 47 0 86 1 2 1 2
|
125 -43 47 0 86 1 2 1 2
|
||||||
126 6 -6 0 2 1 2 1 2
|
126 6 -6 0 2 1 2 1 2
|
||||||
127 70 99 0 31 1 2 1 2
|
127 70 99 0 31 1 2 1 2
|
||||||
128 68 -29 0 54 1 2 1 2
|
128 68 -29 0 54 1 2 1 2
|
||||||
129 -94 -30 0 87 1 2 1 2
|
129 -94 -30 0 87 1 2 1 2
|
||||||
130 -94 -20 0 17 1 2 1 2
|
130 -94 -20 0 17 1 2 1 2
|
||||||
131 -21 77 0 81 1 2 1 2
|
131 -21 77 0 81 1 2 1 2
|
||||||
132 64 37 0 72 1 2 1 2
|
132 64 37 0 72 1 2 1 2
|
||||||
133 -70 -19 0 10 1 2 1 2
|
133 -70 -19 0 10 1 2 1 2
|
||||||
134 88 65 0 50 1 2 1 2
|
134 88 65 0 50 1 2 1 2
|
||||||
135 2 29 0 25 1 2 1 2
|
135 2 29 0 25 1 2 1 2
|
||||||
136 33 57 0 71 1 2 1 2
|
136 33 57 0 71 1 2 1 2
|
||||||
137 -70 6 0 85 1 2 1 2
|
137 -70 6 0 85 1 2 1 2
|
||||||
138 -38 -56 0 51 1 2 1 2
|
138 -38 -56 0 51 1 2 1 2
|
||||||
139 -80 -95 0 29 1 2 1 2
|
139 -80 -95 0 29 1 2 1 2
|
||||||
140 -5 -39 0 55 1 2 1 2
|
140 -5 -39 0 55 1 2 1 2
|
||||||
141 8 -22 0 45 1 2 1 2
|
141 8 -22 0 45 1 2 1 2
|
||||||
142 -61 -76 0 100 1 2 1 2
|
142 -61 -76 0 100 1 2 1 2
|
||||||
143 76 -22 0 38 1 2 1 2
|
143 76 -22 0 38 1 2 1 2
|
||||||
144 49 -71 0 11 1 2 1 2
|
144 49 -71 0 11 1 2 1 2
|
||||||
145 -30 -68 0 82 1 2 1 2
|
145 -30 -68 0 82 1 2 1 2
|
||||||
146 1 34 0 50 1 2 1 2
|
146 1 34 0 50 1 2 1 2
|
||||||
147 77 79 0 39 1 2 1 2
|
147 77 79 0 39 1 2 1 2
|
||||||
148 -58 64 0 6 1 2 1 2
|
148 -58 64 0 6 1 2 1 2
|
||||||
149 82 -97 0 87 1 2 1 2
|
149 82 -97 0 87 1 2 1 2
|
||||||
150 -80 55 0 83 1 2 1 2
|
150 -80 55 0 83 1 2 1 2
|
||||||
151 81 -86 0 22 1 2 1 2
|
151 81 -86 0 22 1 2 1 2
|
||||||
152 39 -49 0 24 1 2 1 2
|
152 39 -49 0 24 1 2 1 2
|
||||||
153 -67 72 0 69 1 2 1 2
|
153 -67 72 0 69 1 2 1 2
|
||||||
154 -25 -89 0 97 1 2 1 2
|
154 -25 -89 0 97 1 2 1 2
|
||||||
155 -44 -95 0 65 1 2 1 2
|
155 -44 -95 0 65 1 2 1 2
|
||||||
156 32 -68 0 97 1 2 1 2
|
156 32 -68 0 97 1 2 1 2
|
||||||
157 -17 49 0 79 1 2 1 2
|
157 -17 49 0 79 1 2 1 2
|
||||||
158 93 49 0 79 1 2 1 2
|
158 93 49 0 79 1 2 1 2
|
||||||
159 99 81 0 46 1 2 1 2
|
159 99 81 0 46 1 2 1 2
|
||||||
160 10 -49 0 52 1 2 1 2
|
160 10 -49 0 52 1 2 1 2
|
||||||
161 63 -41 0 39 1 2 1 2
|
161 63 -41 0 39 1 2 1 2
|
||||||
162 38 39 0 94 1 2 1 2
|
162 38 39 0 94 1 2 1 2
|
||||||
163 -28 39 0 97 1 2 1 2
|
163 -28 39 0 97 1 2 1 2
|
||||||
164 -2 -47 0 18 1 2 1 2
|
164 -2 -47 0 18 1 2 1 2
|
||||||
165 38 8 0 3 1 2 1 2
|
165 38 8 0 3 1 2 1 2
|
||||||
166 -42 -6 0 23 1 2 1 2
|
166 -42 -6 0 23 1 2 1 2
|
||||||
167 -67 88 0 19 1 2 1 2
|
167 -67 88 0 19 1 2 1 2
|
||||||
168 19 93 0 40 1 2 1 2
|
168 19 93 0 40 1 2 1 2
|
||||||
169 40 27 0 49 1 2 1 2
|
169 40 27 0 49 1 2 1 2
|
||||||
170 -61 56 0 96 1 2 1 2
|
170 -61 56 0 96 1 2 1 2
|
||||||
171 43 33 0 58 1 2 1 2
|
171 43 33 0 58 1 2 1 2
|
||||||
172 -18 -39 0 15 1 2 1 2
|
172 -18 -39 0 15 1 2 1 2
|
||||||
173 -69 19 0 21 1 2 1 2
|
173 -69 19 0 21 1 2 1 2
|
||||||
174 75 -18 0 56 1 2 1 2
|
174 75 -18 0 56 1 2 1 2
|
||||||
175 31 85 0 67 1 2 1 2
|
175 31 85 0 67 1 2 1 2
|
||||||
176 25 58 0 10 1 2 1 2
|
176 25 58 0 10 1 2 1 2
|
||||||
177 -16 36 0 36 1 2 1 2
|
177 -16 36 0 36 1 2 1 2
|
||||||
178 91 15 0 84 1 2 1 2
|
178 91 15 0 84 1 2 1 2
|
||||||
179 60 -39 0 59 1 2 1 2
|
179 60 -39 0 59 1 2 1 2
|
||||||
180 49 -47 0 85 1 2 1 2
|
180 49 -47 0 85 1 2 1 2
|
||||||
181 42 33 0 60 1 2 1 2
|
181 42 33 0 60 1 2 1 2
|
||||||
182 16 -81 0 33 1 2 1 2
|
182 16 -81 0 33 1 2 1 2
|
||||||
183 -78 53 0 62 1 2 1 2
|
183 -78 53 0 62 1 2 1 2
|
||||||
184 53 -80 0 70 1 2 1 2
|
184 53 -80 0 70 1 2 1 2
|
||||||
185 -46 -26 0 79 1 2 1 2
|
185 -46 -26 0 79 1 2 1 2
|
||||||
186 -25 -54 0 98 1 2 1 2
|
186 -25 -54 0 98 1 2 1 2
|
||||||
187 69 -46 0 99 1 2 1 2
|
187 69 -46 0 99 1 2 1 2
|
||||||
188 0 -78 0 18 1 2 1 2
|
188 0 -78 0 18 1 2 1 2
|
||||||
189 -84 74 0 55 1 2 1 2
|
189 -84 74 0 55 1 2 1 2
|
||||||
190 -16 16 0 75 1 2 1 2
|
190 -16 16 0 75 1 2 1 2
|
||||||
191 -63 -14 0 94 1 2 1 2
|
191 -63 -14 0 94 1 2 1 2
|
||||||
192 51 -77 0 89 1 2 1 2
|
192 51 -77 0 89 1 2 1 2
|
||||||
193 -39 61 0 13 1 2 1 2
|
193 -39 61 0 13 1 2 1 2
|
||||||
194 5 97 0 19 1 2 1 2
|
194 5 97 0 19 1 2 1 2
|
||||||
195 -55 39 0 19 1 2 1 2
|
195 -55 39 0 19 1 2 1 2
|
||||||
196 70 -14 0 90 1 2 1 2
|
196 70 -14 0 90 1 2 1 2
|
||||||
197 0 95 0 35 1 2 1 2
|
197 0 95 0 35 1 2 1 2
|
||||||
198 -45 7 0 76 1 2 1 2
|
198 -45 7 0 76 1 2 1 2
|
||||||
199 38 -24 0 3 1 2 1 2
|
199 38 -24 0 3 1 2 1 2
|
||||||
200 50 -37 0 11 1 2 1 2
|
200 50 -37 0 11 1 2 1 2
|
||||||
201 59 71 0 98 1 2 1 2
|
201 59 71 0 98 1 2 1 2
|
||||||
202 -73 -96 0 92 1 2 1 2
|
202 -73 -96 0 92 1 2 1 2
|
||||||
203 -29 72 0 1 1 2 1 2
|
203 -29 72 0 1 1 2 1 2
|
||||||
204 -47 12 0 2 1 2 1 2
|
204 -47 12 0 2 1 2 1 2
|
||||||
205 -88 -61 0 63 1 2 1 2
|
205 -88 -61 0 63 1 2 1 2
|
||||||
206 -88 36 0 57 1 2 1 2
|
206 -88 36 0 57 1 2 1 2
|
||||||
207 -46 -3 0 50 1 2 1 2
|
207 -46 -3 0 50 1 2 1 2
|
||||||
208 26 -37 0 19 1 2 1 2
|
208 26 -37 0 19 1 2 1 2
|
||||||
209 -39 -67 0 24 1 2 1 2
|
209 -39 -67 0 24 1 2 1 2
|
||||||
210 92 27 0 14 1 2 1 2
|
210 92 27 0 14 1 2 1 2
|
||||||
211 -80 -31 0 18 1 2 1 2
|
211 -80 -31 0 18 1 2 1 2
|
||||||
212 93 -50 0 77 1 2 1 2
|
212 93 -50 0 77 1 2 1 2
|
||||||
213 -20 -5 0 28 1 2 1 2
|
213 -20 -5 0 28 1 2 1 2
|
||||||
214 -22 73 0 72 1 2 1 2
|
214 -22 73 0 72 1 2 1 2
|
||||||
215 -4 -7 0 49 1 2 1 2
|
215 -4 -7 0 49 1 2 1 2
|
||||||
216 54 -48 0 58 1 2 1 2
|
216 54 -48 0 58 1 2 1 2
|
||||||
217 -70 39 0 84 1 2 1 2
|
217 -70 39 0 84 1 2 1 2
|
||||||
218 54 -82 0 58 1 2 1 2
|
218 54 -82 0 58 1 2 1 2
|
||||||
219 29 41 0 41 1 2 1 2
|
219 29 41 0 41 1 2 1 2
|
||||||
220 -87 51 0 98 1 2 1 2
|
220 -87 51 0 98 1 2 1 2
|
||||||
221 -96 -36 0 77 1 2 1 2
|
221 -96 -36 0 77 1 2 1 2
|
||||||
222 49 8 0 57 1 2 1 2
|
222 49 8 0 57 1 2 1 2
|
||||||
223 -5 54 0 39 1 2 1 2
|
223 -5 54 0 39 1 2 1 2
|
||||||
224 -26 43 0 99 1 2 1 2
|
224 -26 43 0 99 1 2 1 2
|
||||||
225 -11 60 0 83 1 2 1 2
|
225 -11 60 0 83 1 2 1 2
|
||||||
226 40 61 0 54 1 2 1 2
|
226 40 61 0 54 1 2 1 2
|
||||||
227 82 35 0 86 1 2 1 2
|
227 82 35 0 86 1 2 1 2
|
||||||
228 -92 12 0 2 1 2 1 2
|
228 -92 12 0 2 1 2 1 2
|
||||||
229 -93 -86 0 14 1 2 1 2
|
229 -93 -86 0 14 1 2 1 2
|
||||||
230 -66 63 0 42 1 2 1 2
|
230 -66 63 0 42 1 2 1 2
|
||||||
231 -72 -87 0 14 1 2 1 2
|
231 -72 -87 0 14 1 2 1 2
|
||||||
232 -57 -84 0 55 1 2 1 2
|
232 -57 -84 0 55 1 2 1 2
|
||||||
233 23 52 0 2 1 2 1 2
|
233 23 52 0 2 1 2 1 2
|
||||||
234 -56 -62 0 18 1 2 1 2
|
234 -56 -62 0 18 1 2 1 2
|
||||||
235 -19 59 0 17 1 2 1 2
|
235 -19 59 0 17 1 2 1 2
|
||||||
236 63 -14 0 22 1 2 1 2
|
236 63 -14 0 22 1 2 1 2
|
||||||
237 -13 38 0 28 1 2 1 2
|
237 -13 38 0 28 1 2 1 2
|
||||||
238 -19 87 0 3 1 2 1 2
|
238 -19 87 0 3 1 2 1 2
|
||||||
239 44 -84 0 96 1 2 1 2
|
239 44 -84 0 96 1 2 1 2
|
||||||
240 98 -17 0 53 1 2 1 2
|
240 98 -17 0 53 1 2 1 2
|
||||||
241 -16 62 0 15 1 2 1 2
|
241 -16 62 0 15 1 2 1 2
|
||||||
242 3 66 0 36 1 2 1 2
|
242 3 66 0 36 1 2 1 2
|
||||||
243 26 22 0 98 1 2 1 2
|
243 26 22 0 98 1 2 1 2
|
||||||
244 -38 -81 0 78 1 2 1 2
|
244 -38 -81 0 78 1 2 1 2
|
||||||
245 70 -80 0 92 1 2 1 2
|
245 70 -80 0 92 1 2 1 2
|
||||||
246 17 -35 0 65 1 2 1 2
|
246 17 -35 0 65 1 2 1 2
|
||||||
247 96 -83 0 64 1 2 1 2
|
247 96 -83 0 64 1 2 1 2
|
||||||
248 -77 80 0 43 1 2 1 2
|
248 -77 80 0 43 1 2 1 2
|
||||||
249 -14 44 0 50 1 2 1 2
|
249 -14 44 0 50 1 2 1 2
|
||||||
250 -33 33 0 0 0 0
|
250 -33 33 0 0 0 0
|
||||||
251 33 -33 0 0 0 0
|
251 33 -33 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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,252 @@
|
||||||
|
/*
|
||||||
|
* 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.examples;
|
||||||
|
|
||||||
|
|
||||||
|
import com.graphhopper.jsprit.analysis.toolbox.AlgorithmEventsRecorder;
|
||||||
|
import com.graphhopper.jsprit.analysis.toolbox.GraphStreamViewer;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.PrettyAlgorithmBuilder;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.SearchStrategy;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.acceptor.SchrimpfAcceptance;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.box.Jsprit;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.listener.IterationStartsListener;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.module.RuinAndRecreateModule;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.recreate.*;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.ruin.RadialRuinStrategyFactory;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.ruin.RandomRuinStrategyFactory;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.ruin.RuinStrategy;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.ruin.RuinString;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.ruin.distance.AvgServiceAndShipmentDistance;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.selector.SelectBest;
|
||||||
|
import com.graphhopper.jsprit.core.algorithm.state.StateManager;
|
||||||
|
import com.graphhopper.jsprit.core.analysis.SolutionAnalyser;
|
||||||
|
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.TransportDistance;
|
||||||
|
import com.graphhopper.jsprit.core.problem.job.Job;
|
||||||
|
import com.graphhopper.jsprit.core.problem.solution.SolutionCostCalculator;
|
||||||
|
import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||||
|
import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute;
|
||||||
|
import com.graphhopper.jsprit.core.problem.vehicle.FiniteFleetManagerFactory;
|
||||||
|
import com.graphhopper.jsprit.core.problem.vehicle.Vehicle;
|
||||||
|
import com.graphhopper.jsprit.core.problem.vehicle.VehicleFleetManager;
|
||||||
|
import com.graphhopper.jsprit.core.reporting.SolutionPrinter;
|
||||||
|
import com.graphhopper.jsprit.core.util.Solutions;
|
||||||
|
import com.graphhopper.jsprit.instance.reader.CordeauReader;
|
||||||
|
import com.graphhopper.jsprit.util.Examples;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BuildAlgorithmFromScratch2 {
|
||||||
|
|
||||||
|
|
||||||
|
public static class MyBestStrategy extends AbstractInsertionStrategy {
|
||||||
|
|
||||||
|
private JobInsertionCostsCalculatorLight insertionCalculator;
|
||||||
|
|
||||||
|
|
||||||
|
public MyBestStrategy(VehicleRoutingProblem vrp, VehicleFleetManager fleetManager, StateManager stateManager, ConstraintManager constraintManager) {
|
||||||
|
super(vrp);
|
||||||
|
insertionCalculator = JobInsertionCostsCalculatorLightFactory.createStandardCalculator(vrp, fleetManager, stateManager, constraintManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Job> insertUnassignedJobs(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||||
|
List<Job> badJobs = new ArrayList<Job>();
|
||||||
|
List<Job> unassigned = new ArrayList<Job>(unassignedJobs);
|
||||||
|
Collections.shuffle(unassigned, random);
|
||||||
|
|
||||||
|
for (Job j : unassigned) {
|
||||||
|
|
||||||
|
InsertionData bestInsertionData = InsertionData.createEmptyInsertionData();
|
||||||
|
VehicleRoute bestRoute = null;
|
||||||
|
//look for inserting unassigned job into existing route
|
||||||
|
for (VehicleRoute r : vehicleRoutes) {
|
||||||
|
InsertionData insertionData = insertionCalculator.getInsertionData(j, r, bestInsertionData.getInsertionCost());
|
||||||
|
if (insertionData instanceof InsertionData.NoInsertionFound) continue;
|
||||||
|
if (insertionData.getInsertionCost() < bestInsertionData.getInsertionCost()) {
|
||||||
|
bestInsertionData = insertionData;
|
||||||
|
bestRoute = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//try whole new route
|
||||||
|
VehicleRoute empty = VehicleRoute.emptyRoute();
|
||||||
|
InsertionData insertionData = insertionCalculator.getInsertionData(j, empty, bestInsertionData.getInsertionCost());
|
||||||
|
if (!(insertionData instanceof InsertionData.NoInsertionFound)) {
|
||||||
|
if (insertionData.getInsertionCost() < bestInsertionData.getInsertionCost()) {
|
||||||
|
vehicleRoutes.add(empty);
|
||||||
|
insertJob(j, insertionData, empty);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (bestRoute != null) insertJob(j, bestInsertionData, bestRoute);
|
||||||
|
else badJobs.add(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return badJobs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Examples.createOutputFolder();
|
||||||
|
|
||||||
|
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||||
|
new CordeauReader(vrpBuilder).read("input/p11");
|
||||||
|
final VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
|
|
||||||
|
// VehicleRoutingAlgorithm vra = createAlgorithm(vrp);
|
||||||
|
VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp).setProperty(Jsprit.Parameter.FAST_REGRET, "true")
|
||||||
|
.setProperty(Jsprit.Parameter.THREADS, "4")
|
||||||
|
.setProperty(Jsprit.Parameter.REGRET_DISTANCE_SCORER, "0.0001")
|
||||||
|
.setProperty(Jsprit.Strategy.STRING_BEST, "0.2")
|
||||||
|
.setProperty(Jsprit.Strategy.STRING_REGRET, "0.2")
|
||||||
|
.buildAlgorithm();
|
||||||
|
|
||||||
|
vra.setMaxIterations(15000);
|
||||||
|
AlgorithmEventsRecorder eventsRecorder = new AlgorithmEventsRecorder(vrp, "output/events.dgs.gz");
|
||||||
|
eventsRecorder.setRecordingRange(40, 100);
|
||||||
|
// vra.addListener(eventsRecorder);
|
||||||
|
|
||||||
|
VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions());
|
||||||
|
SolutionPrinter.print(vrp, solution, SolutionPrinter.Print.VERBOSE);
|
||||||
|
|
||||||
|
new GraphStreamViewer(vrp, solution).display();
|
||||||
|
// AlgorithmEventsViewer viewer = new AlgorithmEventsViewer();
|
||||||
|
// viewer.setRuinDelay(6);
|
||||||
|
// viewer.setRecreationDelay(1);
|
||||||
|
// viewer.display("output/events.dgs.gz");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static VehicleRoutingAlgorithm createAlgorithm(final VehicleRoutingProblem vrp) {
|
||||||
|
|
||||||
|
VehicleFleetManager fleetManager = new FiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
|
||||||
|
StateManager stateManager = new StateManager(vrp);
|
||||||
|
ConstraintManager constraintManager = new ConstraintManager(vrp, stateManager);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* insertion strategies
|
||||||
|
*/
|
||||||
|
//my custom best insertion
|
||||||
|
MyBestStrategy best = new MyBestStrategy(vrp, fleetManager, stateManager, constraintManager);
|
||||||
|
|
||||||
|
//regret insertion
|
||||||
|
InsertionBuilder iBuilder = new InsertionBuilder(vrp, fleetManager, stateManager, constraintManager);
|
||||||
|
iBuilder.setInsertionStrategy(InsertionBuilder.Strategy.REGRET);
|
||||||
|
iBuilder.setFastRegret(true);
|
||||||
|
|
||||||
|
RegretInsertionFast regret = (RegretInsertionFast) iBuilder.build();
|
||||||
|
DefaultScorer scoringFunction = new DefaultScorer(vrp);
|
||||||
|
scoringFunction.setDepotDistanceParam(0.00001);
|
||||||
|
scoringFunction.setTimeWindowParam(0);
|
||||||
|
regret.setScoringFunction(scoringFunction);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ruin strategies
|
||||||
|
*/
|
||||||
|
RuinStrategy randomRuin = new RandomRuinStrategyFactory(0.5).createStrategy(vrp);
|
||||||
|
RuinStrategy radialRuin = new RadialRuinStrategyFactory(0.3, new AvgServiceAndShipmentDistance(vrp.getTransportCosts())).createStrategy(vrp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* objective function
|
||||||
|
*/
|
||||||
|
|
||||||
|
RuinStrategy stringRuin = new RuinString(vrp, new AvgServiceAndShipmentDistance(vrp.getTransportCosts()));
|
||||||
|
|
||||||
|
SolutionCostCalculator objectiveFunction = getObjectiveFunction(vrp);
|
||||||
|
|
||||||
|
final SchrimpfAcceptance schrimpfAcceptance = new SchrimpfAcceptance(1, 0.15);
|
||||||
|
IterationStartsListener schrimpfThreshold = new IterationStartsListener() {
|
||||||
|
@Override
|
||||||
|
public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||||
|
if (i == 1) {
|
||||||
|
double initialThreshold = Solutions.bestOf(solutions).getCost() * 0.03;
|
||||||
|
schrimpfAcceptance.setInitialThreshold(initialThreshold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SearchStrategy firstStrategy = new SearchStrategy("firstStrategy", new SelectBest(), schrimpfAcceptance, objectiveFunction);
|
||||||
|
firstStrategy.addModule(new RuinAndRecreateModule("randRuinRegretIns", regret, stringRuin));
|
||||||
|
|
||||||
|
// SearchStrategy secondStrategy = new SearchStrategy("secondStrategy", new SelectBest(), new GreedyAcceptance(1), objectiveFunction);
|
||||||
|
// secondStrategy.addModule(new RuinAndRecreateModule("radRuinRegretIns", regret, radialRuin));
|
||||||
|
|
||||||
|
// SearchStrategy thirdStrategy = new SearchStrategy("thirdStrategy", new SelectBest(), new GreedyAcceptance(1), objectiveFunction);
|
||||||
|
// secondStrategy.addModule(new RuinAndRecreateModule("radRuinBestIns", regret, radialRuin));
|
||||||
|
|
||||||
|
PrettyAlgorithmBuilder prettyAlgorithmBuilder = PrettyAlgorithmBuilder.newInstance(vrp, fleetManager, stateManager, constraintManager);
|
||||||
|
final VehicleRoutingAlgorithm vra = prettyAlgorithmBuilder
|
||||||
|
.withStrategy(firstStrategy, 0.5)
|
||||||
|
// .withStrategy(secondStrategy, 0.5).withStrategy(thirdStrategy, 0.2)
|
||||||
|
.addCoreStateAndConstraintStuff()
|
||||||
|
.constructInitialSolutionWith(regret, objectiveFunction)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//if you want to switch on/off strategies or adapt their weight within the search, you can do the following
|
||||||
|
//e.g. from iteration 50 on, switch off first strategy
|
||||||
|
//switch on again at iteration 90 with slightly higher weight
|
||||||
|
// IterationStartsListener strategyAdaptor = new IterationStartsListener() {
|
||||||
|
// @Override
|
||||||
|
// public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||||
|
// if (i == 50) {
|
||||||
|
// vra.getSearchStrategyManager().informStrategyWeightChanged("firstStrategy", 0.0);
|
||||||
|
// System.out.println("switched off firstStrategy");
|
||||||
|
// }
|
||||||
|
// if (i == 90) {
|
||||||
|
// vra.getSearchStrategyManager().informStrategyWeightChanged("firstStrategy", 0.7);
|
||||||
|
// System.out.println("switched on firstStrategy again with higher weight");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// vra.addListener(strategyAdaptor);
|
||||||
|
vra.addListener(schrimpfThreshold);
|
||||||
|
vra.addListener(schrimpfAcceptance);
|
||||||
|
return vra;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SolutionCostCalculator getObjectiveFunction(final VehicleRoutingProblem vrp) {
|
||||||
|
return new SolutionCostCalculator() {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getCosts(VehicleRoutingProblemSolution solution) {
|
||||||
|
SolutionAnalyser analyser = new SolutionAnalyser(vrp, solution, new TransportDistance() {
|
||||||
|
@Override
|
||||||
|
public double getDistance(Location from, Location to, double departureTime, Vehicle vehicle) {
|
||||||
|
return vrp.getTransportCosts().getTransportCost(from, to, 0., null, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return analyser.getVariableTransportCosts() + solution.getUnassignedJobs().size() * 500.;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue