/*
* Copyright 2010 Red Hat, Inc. and/or its affiliates.
*
* Licensed 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 org.optaplanner.core.config.solver;
import java.util.Random;
import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.impl.heuristic.move.Move;
import org.optaplanner.core.impl.score.director.ScoreDirector;
/**
* The environment mode also allows you to detect common bugs in your implementation.
* <p>
* Also, a {@link Solver} has a single {@link Random} instance.
* Some optimization algorithms use the {@link Random} instance a lot more than others.
* For example simulated annealing depends highly on random numbers,
* while tabu search only depends on it to deal with score ties.
* This environment mode influences the seed of that {@link Random} instance.
*/
public enum EnvironmentMode {
/**
* This mode turns on all assertions
* to fail-fast on a bug in a {@link Move} implementation, a score rule, the rule engine itself or something else
* at a horrible performance cost.
* <p>
* This mode is reproducible (see {@link #REPRODUCIBLE} mode).
* <p>
* This mode is intrusive because it calls the {@link ScoreDirector#calculateScore()} more frequently
* than a non assert mode.
* <p>
* This mode is horribly slow.
*/
FULL_ASSERT,
/**
* This mode turns on several assertions (but not all of them)
* to fail-fast on a bug in a {@link Move} implementation, a score rule, the rule engine itself or something else
* at a horrible performance cost.
* <p>
* This mode is reproducible (see {@link #REPRODUCIBLE} mode).
* <p>
* This mode is non-intrusive, unlike {@link #FULL_ASSERT} and {@link #FAST_ASSERT}.
* <p>
* This mode is horribly slow.
*/
NON_INTRUSIVE_FULL_ASSERT,
/**
* This mode turns on several assertions (but not all of them)
* to fail-fast on a bug in a {@link Move} implementation, a score rule, the rule engine itself or something else
* at a reasonable performance cost (in development at least).
* <p>
* This mode is reproducible (see {@link #REPRODUCIBLE} mode).
* <p>
* This mode is intrusive because it calls the {@link ScoreDirector#calculateScore()} more frequently
* than a non assert mode.
* <p>
* This mode is slow.
*/
FAST_ASSERT,
/**
* The reproducible mode is the default mode because it is recommended during development.
* In this mode, 2 runs on the same computer will execute the same code in the same order.
* They will also yield the same result, except if they use a time based termination
* and they have a sufficiently large difference in allocated CPU time.
* This allows you to benchmark new optimizations (such as a new Move implementation) fairly.
* <p>
* Warning: some code can disrupt reproducibility regardless of this mode. See the reference manual for more info.
* <p>
* In practice, this mode uses the default random seed,
* and it also disables certain concurrency optimizations (such as work stealing).
* TODO: PLANNER-76 Multi-threaded support which implement those concurrency optimizations
*/
REPRODUCIBLE,
/**
* This mode has been renamed to {@link #NON_REPRODUCIBLE}
* because most users prefer to use {@link #REPRODUCIBLE} in production.
* @deprecated Use {@link #NON_REPRODUCIBLE} instead. Will be removed in 8.0.
*/
@Deprecated
PRODUCTION,
/**
* The non reproducible mode is equally fast or slightly faster than {@link #REPRODUCIBLE}.
* <p>
* The random seed is different on every run, which makes it more robust against an unlucky random seed.
* An unlucky random seed gives a bad result on a certain data set with a certain solver configuration.
* Note that in most use cases the impact of the random seed is relatively low on the result.
* An occasional bad result is far more likely to be caused by another issue (such as a score trap).
* <p>
* In multi-threaded scenario's, this mode allows the use of work stealing and other non deterministic speed tricks.
*/
NON_REPRODUCIBLE;
public boolean isAsserted() {
switch (this) {
case FULL_ASSERT:
case NON_INTRUSIVE_FULL_ASSERT:
case FAST_ASSERT:
return true;
case REPRODUCIBLE:
case NON_REPRODUCIBLE:
return false;
default:
throw new IllegalStateException("The environmentMode (" + this + ") is not implemented.");
}
}
public boolean isNonIntrusiveFullAsserted() {
switch (this) {
case FULL_ASSERT:
case NON_INTRUSIVE_FULL_ASSERT:
return true;
case FAST_ASSERT:
case REPRODUCIBLE:
case NON_REPRODUCIBLE:
return false;
default:
throw new IllegalStateException("The environmentMode (" + this + ") is not implemented.");
}
}
public boolean isIntrusiveFastAsserted() {
switch (this) {
case FULL_ASSERT:
case FAST_ASSERT:
return true;
case NON_INTRUSIVE_FULL_ASSERT:
case REPRODUCIBLE:
case NON_REPRODUCIBLE:
return false;
default:
throw new IllegalStateException("The environmentMode (" + this + ") is not implemented.");
}
}
public boolean isReproducible() {
switch (this) {
case FULL_ASSERT:
case NON_INTRUSIVE_FULL_ASSERT:
case FAST_ASSERT:
case REPRODUCIBLE:
return true;
case NON_REPRODUCIBLE:
return false;
default:
throw new IllegalStateException("The environmentMode (" + this + ") is not implemented.");
}
}
}