\[ \min_{x\in S} g(x) \] Where:
\[ g(x) = E[g(x, \xi_i)] \\ S = \{x: E[h(x, \xi_i)] \leq 0 \} \]
The KSL’s ksl.simopt package contains functionality to implement and use simulation optimization algorithms for KSL models. The package has the following sub-packages:
ksl.simopt.problem This package has classes that facilitate the definition of optimization problem instances. The functionality includes specifying the objective function, the decision variables, and the constraints.ksl.simopt.evaluator This package has classes that provide a well-defined interaction protocol with a simulation model. In essence, a general contract for what constitutes the inputs and outputs from the model is defined. This allows responses to be translated to solutions for problem instances that can be used by algorithms.ksl.simopt.solvers This package provides the algorithms and general functionality for iterative optimization methods. The KSL denotes these simulation optimization algorithms as solvers.ksl.simopt.cache This package provides basic functionality to cache (in memory) executions of simulation models. Because the execution of a simulation model may be a long-running task and algorithms may visit design points multiple times during the search process, the caching of solutions may be useful. This package defines general interfaces for caching solutions and simulation runs.An instance of the ProblemDefinition class represents the following mathematical program:
\[ \min g(\vec{x}) = E[G(\vec{x})] \\ \sum_{i=1}^{|I|}a_{ij}x_i \leq b_j \quad \textrm{for} \quad j=1,\dots,|L|\\ f_{i} (\vec{x}) \leq c_{i} \quad \textrm{for} \quad i=1,\dots,|F|\\ E[R_{i}(\vec{x})] \leq r_i \quad \textrm{for} \quad i=1,\dots,|R|\\ l_i \leq x_i \leq u_i \quad \textrm{for} \quad i=1,\dots,|I|\\ \]
ProblemDefinition class may contain deterministic linear and functional constraints and constraints that are based on observed responses.
class ProblemDefinition constructor(
problemName: String? = null,
val modelIdentifier: String,
val objFnResponseName: String,
inputNames: List<String>,
responseNames: List<String> = emptyList(),
val optimizationType: OptimizationType =
OptimizationType.MINIMIZE,
indifferenceZoneParameter: Double = 0.0,
objFnGranularity: Double = 0.0
) : IdentityIfc by Identity(problemName) ksl.simopt.problem package provides an abstract PenaltyFunction, bound to the one constraint it serves:ProblemDefinition.penaltyFncValue(solution) sums each bound penalty across all constraints — always non-negative, so a violation always worsens the objective whether you minimize or maximize.DynamicPolynomialPenalty — the memory-less default for all three constraint categories: \[P(v_k, t) = \left(C \cdot t^{\beta}\right) \cdot v_k^{\alpha}\] where \(t\) is the solution’s evaluation number, with basePenalty \(C=100\), iterationExponent \(\beta=1\), and violationExponent \(\alpha=1\) by default.
ParkKimPenalty — memoryful, opt-in: tracks how infeasible a solution has looked across visits via an AppreciateDepreciateSequence, charging \(P = \lambda \cdot [S]^+\). Falls back to the memory-less penalty until a solution is revisited more than once.defaultLinearPenalty / defaultFunctionalPenalty / defaultResponsePenalty), override a specific linear/response constraint via its penaltyFunction argument, or implement PenaltyFunction for a custom scheme.The ProblemDefinition class facilitates the computation of each type of violation, individually for each constraint and in total via the functions:
linearConstraintViolations(inputs: Map<String, Double>): DoubleArraytotalLinearConstrainViolations(inputs: Map<String, Double>): DoublefunctionalConstraintViolations(inputs: Map<String, Double>): DoubleArraytotalFunctionalConstraintViolations(inputs: Map<String, Double>): DoubleUsers can use these functions to define their own penalty function forms.
An inventory manager is interested in understanding the cost and service trade-offs related to the inventory management of computer printers. Suppose customer demand occurs according to a Poisson process at a rate of 3.6 units per month and the lead time is 0.5 months. The manager has estimated that the holding cost for the item is approximately $0.25 per unit per month. In addition, when a back-order occurs, the estimate cost will be $1.75 per unit per month. Every time that an order is placed, it costs approximately $0.15 to prepare and process the order. The inventory manager wants to find the optimal setting for the reorder point and the reorder quantity with respect to the total ordering and holding cost while ensuring a fill rate of at least 0.95. Set up a KSL simulation optimization problem for this situation.
The model needs to have controls defined for the decision variables.
@set:KSLControl(
controlType = ControlType.INTEGER,
lowerBound = 0.0
)
var initialReorderPoint: Int
get() = myInitialReorderPt
set(value) {
setInitialPolicyParameters(value, myInitialReorderQty)
}
@set:KSLControl(
controlType = ControlType.INTEGER,
lowerBound = 1.0
)
var initialReorderQty: Int
get() = myInitialReorderQty
set(value) {
setInitialPolicyParameters(myInitialReorderPt, value)
}The names of the two controls will be the strings:
The fill rate and total ordering and holding cost responses have similar naming conventions resulting in these strings:
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 = 40val problemDefinition = ProblemDefinition(
problemName = "InventoryProblem",
modelIdentifier = "RQInventoryModel",
objFnResponseName = "Inventory:Item:OrderingAndHoldingCost",
inputNames = listOf("Inventory:Item.initialReorderQty", "Inventory:Item.initialReorderPoint"),
responseNames = listOf("Inventory:Item:FillRate")
)
problemDefinition.inputVariable(
name = "Inventory:Item.initialReorderQty",
interval = Interval(1.0, 100.0),
granularity = 1.0
)
problemDefinition.inputVariable(
name = "Inventory:Item.initialReorderPoint",
interval = Interval(1.0, 100.0),
granularity = 1.0
)
problemDefinition.responseConstraint(
name = "Inventory:Item:FillRate",
rhsValue = 0.95,
inequalityType = InequalityType.GREATER_THAN
)ksl.simopt.evaluator package is to provide classes and interfaces that establish this interaction protocol.EvaluatorIfc interface translate simulation results into in solutions that solvers can use.A model input is a specification for the inputs that will be used for the simulation run and the outputs that are requested.
Model inputs have a very special representation for determining their equality. Two instances of the ModelInputs class are considered equal if:
modelIdentifier properties are equal, andresponseNames properties are equal (contain all the same response names), andinputs properties are equal (contain the same (key, value) pairs)It is important to note that two instances will be considered equal even if their number of requested replications are different. This definition of equality facilitates the caching of results by model inputs.
\[ n = n_1 + n_2\\ \bar{x} = \frac{n_1\bar{x}_1+n_2\bar{x}_2}{n} \]
\[ s^2 = \frac{(n_1-1)s^2_1+(n_2-1)s^2_2}{n-2} \]
Feasibility is established with respect to the problem instance. There are four types of feasibility modeled.
Notice that feasibility ignores the issue of feasibility with respect to the response constraints.
The ksl.simopt.evaluator package permit requests for simulation evaluations. The inputs to the simulation model are contained within the request. The simulation model is executed at the specified inputs and the requested results returned. For simulation optimization algorithms, the input-output mapping is encapsulated within instances of the Solution class.
The Solution class contains information on the following: