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

Replacing the termination logic to reduce run-times with marginal effect on quality.

This commit is contained in:
safraeli 2019-05-14 12:57:11 +03:00
parent 2a04804748
commit 51fe971d6d
3 changed files with 27 additions and 7 deletions

View file

@ -164,7 +164,5 @@ public class SearchStrategy {
for (SearchStrategyModule module : searchStrategyModules) { for (SearchStrategyModule module : searchStrategyModules) {
module.addModuleListener(moduleListener); module.addModuleListener(moduleListener);
} }
} }
} }

View file

@ -18,9 +18,13 @@
package com.graphhopper.jsprit.core.algorithm.termination; package com.graphhopper.jsprit.core.algorithm.termination;
import com.graphhopper.jsprit.core.algorithm.SearchStrategy; import com.graphhopper.jsprit.core.algorithm.SearchStrategy;
import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
/** /**
* Terminates algorithm prematurely based on iterations without any improvement (i.e. new solution acceptance). * Terminates algorithm prematurely based on iterations without any improvement (i.e. new solution acceptance).
@ -39,6 +43,11 @@ public class IterationWithoutImprovementTermination implements PrematureAlgorith
private int iterationsWithoutImprovement = 0; private int iterationsWithoutImprovement = 0;
private List<Double> costs;
private List<Integer> unassignedCount;
private int bestCost = Integer.MAX_VALUE;
/** /**
* Constructs termination. * Constructs termination.
* *
@ -46,6 +55,8 @@ public class IterationWithoutImprovementTermination implements PrematureAlgorith
*/ */
public IterationWithoutImprovementTermination(int noIterationsWithoutImprovement) { public IterationWithoutImprovementTermination(int noIterationsWithoutImprovement) {
this.noIterationWithoutImprovement = noIterationsWithoutImprovement; this.noIterationWithoutImprovement = noIterationsWithoutImprovement;
costs = new ArrayList<>();
unassignedCount = new ArrayList<>();
log.debug("initialise " + this); log.debug("initialise " + this);
} }
@ -56,10 +67,21 @@ public class IterationWithoutImprovementTermination implements PrematureAlgorith
@Override @Override
public boolean isPrematureBreak(SearchStrategy.DiscoveredSolution discoveredSolution) { public boolean isPrematureBreak(SearchStrategy.DiscoveredSolution discoveredSolution) {
if (discoveredSolution.isAccepted()) iterationsWithoutImprovement = 0; VehicleRoutingProblemSolution sol = discoveredSolution.getSolution();
else iterationsWithoutImprovement++; double currentCost = sol.getCost();
return (iterationsWithoutImprovement > noIterationWithoutImprovement); costs.add(Math.min(currentCost, bestCost));
int currentUnassigned = sol.getUnassignedJobs().size();
unassignedCount.add(currentUnassigned);
int i = costs.size() - 1;
if (i < noIterationWithoutImprovement)
return false;
int progressPercentTerminationCondition = 1; // TODO: Move to configuration
boolean unassignedEqual = (currentUnassigned == unassignedCount.get(i-noIterationWithoutImprovement));
boolean progressTooSlow = (100 * Math.abs(currentCost - costs.get(i - noIterationWithoutImprovement))) / currentCost < progressPercentTerminationCondition;
return (unassignedEqual && progressTooSlow);
} }
} }

View file

@ -131,7 +131,7 @@ public class SolutionPrinter {
out.format("+---------------+------------------------------------------+%n"); out.format("+---------------+------------------------------------------+%n");
out.printf("| indicator | value |%n"); out.printf("| indicator | value |%n");
out.format("+---------------+------------------------------------------+%n"); out.format("+---------------+------------------------------------------+%n");
out.format(leftAlignSolution, "costs", solution.getCost()); out.format(leftAlignSolution, "costs", Math.round(solution.getCost()));
out.format(leftAlignSolution, "noVehicles", solution.getRoutes().size()); out.format(leftAlignSolution, "noVehicles", solution.getRoutes().size());
out.format(leftAlignSolution, "unassgndJobs", solution.getUnassignedJobs().size()); out.format(leftAlignSolution, "unassgndJobs", solution.getUnassignedJobs().size());
out.format("+----------------------------------------------------------+%n"); out.format("+----------------------------------------------------------+%n");