ksl.simopt.solvers package provides a general framework for designing and implementing simulation optimization algorithms.solver package provides the Solver abstract base class that can be specialized to implement different algorithms.The StochasticSolver inherits from the Solver class and requires that a source of random streams be provided. It also allows stream control.
abstract class StochasticSolver(
problemDefinition: ProblemDefinition,
evaluator: EvaluatorIfc,
maxIterations: Int,
replicationsPerEvaluation: ReplicationPerEvaluationIfc,
streamNum: Int = 0,
val streamProvider: RNStreamProviderIfc = KSLRandom.DefaultRNStreamProvider,
name: String? = null
) : Solver(problemDefinition, evaluator, maxIterations, replicationsPerEvaluation, name), RNStreamControlIfc {A solver is an iterative algorithm that searches for the optimal solution for a defined problem. In the abstract Solver class, the algorithm is conceptualized as having a main iterative loop. The basic algorithm is structured conceptually as an iterative loop:
The Solver class has three abstract protected functions that must be implemented.
protected abstract fun startingPoint(): InputMap - The purpose of this function is to determine the starting point for the solver’s process. In the default implementation, this function is called from the initializeIterations() function.protected abstract fun nextPoint(): InputMap - The purpose of this function is to determine the next point to be evaluated for the solver’s process. Specific implementations will call this function within their implementations of the mainIteration() function.protected abstract fun mainIteration() - The purpose of this function is to contain the logic that iteratively executes until the maximum number of iterations is reached or until the stopping criteria is met.The Solver class has protected open functions that can be overridden with more specific behavior:
protected open fun initializeIterations() - This function is called prior to the running of the main loop of iterations.
protected open fun beforeMainIteration() - An empty hook function to permit logic to be inserted prior to the call to mainIteration().protected open fun afterMainIteration() - An empty hook function to permit logic to be inserted after the call to mainIteration().protected open fun mainIterationsEnded() - An empty hook function to permit logic to be inserted after the main iterative loop completes.protected open fun isStoppingCriteriaSatisfied(): Boolean - This function is called from checkStoppingCondition() within the iterative loop.solutionQualityEvaluator property that will be used from within this function.protected open fun generateNeighbor(currentPoint: InputMap,rnStream: RNStreamIfc): InputMapGenerateNeighborIfc interface via the neighborGenerator property.neighborGenerator is not supplied, the base algorithm, randomly selects one of the coordinates from the current point and then randomly generates an input range feasible value for the coordinate.
override fun mainIteration() {
// generate a random neighbor of the current solution
val nextPoint = nextPoint()
// evaluate the solution
val nextSolution = requestEvaluation(nextPoint)
if (compare(nextSolution, currentSolution) < 0) {
currentSolution = nextSolution
}
// capture the last solution
solutionChecker.captureSolution(currentSolution)
}startingPoint() and nextPoint() both inherited from StochasticSolver are as follows:nextPoint() leverages the availability of the supplied generateNeighbor() function.startingPoint() function will use an instance of the StartingPointIfc interface via the startingPointGenerator property or rely on the problem definition to randomly generate an input feasible point.
An implementation of a solver must at the very least specify:
startingPoint()),nextPoint()), andmainIteration()).New solvers can be constructed by sub-classing from Solver or StochasticSolver or by modifying the basic behavior by plugging in different functions.
Functional interfaces provide the ability to specify plug-in behavior by supplying a different implementation for one of these interfaces.
ReplicationPerEvaluationIfc interface - This functional interface can be used by solvers to determined the number of replications to request when asking the simulation oracle for evaluations.GenerateNeighborIfc interface - This functional interface can be used by solvers to specify how to generate a neighbor relative to the supplied input.NeighborSelectorIfc interface - This functional interface defines functions for selecting a neighbor (point) from a defined neighborhood represented as as set containing inputs.SolutionQualityStoppingCriteriaIfc interface - This functional interface represents functions that define when to stop the iterative process based on the quality of the solution.FixedReplicationsPerEvaluation and FixedGrowthRateReplicationSchedule classes.
ReplicationPerEvaluationIfc by implementing it.replicationsPerEvaluation property of the solver.GenerateNeighborIfc interface - This functional interface can be used by solvers to specify how to generate a neighbor relative to the supplied input.ensureFeasibility parameter should indicate if the generation method should ensure that the returned input map is feasible with respect the constraints of the problem.generateNeighbor() function randomly select one of the coordinates (inputs) and then randomly generates an input-range feasible value for the selected input.
generateNeighbor(currentPoint: InputMap,rnStream: RNStreamIfc) function, orGenerateNeighborIfc interface and set the neighborGenerator property with the instanceNeighborSelectorIfc interface - This functional interface defines functions for selecting a neighbor (point) from a defined neighborhood represented as as set containing inputs. The supplied solver could be used to allow memory during the selection process.SolutionQualityStoppingCriteriaIfc interface - This functional interface represents functions that define when to stop the iterative process based on the quality of the solution.
The solutionQualityEvaluator property will be used when the stopping criteria is evaluated within the main loop.
The solutionQualityEvaluator property provides the user with an approach to overriding the base behavior with different behavior rather than through sub-classing.
currentPoint: Represents the current point (input settings) of the solver during its iterative process.
inputMap of the currently active solution, which reflects the solver’s progress in finding optimal or improved solutions.currentSolution: 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.initialSolution: The initial starting solution for the algorithm. It is the responsibility of the subclass of Solver to initialize the initial solution.startingPoint: An initial starting point for the solver. If supplied, this point will be used instead of the returned value of the startingPoint() function.
previousPoint and previousSolution: The previously evaluated point and the previously resulting solution.iterationCounter - The iterationCounter property counts the number of iterations performed by a solver. Since some solvers may used additional stopping criteria, this property can be used to assess the total number of iterations performed.numOracleCalls - Each time a solver requests evaluations from the oracle, this property is incremented. It can be used to indicate how may simulation evaluations were performed. Since simulation evaluations can be computationally expensive, this property can help understand how efficient a solver is with respect to simulation evaluations.numReplicationsRequested - Similar to the numOracleCalls property, this property totals the number of replications requested during the solver’s execution. This property can help understand how efficient a solver is in terms of its sampling.iterativeProcess - This property references the underlying iterative process via the IterativeProcessStatusIfc interface.beginExecutionTime and endExecutionTime properties can be used to compute the total time spent by the solver.currentSolution: The current (or last) solution that was accepted as a possible solution to recommend for the solver.
myBestSolutions protected property is used to capture the newly assigned solution. The protected myBestSolutions property is an instance of the Solutions class.bestSolutions property provides access to the solutions via the SolutionsIfc interface.SolutionsIfc implements the List<Solution> interface, which allows instances of the Solutions class to be treated as a list.Solutions class provides an ordering to the solutions based on the order in which they are added to the list and based on the value of the penalized objective function.Solutions class is like a cache, with a default capacity. It also controls whether it can store infeasible solutions.Solutions class allows mutability by providing specialized add(), addAll(), and remove() functions.peekBest(): Solution? - This function returns the solution with the lowest penalized objective function value.possiblyBest(comparator: Comparator<Solution>): Solutions - This function returns a list of solutions that are possibly the best using the supplied comparator.possiblyBest(level: Double = DEFAULT_CONFIDENCE_LEVEL,indifferenceZone: Double = 0.0): Solutions - This function returns solutions that could be considered best using a penalized objective function confidence interval comparator.
SolutionChecker class is designed to hold and test if its contained solutions are all the same.SolutionEqualityIfc interface is to provide a mechanism to check for the equality between two solutionsConfidenceIntervalEquality - This class checks for equality between solutions based whether the confidence interval on the difference contains the indifference zone parameter. This is based on an approximate confidence interval on the difference between the unpenalized objective function values.PenalizedObjectiveFunctionEquality - This class checks if the penalized objective function values are within some specified precision. The uncertainty of the values is not taken into consideration.InputEquality This class indicates that two solutions are equal based only on the values of their inputs. If the solutions do not have the same inputs, then the penalized objective function is used to determine the ordering. Thus, two solutions are considered the same if they have the same input values, regardless of the value of the objective functions.InputsAndConfidenceIntervalEquality - This class checks for equality between solutions based whether the confidence interval on the difference contains the indifference zone parameter and whether the input variable values are the same.SolutionChecker ClassSolutionChecker class uses an instance of the SolutionEqualityIfc interface to check if the elements that it holds all test as equal.checkSolutions() function, which will return true if the all the contained solutions test as equal. The specified threshold limit also specifies the capacity.SolutionChecker class can be used as part of the logic for checking if the stopping criteria for the algorithm indicates if the algorithm should stop.StochasticHillClimber - A stochastic hill climbing solver implements the idea of randomly moving through the search space. As new solutions are found, the current solution is updated if the next solution is better than the previous solution. Variations of stochastic hill climbing involve how to select points. It is one of the simplest algorithms to implement and it is still useful because in the limit, the algorithm will eventually visit the optimal solution.SimulatedAnnealing - Simulated annealing is a stochastic optimization algorithm that models the optimization process based on an analogy with a metallurgical annealing process. For further background on simulation annealing, the interested reader should consider this on-line book.CrossEntropySolver - The cross-entropy method is a population based algorithm that is based on minimizing the cross-entropy between a target distribution and a parametric distribution. While designed for deterministic optimization problems, the cross-entropy method has also been applied to stochastic optimization problems.RSplineSolver - This method is designed for integer-ordered (discrete) optimization problems. The overall theory guarantees convergence to locally optimal solutions.RandomRestartSolver - Many solvers require an initial starting point. The algorithm’s final solution may be sensitive to the choice of the initial starting point. This solver permits other solvers to be called repeatedly for randomly selected starting points.Pseudo-code for the overall algorithm is as follows:
1. Initialize the solution and the temperature
2. While not converged
2.1. Generate a possible solution based on some probabilistic process
2.2. Calculate the change in the objective function
2.3. If an improvement or acceptance probability is met
2.3.1 accept the new solution
2.4 Reduce the temparture according the cooling schedule
3. Return the best solution found
temperatureConfiguration - How the starting temperature is chosen: either a fixed value you supply (TemperatureConfiguration.Fixed), or automatically calibrated by the solver itself (TemperatureConfiguration.AutoCalibrate).coolingSchedule - An implementation of the CoolingScheduleIfc interface to determine the temperature at each iteration.stoppingTemperature - If the current temperature goes below this value, the algorithm will stop.targetProbability.class SimulatedAnnealing @JvmOverloads constructor(
problemDefinition: ProblemDefinition,
evaluator: EvaluatorIfc,
val temperatureConfiguration: TemperatureConfiguration = TemperatureConfiguration.Fixed(defaultInitialTemperature),
var coolingSchedule: CoolingScheduleIfc = ExponentialCoolingSchedule(defaultInitialTemperature),
stoppingTemperature: Double = defaultStoppingTemperature,
maximumIterations: Int = defaultMaxNumberIterations,
replicationsPerEvaluation: ReplicationPerEvaluationIfc,
streamNum: Int = 0,
streamProvider: RNStreamProviderIfc = RNStreamProvider(),
name: String? = null
) : StochasticSolver(problemDefinition, evaluator, maximumIterations, replicationsPerEvaluation, streamNum, streamProvider, name) { override fun mainIteration() {
// generate a random neighbor of the current solution
val nextPoint = nextPoint()
// evaluate the point to get the next solution
val nextSolution = requestEvaluation(nextPoint)
// calculate the cost difference
costDifference = nextSolution.penalizedObjFncValue - currentSolution.penalizedObjFncValue
// if the cost difference is negative, it is automatically an acceptance
if (costDifference < 0.0) {
// no need to generate a random variate
currentSolution = nextSolution
lastAcceptanceProbability = 1.0
} else {
// decide whether an increased cost should be accepted
val u = rnStream.randU01()
lastAcceptanceProbability = acceptanceProbability(costDifference, currentTemperature)
if (u < lastAcceptanceProbability) {
currentSolution = nextSolution
}
}
// update the current temperature based on the cooling schedule
currentTemperature = coolingSchedule.nextTemperature(iterationCounter)
// capture the last solution
solutionChecker.captureSolution(currentSolution)
}The acceptance probability criteria is based on the Boltzman distribution and is a function of the objective function difference and the current value of the temperature.
ksl.solvers.algorithms package also provides implementations for linear and logarithmic cooling schedules.class ExponentialCoolingSchedule(
initialTemperature: Double,
val coolingRate: Double = defaultCoolingRate
) : CoolingSchedule (initialTemperature) {
init {
require(coolingRate > 0.0) { "Cooling rate must be positive" }
require(coolingRate < 1.0) { "Cooling rate must be less than 1.0" }
}
override fun nextTemperature(iteration: Int): Double {
require(iteration > 0) { "The iteration must be positive. It was $iteration." }
return initialTemperature * coolingRate.pow(iteration)
}
}SimulatedAnnealing class uses an instance of the previously discussed SolutionChecker class as part of the stopping criteria to check if the last 5 (default) solutions are the same or if the temperature has become too small.StochasticSolver class.CESampler class or accept the default of a sampler based on the multivariate normal distribution.InputsAndConfidenceIntervalEquality class, which implements the SolutionEqualityIfc interface.
CESampler class to generate the points \(\vec{X}_1, \vec{X}_2, \dots, \vec{X}_N\) via the function call ceSampler.sample(sampleSize()) within the mainIteration() function.sampleSize() computes the size, \(N\), of the cross-entropy population at each iteration.class CrossEntropySolver @JvmOverloads constructor(
problemDefinition: ProblemDefinition,
evaluator: EvaluatorIfc,
streamNum: Int = 0,
streamProvider: RNStreamProviderIfc = RNStreamProvider(),
ceSampler: CESampler = CENormalSampler(problemDefinition),
maxIterations: Int = ceDefaultMaxIterations,
replicationsPerEvaluation: ReplicationPerEvaluationIfc,
solutionEqualityChecker: SolutionEqualityIfc = InputsAndConfidenceIntervalEquality(),
name: String? = null
) : StochasticSolver(problemDefinition,
evaluator, maxIterations,
replicationsPerEvaluation, streamNum,
streamProvider, name
) override fun mainIteration() {
// Generate the cross-entropy sample population
val points = ceSampler.sample(sampleSize())
// Convert the points to be able to evaluate.
val inputs = problemDefinition.convertPointsToInputs(points)
// request evaluations for solutions
val evaluations = requestEvaluations(inputs)
val results = evaluations.values.toList()
if (results.isEmpty()) {
// Returning will cause no updating on this iteration.
// New points will be generated for another try on the next iteration.
return
}
// At least one result, so proceed with processing.
// Process the results to find the elites. This should fill myEliteSolutions.
myEliteSolutions = findEliteSolutions(results)
// convert elite solutions to points
val elitePoints = extractSolutionInputPoints(myEliteSolutions)
// update the sampler's parameters
ceSampler.updateParameters(elitePoints)
// specify the current solution
currentSolution = myEliteSolutions.first()
// capture the last solution
solutionChecker.captureSolution(currentSolution)
}There are a number of key issues that must be implemented for the cross-entropy method.
ceSampleSize property.ceSampleSize property is based on a user changeable default value or a recommended sample size based on the size of a sample needed to adequately estimate the quantile of a distribution.eliteSize() function for this purpose.EliteSizeIfc functional interface, which simply promises to compute the size of the elite sample.eliteSize() function will use a supplied function specified by the eliteSizeFn property or determine the size based on the specified elite percentage.The questions associated with the sampling distribution and the updating of its parameters should be addressed by the choice of the implementation of the CESampler class chosen for the algorithm.
Note that the CESampler abstract class implements the MVSampleIfc and RNStreamControlIfc interfaces. Thus, it can act as a multivariate sampler and can control the underlying random number stream. The four most relevant functions are:
updateParameters(elites: List<DoubleArray>) - This function should update the parameters based on the points from the elite sample (held in a list of double arrays).
parameters(): DoubleArray - This function returns the current parameter values.
initializeParameters(values: DoubleArray) - This function is used to specify the initial values of the parameters.
hasConverged(): Boolean - This function should return true if the parameters of the underlying sampling distribution are considered converged.
CENormalSampler class, the implementation uses a randomly generated point in the solution space as the specification of the means of the multivariate normal distribution.CENormalSampler class requires the specification of the smoothing constant, \(\alpha\), for both the mean and the standard deviation parameters.
initialVariabilityFactor property, which will be used to multiply the approximated initial values for the standard deviation parameters.
cvThreshold parameter value.
hasConverged() function will return true. override fun mainIteration() {
// The initial (current) solution is randomly selected or specified by the user.
// It will be the current solution until beaten by the SPLINE search process.
// Call SPLINE for the next solution using the current sample size (m_k) and
// current SPLINE oracle call limit (b_k).
val splineSolution = spline(
currentSolution,
rSPLINESampleSize, splineCallLimit
)
currentSolution = splineSolution
// capture the last solution
solutionChecker.captureSolution(currentSolution)
}class RandomRestartSolver(
val restartingSolver: Solver,
maxNumRestarts: Int = defaultMaxRestarts,
streamNum: Int = 0,
streamProvider: RNStreamProviderIfc = KSLRandom.DefaultRNStreamProvider,
name: String? = null
) : StochasticSolver(
restartingSolver.problemDefinition, restartingSolver.evaluator, maxNumRestarts,
restartingSolver.replicationsPerEvaluation, streamNum, streamProvider, name
) private fun sequentialMainIteration() {
// clear the evaluator cache between randomized runs, but allow caching during the run itself
// this will cause new replications to be generated
if (clearCacheBetweenRuns){
evaluator.cache?.clear()
}
// randomly assign a new starting point
val startPoint = startingPoint()
restartingSolver.startingPoint = startPoint
// run the solver until it finds a solution
restartingSolver.runAllIterations()
numOracleCalls = numOracleCalls + restartingSolver.numOracleCalls
numReplicationsRequested = numReplicationsRequested + restartingSolver.numReplicationsRequested
// get the best solution from the solver run
val bestSolution = restartingSolver.bestSolution
currentSolution = bestSolution
}RandomRestartSolver has two public constructors. A second one builds restarts from a SolverFactoryIfc and can run them concurrently, so mainIteration() dispatches on isConcurrentMode:
solverFactory: SolverFactoryIfc, memberEvaluatorFactory, concurrentRestarts, and concurrentOptions.concurrentRestarts > 1, that many restarts run at once, each on its own worker with its own solver instance and private evaluation resources (restarts are statistically independent).ProblemDefinition classModelBuilderIfc interfaceEvaluatorIfc interfaceSolver class provides factory functions that facilitate the creation of the available solvers with default configurations.
MemorySolutionCache() to store and reuse solutions requested by the solver.object BuildRQModel : ModelBuilderIfc {
override fun build(
modelConfiguration: Map<String, String>?,
experimentRunParameters: ExperimentRunParametersIfc?
): Model {
val reorderQty: Int = 2
val reorderPoint: Int = 1
val model = Model("RQInventoryModel")
val rqModel = RQInventorySystem(model, reorderPoint, reorderQty, "Inventory")
rqModel.initialOnHand = 0
rqModel.demandGenerator.initialTimeBtwEvents = ExponentialRV(1.0 / 3.6)
rqModel.leadTime.initialRandomSource = ConstantRV(0.5)
model.lengthOfReplication = 20000.0
model.lengthOfReplicationWarmUp = 10000.0
model.numberOfReplications = 40
return model
}
}fun runCESolver(
simulationRunCache: SimulationRunCacheIfc? = null,
experimentRunParameters: ExperimentRunParametersIfc? = null
) {
val problemDefinition = makeRQInventoryModelProblemDefinition()
val modelBuilder = BuildRQModel
val solver = Solver.createCrossEntropySolver(
problemDefinition = problemDefinition,
modelBuilder = modelBuilder,
startingPoint = null,
maxIterations = 100,
replicationsPerEvaluation = 50,
simulationRunCache = simulationRunCache,
experimentRunParameters = experimentRunParameters
)
val tracker = ConsoleSolverStateTracker(solver)
tracker.startTracking()
solver.runAllIterations()
println()
println(solver)
println()
println("Solver Results Summary:")
solver.printResults()
println()
println("Final (Best) Solution:")
println(solver.bestSolution.asString())
println()
println("Approximate screening:")
val solutions = solver.bestSolutions.possiblyBest()
println(solutions)
println("Dataframe")
val df = solver.bestSolutions.toDataFrame()
df.schema().print()
df.print()
}An attached ConsoleSolverStateTracker emits a snapshot per iteration; the solution improves, then the last 5 iterations repeat and the solver stops.
>>> SOLVER INITIALIZED: Baseline captured.
>>> SOLVER STARTED: Beginning iterations...
[Iter: 1 | Oracle: 34] EstObj: 13.7967 | PenObj: 13.7967 | Cur: (Inventory:Item.initialReorderQty, Inventory:Item.initialReorderPoint)=(1.000, 11.000) | Best: (Inventory:Item.initialReorderQty, Inventory:Item.initialReorderPoint)=(1.000, 11.000)
[Iter: 2 | Oracle: 67] EstObj: 9.06001 | PenObj: 9.06001 | Cur: (Inventory:Item.initialReorderQty, Inventory:Item.initialReorderPoint)=(10.000, 5.000) | Best: (Inventory:Item.initialReorderQty, Inventory:Item.initialReorderPoint)=(10.000, 5.000)
[Iter: 7 | Oracle: 238] EstObj: 8.45271 | PenObj: 8.45271 | Cur: (Inventory:Item.initialReorderQty, Inventory:Item.initialReorderPoint)=(15.000, 2.000) | Best: (Inventory:Item.initialReorderQty, Inventory:Item.initialReorderPoint)=(15.000, 2.000)
...
[Iter: 39 | Oracle: 1113] EstObj: 4.61628 | PenObj: 4.61628 | Cur: (Inventory:Item.initialReorderQty, Inventory:Item.initialReorderPoint)=(4.000, 3.000) | Best: (Inventory:Item.initialReorderQty, Inventory:Item.initialReorderPoint)=(4.000, 3.000)
[Iter: 40 | Oracle: 1129] EstObj: 4.61628 | PenObj: 4.61628 | Cur: (Inventory:Item.initialReorderQty, Inventory:Item.initialReorderPoint)=(4.000, 3.000) | Best: (Inventory:Item.initialReorderQty, Inventory:Item.initialReorderPoint)=(4.000, 3.000)
solver.printResults() emits a structured SOLVER RESULTS report.
=================================================================
SOLVER RESULTS
=================================================================
Solver : ID_48
Problem : InventoryProblem
Termination : Stopping Criteria Satisfied
Execution Time : 460816ms
--- Algorithmic Budget ---
Total Iterations : 40
--- Evaluator Usage ---
Evaluator Invocations : 40
Design Points Evaluated : 1129
Total Replications Req. : 56450
├─ Executed by Oracle : 23800
└─ Satisfied by Cache : 32650
Cache Savings : 57.8% of simulation budget
--- Trajectory Summary ---
[INITIAL POINT]
Not Applicable (Population-based or not provided)
[FINAL/CURRENT POINT]
Solution(id = 467, status = Valid, evaluation = 40)
Objectives:
Estimated = 4.616278083730662
Penalized = 4.616278083730662
Granular = 4.616278083730662
Penalty = 0.0
Estimated Objective Function Details:
Name = Inventory:Item:OrderingAndHoldingCost
Average = 4.616278083730662
Variance = 4.7606867543817605E-5
Count = 50.0
95%CI = [4.614317189939786, 4.618238977521537]
Inputs:
Inventory:Item.initialReorderQty = 4.0
Inventory:Item.initialReorderPoint = 3.0
Response Constraints:
[SATISFIED] Inventory:Item:FillRate | LHS: 0.9604 >= RHS: 0.9500 | Viol: 0.0000 | (N=50.0, SE= 0.0002, 95% HW= 0.0004)
[BEST POINT FOUND]
Solution(id = 467, status = Valid, evaluation = 23)
Objectives:
Estimated = 4.616278083730662
Penalized = 4.616278083730662
Granular = 4.616278083730662
Penalty = 0.0
Estimated Objective Function Details:
Name = Inventory:Item:OrderingAndHoldingCost
Average = 4.616278083730662
Variance = 4.7606867543817605E-5
Count = 50.0
95%CI = [4.614317189939786, 4.618238977521537]
Inputs:
Inventory:Item.initialReorderQty = 4.0
Inventory:Item.initialReorderPoint = 3.0
Response Constraints:
[SATISFIED] Inventory:Item:FillRate | LHS: 0.9604 >= RHS: 0.9500 | Viol: 0.0000 | (N=50.0, SE= 0.0002, 95% HW= 0.0004)
=================================================================
Approximate screening:
Solutions:
totalSolutions = 1
capacity = 10
allowInfeasibleSolutions = false
orderedSolutions:
Solution(id = 467, status = Valid, evaluation = 23)
Objectives:
Estimated = 4.616278083730662
Penalized = 4.616278083730662
Granular = 4.616278083730662
Penalty = 0.0
Estimated Objective Function Details:
Name = Inventory:Item:OrderingAndHoldingCost
Average = 4.616278083730662
Variance = 4.7606867543817605E-5
Count = 50.0
95%CI = [4.614317189939786, 4.618238977521537]
Inputs:
Inventory:Item.initialReorderQty = 4.0
Inventory:Item.initialReorderPoint = 3.0
Response Constraints:
[SATISFIED] Inventory:Item:FillRate | LHS: 0.9604 >= RHS: 0.9500 | Viol: 0.0000 | (N=50.0, SE= 0.0002, 95% HW= 0.0004)
ProblemDefinition - This class facilitates the definition of an optimization problem involving an objective function, deterministic linear constraints, deterministic functional constraints, and response constraints.PenaltyFunction - This abstract class defines the interface for penalty functions that can be used to handle constraint violations within an optimization problem, bound to the specific constraint each instance serves.InputDefinition - This class facilitates the definition of input variables for an optimization problem.ConstraintIfc - This interface defines the behavior of deterministic constraints for an optimization problem. There are two types of deterministic constraints specified by the LinearConstraint and FunctionalConstraint classes.ResponseConstraint - This class models constraints in a simulation optimization problem that are based on responses from the execution of the simulation model.SimulationOracleIfc - This interface provides a general protocol for translating evaluation requests into evaluation results.SimulationProviderIfc - This interface implements the SimulationOracleIfc interface and provides functionality to validate evaluation requests.SimulationServiceIfc - This interface implements the SimulationOracleIfc interface to enable the requesting of simulation evaluations from many models.EvaluatorIfc - This interface defines a general protocol for translating evaluation requests into solutions that are needed by simulation optimization solvers.Evaluator - This class is a concrete implementation of the EvaluatorIfc interface that executes a model in a local execution.EvaluationRequest - A key class for communicating between solvers and evaluators. It represents the inputs associated with the evaluation, the outputs needed for the evaluation, and options for running common random numbers and using solution caching.ModelInputs - This class is an intermediary between input variables within a problem definition and the input variables of a simulation model.ResponseMap - This class represents the named responses from the simulation and their estimated value.EstimatedResponseIfc - This interface encapsulates summary statistics for the simulation responses across the replications.EstimatedResponse - This class is a concrete implementation of the EstimatedResponseIfc interface.Solution - This fundamental class encapsulates the inputs, outputs, and constraints associated with an evaluation request placed by a solver.Solver - This is an abstract base class the represents the concepts needed by all simulation optimization algorithms.StochasticSolver - This is an abstract class that represents solvers that use randomness in the search process. It has concrete implementations of StochasticHillClimber, SimulatedAnnealing, CrossEntropySolver, RSplineSovler, and RandomRestartSolver.ReplicationPerEvaluationIfc - This interface facilitates algorithms that change the number of replications during the search process. It has concrete implementations of FixedReplicationsPerEvaluation and FixedGrowthRateReplicationSchedule.SolutionEqualtyIfc - This interface as its variations allow for different processes to compare or check for solution equality, which is essential in implementing stopping criteria for algorithms.