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

Merge pull request #355 from balage1541/master

#354 - Initial solution with new jobs added
This commit is contained in:
Stefan Schröder 2017-06-14 14:51:15 +02:00 committed by GitHub
commit c47dae32d3

View file

@ -17,6 +17,14 @@
*/ */
package com.graphhopper.jsprit.core.algorithm; package com.graphhopper.jsprit.core.algorithm;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.graphhopper.jsprit.core.algorithm.SearchStrategy.DiscoveredSolution; import com.graphhopper.jsprit.core.algorithm.SearchStrategy.DiscoveredSolution;
import com.graphhopper.jsprit.core.algorithm.listener.SearchStrategyListener; import com.graphhopper.jsprit.core.algorithm.listener.SearchStrategyListener;
import com.graphhopper.jsprit.core.algorithm.listener.SearchStrategyModuleListener; import com.graphhopper.jsprit.core.algorithm.listener.SearchStrategyModuleListener;
@ -30,11 +38,6 @@ import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolutio
import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute; import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute;
import com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivity; import com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivity;
import com.graphhopper.jsprit.core.util.Solutions; import com.graphhopper.jsprit.core.util.Solutions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collection;
/** /**
@ -57,10 +60,9 @@ public class VehicleRoutingAlgorithm {
@Override @Override
public boolean isPrematureBreak(DiscoveredSolution discoveredSolution) { public boolean isPrematureBreak(DiscoveredSolution discoveredSolution) {
for (PrematureAlgorithmTermination termination : terminationCriteria) { for (PrematureAlgorithmTermination termination : terminationCriteria) {
if (termination.isPrematureBreak(discoveredSolution)) { if (termination.isPrematureBreak(discoveredSolution))
return true; return true;
} }
}
return false; return false;
} }
} }
@ -140,26 +142,32 @@ public class VehicleRoutingAlgorithm {
* @param solution the solution to be added * @param solution the solution to be added
*/ */
public void addInitialSolution(VehicleRoutingProblemSolution solution) { public void addInitialSolution(VehicleRoutingProblemSolution solution) {
// We will make changes so let's make a copy
solution = VehicleRoutingProblemSolution.copyOf(solution);
verify(solution); verify(solution);
initialSolutions.add(solution); initialSolutions.add(solution);
} }
private void verify(VehicleRoutingProblemSolution solution) { private void verify(VehicleRoutingProblemSolution solution) {
int nuJobs = 0; Set<Job> allJobs = new HashSet<Job>(problem.getJobs().values());
allJobs.removeAll(solution.getUnassignedJobs());
for (VehicleRoute route : solution.getRoutes()) { for (VehicleRoute route : solution.getRoutes()) {
nuJobs += route.getTourActivities().getJobs().size(); allJobs.removeAll(route.getTourActivities().getJobs());
if (route.getVehicle().getIndex() == 0) if (route.getVehicle().getIndex() == 0)
throw new IllegalStateException("vehicle used in initial solution has no index. probably a vehicle is used that has not been added to the " + throw new IllegalStateException("vehicle used in initial solution has no index. probably a vehicle is used that has not been added to the " +
" the VehicleRoutingProblem. only use vehicles that have already been added to the problem."); " the VehicleRoutingProblem. only use vehicles that have already been added to the problem.");
for (TourActivity act : route.getActivities()) { for (TourActivity act : route.getActivities()) {
if (act.getIndex() == 0) { if (act.getIndex() == 0)
throw new IllegalStateException("act in initial solution has no index. activities are created and associated to their job in VehicleRoutingProblem\n." + throw new IllegalStateException("act in initial solution has no index. activities are created and associated to their job in VehicleRoutingProblem\n." +
" thus if you build vehicle-routes use the jobActivityFactory from vehicle routing problem like that \n" + " thus if you build vehicle-routes use the jobActivityFactory from vehicle routing problem like that \n" +
" VehicleRoute.Builder.newInstance(knownVehicle).setJobActivityFactory(vrp.getJobActivityFactory).addService(..)....build() \n" + " VehicleRoute.Builder.newInstance(knownVehicle).setJobActivityFactory(vrp.getJobActivityFactory).addService(..)....build() \n" +
" then the activities that are created to build the route are identical to the ones used in VehicleRoutingProblem"); " then the activities that are created to build the route are identical to the ones used in VehicleRoutingProblem");
} }
} }
}
solution.getUnassignedJobs().addAll(allJobs);
solution.setCost(getObjectiveFunction().getCosts(solution));
// if (nuJobs != problem.getJobs().values().size()) { // if (nuJobs != problem.getJobs().values().size()) {
// logger.warn("number of jobs in initial solution ({}) is not equal nuJobs in vehicle routing problem ({})" + // logger.warn("number of jobs in initial solution ({}) is not equal nuJobs in vehicle routing problem ({})" +
// "\n this might yield unintended effects, e.g. initial solution cannot be improved anymore.", nuJobs, problem.getJobs().values().size()); // "\n this might yield unintended effects, e.g. initial solution cannot be improved anymore.", nuJobs, problem.getJobs().values().size());
@ -214,7 +222,9 @@ public class VehicleRoutingAlgorithm {
Collection<VehicleRoutingProblemSolution> solutions = new ArrayList<VehicleRoutingProblemSolution>(initialSolutions); Collection<VehicleRoutingProblemSolution> solutions = new ArrayList<VehicleRoutingProblemSolution>(initialSolutions);
algorithmStarts(problem, solutions); algorithmStarts(problem, solutions);
bestEver = Solutions.bestOf(solutions); bestEver = Solutions.bestOf(solutions);
if (logger.isTraceEnabled()) log(solutions); if (logger.isTraceEnabled()) {
log(solutions);
}
logger.info("iterations start"); logger.info("iterations start");
for (int i = 0; i < maxIterations; i++) { for (int i = 0; i < maxIterations; i++) {
iterationStarts(i + 1, problem, solutions); iterationStarts(i + 1, problem, solutions);
@ -222,7 +232,9 @@ public class VehicleRoutingAlgorithm {
counter.incCounter(); counter.incCounter();
SearchStrategy strategy = searchStrategyManager.getRandomStrategy(); SearchStrategy strategy = searchStrategyManager.getRandomStrategy();
DiscoveredSolution discoveredSolution = strategy.run(problem, solutions); DiscoveredSolution discoveredSolution = strategy.run(problem, solutions);
if (logger.isTraceEnabled()) log(discoveredSolution); if (logger.isTraceEnabled()) {
log(discoveredSolution);
}
memorizeIfBestEver(discoveredSolution); memorizeIfBestEver(discoveredSolution);
selectedStrategy(discoveredSolution, problem, solutions); selectedStrategy(discoveredSolution, problem, solutions);
if (terminationManager.isPrematureBreak(discoveredSolution)) { if (terminationManager.isPrematureBreak(discoveredSolution)) {
@ -240,11 +252,15 @@ public class VehicleRoutingAlgorithm {
} }
private void addBestEver(Collection<VehicleRoutingProblemSolution> solutions) { private void addBestEver(Collection<VehicleRoutingProblemSolution> solutions) {
if (bestEver != null) solutions.add(bestEver); if (bestEver != null) {
solutions.add(bestEver);
}
} }
private void log(Collection<VehicleRoutingProblemSolution> solutions) { private void log(Collection<VehicleRoutingProblemSolution> solutions) {
for (VehicleRoutingProblemSolution sol : solutions) log(sol); for (VehicleRoutingProblemSolution sol : solutions) {
log(sol);
}
} }
private void log(VehicleRoutingProblemSolution solution) { private void log(VehicleRoutingProblemSolution solution) {
@ -277,9 +293,11 @@ public class VehicleRoutingAlgorithm {
private void memorizeIfBestEver(DiscoveredSolution discoveredSolution) { private void memorizeIfBestEver(DiscoveredSolution discoveredSolution) {
if (discoveredSolution == null) return; if (discoveredSolution == null) return;
if (bestEver == null) bestEver = discoveredSolution.getSolution(); if (bestEver == null) {
else if (discoveredSolution.getSolution().getCost() < bestEver.getCost())
bestEver = discoveredSolution.getSolution(); bestEver = discoveredSolution.getSolution();
} else if (discoveredSolution.getSolution().getCost() < bestEver.getCost()) {
bestEver = discoveredSolution.getSolution();
}
} }
@ -297,11 +315,13 @@ public class VehicleRoutingAlgorithm {
public void addListener(VehicleRoutingAlgorithmListener l) { public void addListener(VehicleRoutingAlgorithmListener l) {
algoListeners.addListener(l); algoListeners.addListener(l);
if (l instanceof SearchStrategyListener) if (l instanceof SearchStrategyListener) {
searchStrategyManager.addSearchStrategyListener((SearchStrategyListener) l); searchStrategyManager.addSearchStrategyListener((SearchStrategyListener) l);
if (l instanceof SearchStrategyModuleListener) }
if (l instanceof SearchStrategyModuleListener) {
searchStrategyManager.addSearchStrategyModuleListener((SearchStrategyModuleListener) l); searchStrategyManager.addSearchStrategyModuleListener((SearchStrategyModuleListener) l);
} }
}
private void iterationEnds(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) { private void iterationEnds(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
algoListeners.iterationEnds(i, problem, solutions); algoListeners.iterationEnds(i, problem, solutions);