SolverPortfolio

class SolverPortfolio @JvmOverloads constructor(problemDefinition: ProblemDefinition, evaluator: EvaluatorIfc, val members: List<SolverMemberTask>, memberEvaluatorFactory: MemberEvaluatorFactoryIfc, val concurrentOptions: ConcurrentRunOptions = ConcurrentRunOptions(), replicationsPerEvaluation: ReplicationPerEvaluationIfc = FixedReplicationsPerEvaluation(defaultReplicationsPerEvaluation), streamNum: Int = 0, streamProvider: RNStreamProviderIfc = RNStreamProvider(), name: String? = null) : StochasticSolver(source)

A solver portfolio: N solver instances — typically of different algorithms — race on the same problem concurrently, each on its own worker with its own factory-created solver and private evaluation resources, and the portfolio reports the best solution found across all members.

The portfolio is itself a solver, following the convention the random-restart solver established: the maximum number of iterations equals the member count, and outer iteration k blocks until member k completes, no matter which member happened to finish first. Trackers, snapshots, and results therefore see a deterministic per-member sequence, and the whole orchestration/reporting stack works on a portfolio unchanged.

Reproducibility follows the concurrent-substrate rules: member starting points are fixed at launch (per task, or inherited from the portfolio's starting point), member solvers own fresh stream providers, and each member's simulation streams occupy a dedicated block of the sub-stream tape — so results do not depend on scheduling or the worker count.

Because members may estimate their bests with different statistical precision (different replication budgets, different luck), picking the winner from raw point estimates favors noise. Configure a confirmation stage via ConcurrentRunOptions.confirmation to re-evaluate the top member bests under common random numbers; the confirmed winner becomes the final current solution and the full outcome is available via confirmationOutcome.

Starting points: a member task with its own starting point keeps it. Members without one inherit the portfolio's starting point when set (racing algorithms from a common start), and otherwise generate their own.

Parameters

problemDefinition

the problem all members solve

evaluator

the portfolio's own evaluator; used for the initial-point evaluation and the optional confirmation stage (member evaluations never route through it)

members

the member tasks, in reporting order; labels must be unique

memberEvaluatorFactory

provisions each member's private evaluation resources

concurrentOptions

worker count, stream-block size, and optional confirmation

replicationsPerEvaluation

the replication strategy for the portfolio's own evaluations (the initial point)

streamNum

the random number stream number for the portfolio driver

streamProvider

the stream provider for the portfolio driver

name

optional name identifier for this instance of the solver

Constructors

Link copied to clipboard
constructor(problemDefinition: ProblemDefinition, evaluator: EvaluatorIfc, members: List<SolverMemberTask>, memberEvaluatorFactory: MemberEvaluatorFactoryIfc, concurrentOptions: ConcurrentRunOptions = ConcurrentRunOptions(), replicationsPerEvaluation: ReplicationPerEvaluationIfc = FixedReplicationsPerEvaluation(defaultReplicationsPerEvaluation), streamNum: Int = 0, streamProvider: RNStreamProviderIfc = RNStreamProvider(), name: String? = null)

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard

Flat representation: each member prototype's keys are re-emitted with a dotted, indexed prefix (member.0.label, member.0.solverName, ...) so the resulting map stays flat and TOML-friendly.

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 member 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

The results of the members, in member order, as consumed so far. Complete after the portfolio finishes running.

Link copied to clipboard
Link copied to clipboard

The number of members in the portfolio.

Functions

Link copied to clipboard
protected open override fun extractSolverSpecificState(): Map<String, Double>?

A hook for subclasses to inject their specific internal state metrics into the snapshot without having to override the entire makeSolverStateSnapshot method.

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