Solver
A solver is an iterative algorithm that searches for the optimal solution to a defined problem. In this abstract base class, the algorithm is conceptualized as having a main iterative loop. The loop is the main loop that ultimately determines the convergence of the algorithm and recommended solution. Some algorithms have "inner" loops". In general, inner loops are used to control localized search for solutions. If an algorithm has additional inner loops, these can be embedded within the main loop via the subclassing process.
Specialized implementations may have specific methods for determining stopping criteria; however, to avoid the execution of a large number of iterations, the iterative process has a specified maximum number of iterations.
Within the context of simulation optimization, the supplied evaluator promises to execute requests for evaluations of the simulation model at particular design points (as determined by the algorithm). In addition, because of the stochastic nature of the evaluation, the solver may request one or more replications for its evaluation requests. The number of replications may dynamically change, and thus the user needs to supply a function to determine the number of replications per evaluation. Within the framework of the hooks for subclasses, the user could specify more complex procedures for determining the number of replications per evaluation.
Parameters
the problem being solved
the reference to the evaluator for evaluating responses from the model
the maximum number of iterations permitted for the main loop. This must be greater than 0.
the function controlling how many replications are requested for each evaluation
a name to help with identifying the solver when multiple solvers are used on a problem
Inheritors
Constructors
A solver is an iterative algorithm that searches for the optimal solution to a defined problem. In this abstract base class, the algorithm is conceptualized as having a main iterative loop. The loop is the main loop that ultimately determines the convergence of the algorithm and recommended solution. Some algorithms have "inner" loops". In general, inner loops are used to control localized search for solutions. If an algorithm has additional inner loops, these can be embedded within the main loop via the subclassing process.
Properties
The best solution found so far in the search. Some algorithms may allow the current solution to vary from the best solution due to randomness or other search needs (e.g., explore bad areas with the hope of getting better). The algorithm should ensure the updating of the best solution found across any iteration.
A read-only view of the best solutions evaluated by the solver. Not all solvers retain past solutions. Also, in general, the evaluator may have access to a cache of solutions.
Represents the current point (input settings) of the solver during its iterative process.
The current (or last) solution that was accepted as a possible solution to recommend for the solver. It is the responsibility of the subclass to determine the current solution.
Indicates whether the solver allows infeasible requests to be sent to the evaluator. The default is false. That is, the solver is allowed to send infeasible problem requests for evaluation by the evaluator.
The evaluator used by the solver.
The initial point associated with the initial solution.
Returns the number of times the main iteration function was called.
Allow the status of the iterative process to be accessible
The maximum number of iterations when sampling for an input feasible point
The maximum number of iterations permitted for the main loop. This must be greater than 0.
Permits capture of evaluated solutions locally by the solver. Not all solvers retain past solutions. Also, in general, the evaluator will have access to a cache of solutions.
The initial starting solution for the algorithm. It is the responsibility of the subclass to initialize the initial solution.
The user can supply a function that will generate a neighbor for the evaluation process. If supplied, this function will be used instead of the pre-defined generateNeighbor() function. The user may also override the generateNeighbor() function when developing subclasses.
A variable that tracks the total number of simulation oracle calls.
A variable that tracks the total number of simulation replications requested.
The difference between the current solution's penalized objective function value and the previous solution's penalized objective function value.
The previous point in the solution process. It is associated with the previous solution.
The previous solution in the sequence of solutions.
If a listener is attached to the solver via its iterationEmitter property, then snapshots of the solver's state are captured at the end of each iteration according to this specified frequency. For example, if the frequency is 10, then every 10th iteration is emitted. The default is 1. If nothing listens for emissions, then no snapshots are emitted.
The user can supply a comparator for comparing whether one solution is smaller, equal to, or larger than another solution. If supplied, this function will be used instead of the implemented compare() function. The user can supply a function or override the compare function to specialize how solutions are compared.
Many algorithms compare solutions. This factor serves as the criteria when comparing two solutions such that if the solutions are within this value they are considered equal. The default is defaultSolutionPrecision. Algorithms may or may not use this criterion.
A variable representing an instance of the SolutionQualityEvaluatorIfc interface. It is used to assess and evaluate the quality of a given solution. The variable can hold a nullable implementation of the interface.
Captures the current results of the optimization run. Guarantees a valid result object, returning a pending state if not yet executed.
An initial starting point for the solver. If supplied, this point will be used instead of the returned value of the startingPoint() function. The default is null, which indicates that the function should be called to obtain the initial starting point.
The difference between the current solution's unpenalized objective function value and the previous solution's unpenalized objective function value.
Functions
This function is called after the function mainIteration() executes. Provides a hook for additional after-iteration logic, which could be placed here instead of at the end of the mainIteration() function.
This function is called before the function mainIteration() is executed. Provides a hook for additional pre-iteration logic, which could be placed here instead of at the beginning of the mainIteration() function.
Clears the best solutions captured by the solver. The solver will retain all best solutions that have been observed until they are cleared, even with repeated use.
Recognizing the need to be able to compare solutions that may have sampling error, the user can override this function to provide more extensive comparison or supply an instance of the Comparator
Creates a request for evaluation from the input map. The number of replications for the request will be based on the property replicationsPerEvaluation for the solver. The resulting request will be input range-feasible but may be infeasible with respect to the problem. If the user does not allow infeasible requests by setting the ensureProblemFeasibleRequests to false, then this function will throw an exception if the supplied input is infeasible with respect to the deterministic constraints of the problem.
Note that the iterations can only be ended before running all iterations or before running the next iteration. Use stopIterations() to cause a graceful completion of inner and outer iterations.
A hook for subclasses to inject their specific internal state metrics into the snapshot without having to override the entire makeSolverStateSnapshot method.
Generates a random neighbor of the current point that satisfies input feasibility constraints. The method attempts to generate a feasible point by randomizing the input variables of the current point. If a feasible point cannot be generated within a maximum number of iterations, an exception is thrown.
Generates a neighboring point based on the current point represented by the input map. This method determines the next potential point in the iterative process, either through a neighbor generator or by randomizing the value of a randomly selected input variable. Unless a neighborhood generator is supplied, the resulting point will be input-range feasible. Thus, it may be infeasible with respect to deterministic constraints. If a neighborhood generator is not supplied, the approach is to randomly select one of the coordinates (inputs) and then randomly generating an input-range feasible value for the selected input.
Checks if the iterative process has additional iterations to execute. This does not check other stopping criteria related to solution quality or convergence. This is about how many iterations have been executed from the maximum specified.
Causes the solver to be initialized. It will then be in a state that allows for the running of the iterations.
Subclasses may implement this function to prepare the solver before running the first iteration. Generally, it is sufficient to just implement the startingPoint() function.
Subclasses should implement this function to determine if the solver should continue running iterations. This will likely include some implementation of stopping criteria. This function should implement stopping criteria based on the quality of the solution. The number of iterations, compared to the maximum number of iterations, is automatically checked after each step in the iterative process. Unless overridden, this function returns false by default, which indicates that the solution quality criteria have not been satisfied. This will cause the solver to iterate through all iterations of the solution process up to the maximum number of iterations. Alternatively, the user can specify an instance of the SolutionQualityEvaluatorIfc interface to determine if the solution quality has been reached.
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.
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.
Creates an immutable snapshot of the solver's current state. This is typically called at the end of an iteration to broadcast the state to any attached listeners safely.
Returns the smaller of the two solutions. Ties result in the first solution being returned. This function uses the supplied comparator.
Prints the current results of the optimization run to the console. This includes details about the solver's performance,
Requests an evaluation for a single input map and returns the resulting solution. The function prepares the input as an evaluation request, performs the evaluation, and subsequently emits and logs the resulting solution. CRN is not permitted for a single evaluation.
Requests evaluations for a set of input maps. The function prepares the evaluation requests from the provided inputs and then performs evaluations to generate solutions.
Requests evaluations for a set of input maps. The function prepares the evaluation requests from the provided inputs and then performs evaluations to generate solutions. The evaluations will be performed using the common random numbers.
Causes the solver to run all iterations until its stopping criteria is met, or the maximum number of iterations has been reached.
Runs the next iteration. Only valid if the solver has been initialized and there are additional iterations to run.
Defines and specifies the starting point for the solver's iterative process. This function is intended to be overridden in subclasses to provide an initial setting of input values for the solver.
Causes a graceful stopping of the iterative processes for the solver. The inner process will complete its current iteration, and then no more outer iterations will start.