Skip to content

Commit

Permalink
PLANNER-489 Avoid getBestSolution() cast by generifying Solver and So…
Browse files Browse the repository at this point in the history
…lverFactory and return the best solution from solve(): docs and migrate examples
  • Loading branch information
ge0ffrey committed Dec 17, 2015
1 parent 2600301 commit 1f2e52a
Show file tree
Hide file tree
Showing 53 changed files with 343 additions and 397 deletions.
Expand Up @@ -86,16 +86,15 @@ public SubSingleBenchmarkRunner call() {
solverConfig.offerRandomSeedFromSubSingleIndex((long) subSingleBenchmarkResult.getSubSingleBenchmarkIndex()); solverConfig.offerRandomSeedFromSubSingleIndex((long) subSingleBenchmarkResult.getSubSingleBenchmarkIndex());
} }
// Intentionally create a fresh solver for every SingleBenchmarkResult to reset Random, tabu lists, ... // Intentionally create a fresh solver for every SingleBenchmarkResult to reset Random, tabu lists, ...
Solver solver = solverConfig.buildSolver(classLoader); Solver<Solution> solver = solverConfig.buildSolver(classLoader);


for (SubSingleStatistic subSingleStatistic : subSingleBenchmarkResult.getEffectiveSubSingleStatisticMap().values()) { for (SubSingleStatistic subSingleStatistic : subSingleBenchmarkResult.getEffectiveSubSingleStatisticMap().values()) {
subSingleStatistic.open(solver); subSingleStatistic.open(solver);
subSingleStatistic.initPointList(); subSingleStatistic.initPointList();
} }


solver.solve(inputSolution); Solution outputSolution = solver.solve(inputSolution);
long timeMillisSpent = solver.getTimeMillisSpent(); long timeMillisSpent = solver.getTimeMillisSpent();
Solution outputSolution = solver.getBestSolution();


DefaultSolverScope solverScope = ((DefaultSolver) solver).getSolverScope(); DefaultSolverScope solverScope = ((DefaultSolver) solver).getSolverScope();
SolutionDescriptor solutionDescriptor = solverScope.getSolutionDescriptor(); SolutionDescriptor solutionDescriptor = solverScope.getSolutionDescriptor();
Expand Down
Expand Up @@ -36,6 +36,7 @@
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.optaplanner.benchmark.impl.report.ReportHelper; import org.optaplanner.benchmark.impl.report.ReportHelper;
import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult; import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult;
import org.optaplanner.core.api.domain.solution.Solution;
import org.optaplanner.core.api.solver.Solver; import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.impl.score.definition.ScoreDefinition; import org.optaplanner.core.impl.score.definition.ScoreDefinition;
import org.slf4j.Logger; import org.slf4j.Logger;
Expand Down Expand Up @@ -103,9 +104,9 @@ public File getCsvFile() {
// Lifecycle methods // Lifecycle methods
// ************************************************************************ // ************************************************************************


public abstract void open(Solver solver); public abstract void open(Solver<Solution> solver);


public abstract void close(Solver solver); public abstract void close(Solver<Solution> solver);


// ************************************************************************ // ************************************************************************
// Write methods // Write methods
Expand Down
Expand Up @@ -40,11 +40,11 @@ public BestScoreSubSingleStatistic(SubSingleBenchmarkResult subSingleBenchmarkRe
// Lifecycle methods // Lifecycle methods
// ************************************************************************ // ************************************************************************


public void open(Solver solver) { public void open(Solver<Solution> solver) {
solver.addEventListener(listener); solver.addEventListener(listener);
} }


public void close(Solver solver) { public void close(Solver<Solution> solver) {
solver.removeEventListener(listener); solver.removeEventListener(listener);
} }


Expand Down
Expand Up @@ -43,14 +43,14 @@ public BestSolutionMutationSubSingleStatistic(SubSingleBenchmarkResult subSingle
// Lifecycle methods // Lifecycle methods
// ************************************************************************ // ************************************************************************


public void open(Solver solver) { public void open(Solver<Solution> solver) {
InnerScoreDirectorFactory scoreDirectorFactory = (InnerScoreDirectorFactory) solver.getScoreDirectorFactory(); InnerScoreDirectorFactory scoreDirectorFactory = (InnerScoreDirectorFactory) solver.getScoreDirectorFactory();
SolutionDescriptor solutionDescriptor = scoreDirectorFactory.getSolutionDescriptor(); SolutionDescriptor solutionDescriptor = scoreDirectorFactory.getSolutionDescriptor();
listener.setMutationCounter(new MutationCounter(solutionDescriptor)); listener.setMutationCounter(new MutationCounter(solutionDescriptor));
solver.addEventListener(listener); solver.addEventListener(listener);
} }


public void close(Solver solver) { public void close(Solver<Solution> solver) {
solver.removeEventListener(listener); solver.removeEventListener(listener);
} }


Expand Down
Expand Up @@ -21,6 +21,7 @@
import org.optaplanner.benchmark.config.statistic.ProblemStatisticType; import org.optaplanner.benchmark.config.statistic.ProblemStatisticType;
import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult; import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult;
import org.optaplanner.benchmark.impl.statistic.ProblemBasedSubSingleStatistic; import org.optaplanner.benchmark.impl.statistic.ProblemBasedSubSingleStatistic;
import org.optaplanner.core.api.domain.solution.Solution;
import org.optaplanner.core.api.solver.Solver; import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.impl.phase.event.PhaseLifecycleListenerAdapter; import org.optaplanner.core.impl.phase.event.PhaseLifecycleListenerAdapter;
import org.optaplanner.core.impl.phase.scope.AbstractStepScope; import org.optaplanner.core.impl.phase.scope.AbstractStepScope;
Expand Down Expand Up @@ -52,12 +53,12 @@ public CalculateCountSubSingleStatistic(SubSingleBenchmarkResult benchmarkResult
// Lifecycle methods // Lifecycle methods
// ************************************************************************ // ************************************************************************


public void open(Solver solver) { public void open(Solver<Solution> solver) {
((DefaultSolver) solver).addPhaseLifecycleListener(listener); ((DefaultSolver<Solution>) solver).addPhaseLifecycleListener(listener);
} }


public void close(Solver solver) { public void close(Solver<Solution> solver) {
((DefaultSolver) solver).removePhaseLifecycleListener(listener); ((DefaultSolver<Solution>) solver).removePhaseLifecycleListener(listener);
} }


private class CalculateCountSubSingleStatisticListener extends PhaseLifecycleListenerAdapter { private class CalculateCountSubSingleStatisticListener extends PhaseLifecycleListenerAdapter {
Expand Down
Expand Up @@ -21,6 +21,7 @@
import org.optaplanner.benchmark.config.statistic.ProblemStatisticType; import org.optaplanner.benchmark.config.statistic.ProblemStatisticType;
import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult; import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult;
import org.optaplanner.benchmark.impl.statistic.ProblemBasedSubSingleStatistic; import org.optaplanner.benchmark.impl.statistic.ProblemBasedSubSingleStatistic;
import org.optaplanner.core.api.domain.solution.Solution;
import org.optaplanner.core.api.solver.Solver; import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.impl.phase.event.PhaseLifecycleListenerAdapter; import org.optaplanner.core.impl.phase.event.PhaseLifecycleListenerAdapter;
import org.optaplanner.core.impl.phase.scope.AbstractStepScope; import org.optaplanner.core.impl.phase.scope.AbstractStepScope;
Expand Down Expand Up @@ -51,12 +52,12 @@ public MemoryUseSubSingleStatistic(SubSingleBenchmarkResult subSingleBenchmarkRe
// Lifecycle methods // Lifecycle methods
// ************************************************************************ // ************************************************************************


public void open(Solver solver) { public void open(Solver<Solution> solver) {
((DefaultSolver) solver).addPhaseLifecycleListener(listener); ((DefaultSolver<Solution>) solver).addPhaseLifecycleListener(listener);
} }


public void close(Solver solver) { public void close(Solver<Solution> solver) {
((DefaultSolver) solver).removePhaseLifecycleListener(listener); ((DefaultSolver<Solution>) solver).removePhaseLifecycleListener(listener);
} }


private class MemoryUseSubSingleStatisticListener extends PhaseLifecycleListenerAdapter { private class MemoryUseSubSingleStatisticListener extends PhaseLifecycleListenerAdapter {
Expand Down
Expand Up @@ -21,6 +21,7 @@
import org.optaplanner.benchmark.config.statistic.ProblemStatisticType; import org.optaplanner.benchmark.config.statistic.ProblemStatisticType;
import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult; import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult;
import org.optaplanner.benchmark.impl.statistic.ProblemBasedSubSingleStatistic; import org.optaplanner.benchmark.impl.statistic.ProblemBasedSubSingleStatistic;
import org.optaplanner.core.api.domain.solution.Solution;
import org.optaplanner.core.api.solver.Solver; import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.impl.localsearch.scope.LocalSearchStepScope; import org.optaplanner.core.impl.localsearch.scope.LocalSearchStepScope;
import org.optaplanner.core.impl.phase.event.PhaseLifecycleListenerAdapter; import org.optaplanner.core.impl.phase.event.PhaseLifecycleListenerAdapter;
Expand All @@ -41,12 +42,12 @@ public MoveCountPerStepSubSingleStatistic(SubSingleBenchmarkResult subSingleBenc
// Lifecycle methods // Lifecycle methods
// ************************************************************************ // ************************************************************************


public void open(Solver solver) { public void open(Solver<Solution> solver) {
((DefaultSolver) solver).addPhaseLifecycleListener(listener); ((DefaultSolver<Solution>) solver).addPhaseLifecycleListener(listener);
} }


public void close(Solver solver) { public void close(Solver<Solution> solver) {
((DefaultSolver) solver).removePhaseLifecycleListener(listener); ((DefaultSolver<Solution>) solver).removePhaseLifecycleListener(listener);
} }


private class MoveCountPerStepSubSingleStatisticListener extends PhaseLifecycleListenerAdapter { private class MoveCountPerStepSubSingleStatisticListener extends PhaseLifecycleListenerAdapter {
Expand Down
Expand Up @@ -21,6 +21,7 @@
import org.optaplanner.benchmark.config.statistic.ProblemStatisticType; import org.optaplanner.benchmark.config.statistic.ProblemStatisticType;
import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult; import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult;
import org.optaplanner.benchmark.impl.statistic.ProblemBasedSubSingleStatistic; import org.optaplanner.benchmark.impl.statistic.ProblemBasedSubSingleStatistic;
import org.optaplanner.core.api.domain.solution.Solution;
import org.optaplanner.core.api.solver.Solver; import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.impl.phase.event.PhaseLifecycleListenerAdapter; import org.optaplanner.core.impl.phase.event.PhaseLifecycleListenerAdapter;
import org.optaplanner.core.impl.phase.scope.AbstractStepScope; import org.optaplanner.core.impl.phase.scope.AbstractStepScope;
Expand All @@ -40,12 +41,12 @@ public StepScoreSubSingleStatistic(SubSingleBenchmarkResult subSingleBenchmarkRe
// Lifecycle methods // Lifecycle methods
// ************************************************************************ // ************************************************************************


public void open(Solver solver) { public void open(Solver<Solution> solver) {
((DefaultSolver) solver).addPhaseLifecycleListener(listener); ((DefaultSolver<Solution>) solver).addPhaseLifecycleListener(listener);
} }


public void close(Solver solver) { public void close(Solver<Solution> solver) {
((DefaultSolver) solver).removePhaseLifecycleListener(listener); ((DefaultSolver<Solution>) solver).removePhaseLifecycleListener(listener);
} }


private class StepScoreSubSingleStatisticListener extends PhaseLifecycleListenerAdapter { private class StepScoreSubSingleStatisticListener extends PhaseLifecycleListenerAdapter {
Expand Down
Expand Up @@ -39,6 +39,7 @@
import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult; import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult;
import org.optaplanner.benchmark.impl.statistic.PureSubSingleStatistic; import org.optaplanner.benchmark.impl.statistic.PureSubSingleStatistic;
import org.optaplanner.benchmark.impl.statistic.common.MillisecondsSpentNumberFormat; import org.optaplanner.benchmark.impl.statistic.common.MillisecondsSpentNumberFormat;
import org.optaplanner.core.api.domain.solution.Solution;
import org.optaplanner.core.api.score.constraint.ConstraintMatchTotal; import org.optaplanner.core.api.score.constraint.ConstraintMatchTotal;
import org.optaplanner.core.api.solver.Solver; import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.impl.localsearch.scope.LocalSearchPhaseScope; import org.optaplanner.core.impl.localsearch.scope.LocalSearchPhaseScope;
Expand Down Expand Up @@ -76,13 +77,13 @@ public List<File> getGraphFileList() {
// Lifecycle methods // Lifecycle methods
// ************************************************************************ // ************************************************************************


public void open(Solver solver) { public void open(Solver<Solution> solver) {
DefaultSolver defaultSolver = (DefaultSolver) solver; DefaultSolver<Solution> defaultSolver = (DefaultSolver<Solution>) solver;
defaultSolver.setConstraintMatchEnabledPreference(true); defaultSolver.setConstraintMatchEnabledPreference(true);
defaultSolver.addPhaseLifecycleListener(listener); defaultSolver.addPhaseLifecycleListener(listener);
} }


public void close(Solver solver) { public void close(Solver<Solution> solver) {
((DefaultSolver) solver).removePhaseLifecycleListener(listener); ((DefaultSolver) solver).removePhaseLifecycleListener(listener);
} }


Expand Down
Expand Up @@ -39,6 +39,7 @@
import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult; import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult;
import org.optaplanner.benchmark.impl.statistic.PureSubSingleStatistic; import org.optaplanner.benchmark.impl.statistic.PureSubSingleStatistic;
import org.optaplanner.benchmark.impl.statistic.common.MillisecondsSpentNumberFormat; import org.optaplanner.benchmark.impl.statistic.common.MillisecondsSpentNumberFormat;
import org.optaplanner.core.api.domain.solution.Solution;
import org.optaplanner.core.api.score.constraint.ConstraintMatchTotal; import org.optaplanner.core.api.score.constraint.ConstraintMatchTotal;
import org.optaplanner.core.api.solver.Solver; import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.impl.localsearch.scope.LocalSearchStepScope; import org.optaplanner.core.impl.localsearch.scope.LocalSearchStepScope;
Expand Down Expand Up @@ -75,14 +76,14 @@ public List<File> getGraphFileList() {
// Lifecycle methods // Lifecycle methods
// ************************************************************************ // ************************************************************************


public void open(Solver solver) { public void open(Solver<Solution> solver) {
DefaultSolver defaultSolver = (DefaultSolver) solver; DefaultSolver<Solution> defaultSolver = (DefaultSolver<Solution>) solver;
defaultSolver.setConstraintMatchEnabledPreference(true); defaultSolver.setConstraintMatchEnabledPreference(true);
defaultSolver.addPhaseLifecycleListener(listener); defaultSolver.addPhaseLifecycleListener(listener);
} }


public void close(Solver solver) { public void close(Solver<Solution> solver) {
((DefaultSolver) solver).removePhaseLifecycleListener(listener); ((DefaultSolver<Solution>) solver).removePhaseLifecycleListener(listener);
} }


private class ConstraintMatchTotalStepScoreSubSingleStatisticListener extends PhaseLifecycleListenerAdapter { private class ConstraintMatchTotalStepScoreSubSingleStatisticListener extends PhaseLifecycleListenerAdapter {
Expand Down
Expand Up @@ -39,6 +39,7 @@
import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult; import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult;
import org.optaplanner.benchmark.impl.statistic.PureSubSingleStatistic; import org.optaplanner.benchmark.impl.statistic.PureSubSingleStatistic;
import org.optaplanner.benchmark.impl.statistic.common.MillisecondsSpentNumberFormat; import org.optaplanner.benchmark.impl.statistic.common.MillisecondsSpentNumberFormat;
import org.optaplanner.core.api.domain.solution.Solution;
import org.optaplanner.core.api.score.Score; import org.optaplanner.core.api.score.Score;
import org.optaplanner.core.api.solver.Solver; import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.impl.localsearch.scope.LocalSearchPhaseScope; import org.optaplanner.core.impl.localsearch.scope.LocalSearchPhaseScope;
Expand Down Expand Up @@ -76,12 +77,12 @@ public List<File> getGraphFileList() {
// Lifecycle methods // Lifecycle methods
// ************************************************************************ // ************************************************************************


public void open(Solver solver) { public void open(Solver<Solution> solver) {
((DefaultSolver) solver).addPhaseLifecycleListener(listener); ((DefaultSolver<Solution>) solver).addPhaseLifecycleListener(listener);
} }


public void close(Solver solver) { public void close(Solver<Solution> solver) {
((DefaultSolver) solver).removePhaseLifecycleListener(listener); ((DefaultSolver<Solution>) solver).removePhaseLifecycleListener(listener);
} }


private class PickedMoveTypeBestScoreDiffSubSingleStatisticListener extends PhaseLifecycleListenerAdapter { private class PickedMoveTypeBestScoreDiffSubSingleStatisticListener extends PhaseLifecycleListenerAdapter {
Expand Down
Expand Up @@ -39,6 +39,7 @@
import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult; import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult;
import org.optaplanner.benchmark.impl.statistic.PureSubSingleStatistic; import org.optaplanner.benchmark.impl.statistic.PureSubSingleStatistic;
import org.optaplanner.benchmark.impl.statistic.common.MillisecondsSpentNumberFormat; import org.optaplanner.benchmark.impl.statistic.common.MillisecondsSpentNumberFormat;
import org.optaplanner.core.api.domain.solution.Solution;
import org.optaplanner.core.api.score.Score; import org.optaplanner.core.api.score.Score;
import org.optaplanner.core.api.solver.Solver; import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.impl.localsearch.scope.LocalSearchPhaseScope; import org.optaplanner.core.impl.localsearch.scope.LocalSearchPhaseScope;
Expand Down Expand Up @@ -76,12 +77,12 @@ public List<File> getGraphFileList() {
// Lifecycle methods // Lifecycle methods
// ************************************************************************ // ************************************************************************


public void open(Solver solver) { public void open(Solver<Solution> solver) {
((DefaultSolver) solver).addPhaseLifecycleListener(listener); ((DefaultSolver<Solution>) solver).addPhaseLifecycleListener(listener);
} }


public void close(Solver solver) { public void close(Solver<Solution> solver) {
((DefaultSolver) solver).removePhaseLifecycleListener(listener); ((DefaultSolver<Solution>) solver).removePhaseLifecycleListener(listener);
} }


private class PickedMoveTypeStepScoreDiffSubSingleStatisticListener extends PhaseLifecycleListenerAdapter { private class PickedMoveTypeStepScoreDiffSubSingleStatisticListener extends PhaseLifecycleListenerAdapter {
Expand Down
Expand Up @@ -52,11 +52,13 @@ public interface Solver<Solution_ extends Solution> {
long getTimeMillisSpent(); long getTimeMillisSpent();


/** /**
* Solves the planning problem. * Solves the planning problem and returns the best solution encountered (which might or might not be optimal).
* It can take minutes, even hours or days before this method returns, * <p>
* depending on the termination configuration. * It can take seconds, minutes, even hours or days before this method returns,
* depending on the {@link Termination} configuration.
* To terminate a {@link Solver} early, call {@link #terminateEarly()}. * To terminate a {@link Solver} early, call {@link #terminateEarly()}.
* @param planningProblem never null, usually its planning variables are uninitialized * @param planningProblem never null, usually its planning variables are uninitialized
* @return never null, but it can return the original, uninitialized {@link Solution} with a {@link Score} null.
* @see #terminateEarly() * @see #terminateEarly()
*/ */
Solution_ solve(Solution_ planningProblem); Solution_ solve(Solution_ planningProblem);
Expand Down
Expand Up @@ -20,51 +20,60 @@


import org.junit.Test; import org.junit.Test;
import org.optaplanner.core.config.solver.termination.TerminationConfig; import org.optaplanner.core.config.solver.termination.TerminationConfig;
import org.optaplanner.core.impl.testdata.domain.TestdataSolution;


import static org.junit.Assert.*; import static org.junit.Assert.*;


public class SolverFactoryTest { public class SolverFactoryTest {


@Test @Test
public void testdataSolverConfig() { public void testdataSolverConfigWithoutGenericsForBackwardsCompatibility() {
SolverFactory solverFactory = SolverFactory.createFromXmlResource( SolverFactory solverFactory = SolverFactory.createFromXmlResource(
"org/optaplanner/core/api/solver/testdataSolverConfig.xml"); "org/optaplanner/core/api/solver/testdataSolverConfig.xml");
Solver solver = solverFactory.buildSolver(); Solver solver = solverFactory.buildSolver();
assertNotNull(solver); assertNotNull(solver);
} }


@Test
public void testdataSolverConfig() {
SolverFactory<TestdataSolution> solverFactory = SolverFactory.createFromXmlResource(
"org/optaplanner/core/api/solver/testdataSolverConfig.xml");
Solver<TestdataSolution> solver = solverFactory.buildSolver();
assertNotNull(solver);
}

@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void nonExistingSolverConfig() { public void nonExistingSolverConfig() {
SolverFactory solverFactory = SolverFactory.createFromXmlResource( SolverFactory<TestdataSolution> solverFactory = SolverFactory.createFromXmlResource(
"org/optaplanner/core/api/solver/nonExistingSolverConfig.xml"); "org/optaplanner/core/api/solver/nonExistingSolverConfig.xml");
Solver solver = solverFactory.buildSolver(); Solver<TestdataSolution> solver = solverFactory.buildSolver();
assertNotNull(solver); assertNotNull(solver);
} }


@Test @Test
public void testdataSolverConfigWithClassLoader() throws ClassNotFoundException, IOException { public void testdataSolverConfigWithClassLoader() throws ClassNotFoundException, IOException {
// Mocking loadClass doesn't work well enough, because the className still differs from class.getName() // Mocking loadClass doesn't work well enough, because the className still differs from class.getName()
ClassLoader classLoader = new DivertingClassLoader(getClass().getClassLoader()); ClassLoader classLoader = new DivertingClassLoader(getClass().getClassLoader());
SolverFactory solverFactory = SolverFactory.createFromXmlResource( SolverFactory<TestdataSolution> solverFactory = SolverFactory.createFromXmlResource(
"divertThroughClassLoader/org/optaplanner/core/api/solver/classloaderTestdataSolverConfig.xml", classLoader); "divertThroughClassLoader/org/optaplanner/core/api/solver/classloaderTestdataSolverConfig.xml", classLoader);
Solver solver = solverFactory.buildSolver(); Solver<TestdataSolution> solver = solverFactory.buildSolver();
assertNotNull(solver); assertNotNull(solver);
} }


@Test @Test
public void cloneSolverFactory() { public void cloneSolverFactory() {
SolverFactory solverFactoryTemplate = SolverFactory.createFromXmlResource( SolverFactory<TestdataSolution> solverFactoryTemplate = SolverFactory.createFromXmlResource(
"org/optaplanner/core/api/solver/testdataSolverConfig.xml"); "org/optaplanner/core/api/solver/testdataSolverConfig.xml");
solverFactoryTemplate.getSolverConfig().setTerminationConfig(new TerminationConfig()); solverFactoryTemplate.getSolverConfig().setTerminationConfig(new TerminationConfig());
SolverFactory solverFactory1 = solverFactoryTemplate.cloneSolverFactory(); SolverFactory<TestdataSolution> solverFactory1 = solverFactoryTemplate.cloneSolverFactory();
SolverFactory solverFactory2 = solverFactoryTemplate.cloneSolverFactory(); SolverFactory<TestdataSolution> solverFactory2 = solverFactoryTemplate.cloneSolverFactory();
assertNotSame(solverFactory1, solverFactory2); assertNotSame(solverFactory1, solverFactory2);
solverFactory1.getSolverConfig().getTerminationConfig().setMinutesSpentLimit(1L); solverFactory1.getSolverConfig().getTerminationConfig().setMinutesSpentLimit(1L);
solverFactory2.getSolverConfig().getTerminationConfig().setMinutesSpentLimit(2L); solverFactory2.getSolverConfig().getTerminationConfig().setMinutesSpentLimit(2L);
assertEquals((Long) 1L, solverFactory1.getSolverConfig().getTerminationConfig().getMinutesSpentLimit()); assertEquals((Long) 1L, solverFactory1.getSolverConfig().getTerminationConfig().getMinutesSpentLimit());
assertEquals((Long) 2L, solverFactory2.getSolverConfig().getTerminationConfig().getMinutesSpentLimit()); assertEquals((Long) 2L, solverFactory2.getSolverConfig().getTerminationConfig().getMinutesSpentLimit());
Solver solver1 = solverFactory1.buildSolver(); Solver<TestdataSolution> solver1 = solverFactory1.buildSolver();
Solver solver2 = solverFactory2.buildSolver(); Solver<TestdataSolution> solver2 = solverFactory2.buildSolver();
assertNotSame(solver1, solver2); assertNotSame(solver1, solver2);
} }


Expand Down
Expand Up @@ -953,7 +953,7 @@
a server restart. This cannot be configured by a <literal>Termination</literal> as it's impossible to predict when a server restart. This cannot be configured by a <literal>Termination</literal> as it's impossible to predict when
and if it will occur. Therefore the <literal>Solver</literal> interface has these 2 thread-safe methods:</para> and if it will occur. Therefore the <literal>Solver</literal> interface has these 2 thread-safe methods:</para>


<programlisting language="java">public interface Solver { <programlisting language="java">public interface Solver&lt;S extends Solution&gt; {


// ... // ...


Expand All @@ -977,12 +977,12 @@
<para>To listen to such events, add a <literal>SolverEventListener</literal> to the <para>To listen to such events, add a <literal>SolverEventListener</literal> to the
<literal>Solver</literal>:</para> <literal>Solver</literal>:</para>


<programlisting language="java">public interface Solver { <programlisting language="java">public interface Solver&lt;S extends Solution&gt; {


// ... // ...


void addEventListener(SolverEventListener&lt;? extends Solution&gt; eventListener); void addEventListener(SolverEventListener&lt;S&gt; eventListener);
void removeEventListener(SolverEventListener&lt;? extends Solution&gt; eventListener); void removeEventListener(SolverEventListener&lt;S&gt; eventListener);


}</programlisting> }</programlisting>


Expand Down

0 comments on commit 1f2e52a

Please sign in to comment.