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

make no. unassigned jobs configurable - related to #431

This commit is contained in:
oblonski 2018-09-17 10:21:32 +02:00
parent 13156f7acc
commit 48611e1085
No known key found for this signature in database
GPG key ID: 179DE487285680D1
2 changed files with 142 additions and 11 deletions

View file

@ -26,9 +26,7 @@ import com.graphhopper.jsprit.core.algorithm.ruin.listener.RuinListener;
import com.graphhopper.jsprit.core.problem.job.Job; import com.graphhopper.jsprit.core.problem.job.Job;
import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution; import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import java.util.Collection; import java.util.*;
import java.util.HashSet;
import java.util.Set;
public class RuinAndRecreateModule implements SearchStrategyModule { public class RuinAndRecreateModule implements SearchStrategyModule {
@ -39,6 +37,12 @@ public class RuinAndRecreateModule implements SearchStrategyModule {
private String moduleName; private String moduleName;
private Random random = new Random(4711);
private int minUnassignedJobsToBeReinserted = Integer.MAX_VALUE;
private double proportionOfUnassignedJobsToBeReinserted = 1d;
public RuinAndRecreateModule(String moduleName, InsertionStrategy insertion, RuinStrategy ruin) { public RuinAndRecreateModule(String moduleName, InsertionStrategy insertion, RuinStrategy ruin) {
super(); super();
this.insertion = insertion; this.insertion = insertion;
@ -46,16 +50,58 @@ public class RuinAndRecreateModule implements SearchStrategyModule {
this.moduleName = moduleName; this.moduleName = moduleName;
} }
/**
* To make overall results reproducible, make sure this class is provided with the "global" random number generator.
*
* @param random
*/
public void setRandom(Random random) {
this.random = random;
}
/**
* Minimum number of unassigned jobs that is reinserted in each iteration.
*
* @param minUnassignedJobsToBeReinserted
*/
public void setMinUnassignedJobsToBeReinserted(int minUnassignedJobsToBeReinserted) {
this.minUnassignedJobsToBeReinserted = minUnassignedJobsToBeReinserted;
}
/**
* Proportion of unassigned jobs that is reinserted in each iteration.
*
* @param proportionOfUnassignedJobsToBeReinserted
*/
public void setProportionOfUnassignedJobsToBeReinserted(double proportionOfUnassignedJobsToBeReinserted) {
this.proportionOfUnassignedJobsToBeReinserted = proportionOfUnassignedJobsToBeReinserted;
}
@Override @Override
public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution) { public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution previousVrpSolution) {
Collection<Job> ruinedJobs = ruin.ruin(vrpSolution.getRoutes()); Collection<Job> ruinedJobs = ruin.ruin(previousVrpSolution.getRoutes());
Set<Job> ruinedJobSet = new HashSet<Job>(); Set<Job> ruinedJobSet = new HashSet<>();
ruinedJobSet.addAll(ruinedJobs); ruinedJobSet.addAll(ruinedJobs);
ruinedJobSet.addAll(vrpSolution.getUnassignedJobs()); List<Job> stillUnassignedInThisIteration = new ArrayList<>();
Collection<Job> unassignedJobs = insertion.insertJobs(vrpSolution.getRoutes(), ruinedJobSet); if (previousVrpSolution.getUnassignedJobs().size() < minUnassignedJobsToBeReinserted) {
vrpSolution.getUnassignedJobs().clear(); ruinedJobSet.addAll(previousVrpSolution.getUnassignedJobs());
vrpSolution.getUnassignedJobs().addAll(unassignedJobs); } else {
return vrpSolution; int noUnassignedToBeInserted = Math.max(minUnassignedJobsToBeReinserted, (int) (previousVrpSolution.getUnassignedJobs().size() * proportionOfUnassignedJobsToBeReinserted));
List<Job> jobList = new ArrayList<>(previousVrpSolution.getUnassignedJobs());
Collections.shuffle(jobList, random);
for (int i = 0; i < noUnassignedToBeInserted; i++) {
ruinedJobSet.add(jobList.get(i));
}
for (int i = noUnassignedToBeInserted; i < jobList.size(); i++) {
stillUnassignedInThisIteration.add(jobList.get(i));
}
}
Collection<Job> unassignedJobs = insertion.insertJobs(previousVrpSolution.getRoutes(), ruinedJobSet);
previousVrpSolution.getUnassignedJobs().clear();
previousVrpSolution.getUnassignedJobs().addAll(unassignedJobs);
previousVrpSolution.getUnassignedJobs().addAll(stillUnassignedInThisIteration);
VehicleRoutingProblemSolution newSolution = previousVrpSolution;
return newSolution;
} }

View file

@ -0,0 +1,85 @@
/*
* 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.module;
import com.graphhopper.jsprit.core.algorithm.recreate.InsertionStrategy;
import com.graphhopper.jsprit.core.algorithm.ruin.RuinStrategy;
import com.graphhopper.jsprit.core.problem.job.Job;
import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute;
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static org.mockito.Mockito.mock;
public class RuinAndRecreateModuleTest {
@Test
public void initialNumOfUnassignedShouldWorkCorrectly() {
InsertionStrategy insertionStrategy = mock(InsertionStrategy.class);
RuinStrategy ruinStrategy = mock(RuinStrategy.class);
RuinAndRecreateModule module = new RuinAndRecreateModule("name", insertionStrategy, ruinStrategy);
Collection<VehicleRoute> routes = new ArrayList<>();
List<Job> unassigned = new ArrayList<>();
for (int i = 0; i < 20; i++) {
unassigned.add(mock(Job.class));
}
VehicleRoutingProblemSolution previousSolution = new VehicleRoutingProblemSolution(routes, unassigned, 0);
VehicleRoutingProblemSolution newSolution = module.runAndGetSolution(previousSolution);
Assert.assertEquals(0, newSolution.getUnassignedJobs().size());
}
@Test
public void proportionOfUnassignedShouldWorkCorrectly() {
InsertionStrategy insertionStrategy = mock(InsertionStrategy.class);
RuinStrategy ruinStrategy = mock(RuinStrategy.class);
RuinAndRecreateModule module = new RuinAndRecreateModule("name", insertionStrategy, ruinStrategy);
module.setMinUnassignedJobsToBeReinserted(5);
module.setProportionOfUnassignedJobsToBeReinserted(0.01);
Collection<VehicleRoute> routes = new ArrayList<>();
List<Job> unassigned = new ArrayList<>();
for (int i = 0; i < 20; i++) {
unassigned.add(mock(Job.class));
}
VehicleRoutingProblemSolution previousSolution = new VehicleRoutingProblemSolution(routes, unassigned, 0);
VehicleRoutingProblemSolution newSolution = module.runAndGetSolution(previousSolution);
Assert.assertEquals(15, newSolution.getUnassignedJobs().size());
}
@Test
public void proportionOfUnassignedShouldWorkCorrectly2() {
InsertionStrategy insertionStrategy = mock(InsertionStrategy.class);
RuinStrategy ruinStrategy = mock(RuinStrategy.class);
RuinAndRecreateModule module = new RuinAndRecreateModule("name", insertionStrategy, ruinStrategy);
module.setMinUnassignedJobsToBeReinserted(5);
module.setProportionOfUnassignedJobsToBeReinserted(0.5);
Collection<VehicleRoute> routes = new ArrayList<>();
List<Job> unassigned = new ArrayList<>();
for (int i = 0; i < 20; i++) {
unassigned.add(mock(Job.class));
}
VehicleRoutingProblemSolution previousSolution = new VehicleRoutingProblemSolution(routes, unassigned, 0);
VehicleRoutingProblemSolution newSolution = module.runAndGetSolution(previousSolution);
Assert.assertEquals(10, newSolution.getUnassignedJobs().size());
}
}