RandomRestartSolver

A class that implements the Random Restart optimization algorithm. This algorithm repeatedly runs an inner solver, each run beginning at a different (randomly generated) starting point, and reports the best solution found across all runs.

Two execution modes are supported:

Sequential mode (the historical behavior, and the default): one inner solver instance is reused, run to completion once per restart, with the evaluator's solution cache optionally cleared between runs. Construct via the instance-based constructor, or via the factory-based constructor with concurrentRestarts = 1.

Concurrent mode (concurrentRestarts > 1, factory-based constructor only): restarts are statistically independent, so up to concurrentRestarts of them run at the same time, each on its own worker with its own solver instance (created by the supplied SolverFactoryIfc) and its own private evaluation resources (provisioned by the supplied MemberEvaluatorFactoryIfc, typically a PooledMemberEvaluatorFactory). Starting points for all restarts are pre-drawn from the outer solver's stream before launching, and each restart's simulation streams occupy a dedicated block of the sub-stream tape — so results are reproducible and do not depend on scheduling or the worker count. Restart results are consumed in submission order: outer iteration k reports restart k, keeping trackers and snapshots deterministic. Because each concurrent restart owns a private, freshly created solution cache, "clear the cache between runs" is structural in this mode; setting clearCacheBetweenRuns to false is not supported concurrently.

Note that the two modes consume randomness differently (one continuous stream tape versus per-restart blocks), so sequential and concurrent runs of the same seed are each reproducible but are not numerically identical to each other.

An optional confirmation stage (see ConcurrentRunOptions.confirmation) re-evaluates the best solutions of the completed restarts under common random numbers after all restarts finish, and reports the confirmed winner as the final current solution; the full outcome is available via confirmationOutcome.

Constructors

Link copied to clipboard
constructor(restartingSolver: Solver, maxNumRestarts: Int = defaultMaxRestarts, streamNum: Int = 0, streamProvider: RNStreamProviderIfc = RNStreamProvider(), name: String? = null)

Constructs a sequential random-restart solver around an existing inner solver instance. This is the historical constructor: the instance is reused for every restart, one restart at a time.

constructor(problemDefinition: ProblemDefinition, evaluator: EvaluatorIfc, solverFactory: SolverFactoryIfc, memberEvaluatorFactory: MemberEvaluatorFactoryIfc? = null, maxNumRestarts: Int = defaultMaxRestarts, concurrentRestarts: Int = 1, concurrentOptions: ConcurrentRunOptions = ConcurrentRunOptions(), replicationsPerEvaluation: ReplicationPerEvaluationIfc = FixedReplicationsPerEvaluation(defaultReplicationsPerEvaluation), streamNum: Int = 0, streamProvider: RNStreamProviderIfc = RNStreamProvider(), name: String? = null)

Constructs a factory-based random-restart solver, capable of running restarts concurrently.

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard

Indicates whether the evaluator cache should be cleared between runs. Defaults to true. If the evaluator does not support caching, this value is ignored. In concurrent mode this is structural (each restart's cache is private and born empty); setting it to false with concurrent restarts is rejected at initialization.

Link copied to clipboard
Link copied to clipboard

Flat representation: the inner solver's keys are re-emitted with an innerSolver. prefix so the resulting map stays flat and TOML-friendly (no nested tables, every entry a simple key/value pair).

Link copied to clipboard

The outcome of the confirmation stage, when one was configured via ConcurrentRunOptions.confirmation and the run completed without a stop request; null otherwise. The confirmed winner is also reported as the final current solution. Note that the solver's best-solutions record keeps the unconfirmed restart bests as well, so bestSolution may still report an unconfirmed (noise-favored) point; consult this property when a confirmation stage is in use.

Link copied to clipboard
var innerSolverDecorator: (solver: Solver, restartIndex: Int) -> Unit?

Invoked with each freshly created inner solver and its restart index, before the restart runs. This is the attachment hook for per-restart trackers and other instrumentation. In concurrent mode it is called on worker threads, so anything it touches must be thread-safe (e.g. give each restart its own tracker/file). Not used in sequential mode, where trackers attach to restartingSolver directly.

Link copied to clipboard

True when this solver runs its restarts concurrently.

Link copied to clipboard

The inner solver used by the randomized restarts. In sequential mode this is the (single, reused) run instance. In concurrent mode the run instances are created per restart by the solver factory, and this property holds a prototype instance — created once from the factory, never run — so configuration reporting and tracking probes that inspect the inner solver keep working.

Functions

Link copied to clipboard
protected open override fun initializeIterations()

Subclasses may implement this function to prepare the solver before running the first iteration. Generally, it is sufficient to just implement the startingPoint() function.

Link copied to clipboard
protected open override fun mainIteration()

This function should contain the logic that iteratively executes until the maximum number of iterations is reached or until the stopping criteria is met. The base implementation calls nextPoint() to determine the next point to evaluate, requests an evaluation of the point, and then updates the current solution if the resulting solution is better than the current solution. Generally, implementing startingPoint() and nextPoint() should be adequate. The property iterationCounter represents the current iteration within the mainIteration() function. That is, the value of iterationCounter is incremented prior to the execution of the mainIteration() function.

Link copied to clipboard
protected open override fun mainIterationsEnded()

Subclasses should implement this function to clean up after running all iterations. That is, after the main iteration has stopped. This may include such concepts as selecting the best once all iterations have completed.

Link copied to clipboard
protected open override fun onStopRequested(msg: String?)

A hook invoked when stopIterations() is called, before the solver's own iterative process is signaled to stop. The stop flag of the iterative process is only checked between outer iterations, so a composite solver that blocks inside an iteration waiting on inner solvers (possibly running on other threads) overrides this to forward the stop request to those in-flight inner solvers. The default does nothing.

Link copied to clipboard
open override fun toString(): String