diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/termination/IterationWithoutImprovementTermination.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/termination/IterationWithoutImprovementTermination.java index bacf33e2..72cbb991 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/termination/IterationWithoutImprovementTermination.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/termination/IterationWithoutImprovementTermination.java @@ -107,7 +107,11 @@ public class IterationWithoutImprovementTermination implements PrematureAlgorith return false; boolean unassignedJobsEqual = (currentJobsUnassigned == unassignedJobsCount.get(i - noIterationWithoutImprovement)); - boolean progressTooSlow = 100 * ((costs.get(i - noIterationWithoutImprovement) - currentCost) / currentCost) <= terminationByCostPercentage; - return (unassignedJobsEqual && progressTooSlow); + boolean progressTooSlow = 100 * ((costs.get(i - noIterationWithoutImprovement) - bestCost) / bestCost) <= terminationByCostPercentage; + if (unassignedJobsEqual && progressTooSlow){ + log.debug("Termination condition by percentage reached after " + Integer.toString(i) + " iterations."); + return true; + } + return false; } } diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/termination/IterationsWithoutImprovementTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/termination/IterationsWithoutImprovementTest.java index 6a0bfb43..5b28b470 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/termination/IterationsWithoutImprovementTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/termination/IterationsWithoutImprovementTest.java @@ -150,4 +150,25 @@ public class IterationsWithoutImprovementTest { Assert.assertEquals(60, terminatedAfter); } + @Test + public void isPrematureBreakLastCostIsWorstShouldNotBreak() { + int maxIterations = 7; + IterationWithoutImprovementTermination termination = new IterationWithoutImprovementTermination(5, 1.0); + SearchStrategy.DiscoveredSolution discoveredSolution = mock(SearchStrategy.DiscoveredSolution.class); + VehicleRoutingProblemSolution solution = mock(VehicleRoutingProblemSolution.class); + when(discoveredSolution.getSolution()).thenReturn(solution); + when(solution.getUnassignedJobs()).thenReturn(new ArrayList()); + + boolean isTerminate = false; + for (int i = 0; i < maxIterations; i++) { + + when(solution.getCost()).thenReturn(i < 6.0 ? 10.0-i : 12); + boolean terminate = termination.isPrematureBreak(discoveredSolution); + if (terminate) { + isTerminate= true; + break; + } + } + Assert.assertFalse(isTerminate); + } }