Quiz Study Guide — Chapter 5
This deck is a checklist, not a summary. Every slide is phrased as something you should be able to state, derive, or compute without looking it up.
The spine of this chapter
Within-replication versus across-replication statistics; finite-horizon versus infinite-horizon analysis; and how to compare two or more system configurations.
Capturing output
Response, TWResponse, Counter, IndicatorResponseModelElementObserver lifecycleAnalyzing output
You should be able to:
ModelElementObserver lifecycle methods correctlyYou should be able to:
Tally data is a sequence of equally weighted observations associated with the duration or interval an object is in a state, observed at the end of that state. It is collected with Response.
Time-persistent data is collected with TWResponse.
| Class | Role |
|---|---|
Response |
Tally statistics on values observed at discrete event times |
TWResponse |
Time-weighted statistics on time-persistent (state) variables |
Counter |
Incremented/decremented during a replication; reset to 0 at replication start |
IndicatorResponse |
A Response subclass recording 1.0/0.0 from a boolean predicate on another response |
TWResponseFunction |
A TWResponse derived by applying a function (e.g. \(x/\text{numWorkers}\)) to another TWResponse |
In the pallet example, \(P\{\text{total time} > 480\}\) is captured with an IndicatorResponse whose predicate is { x -> x >= 480.0 }.
initialize() — called once at the beginning of each replication, conceptually at \(t = 0^-\); the recommended place to schedule initial events.replicationEnded() — called automatically infinitesimally before the end of each replication; the recommended place to capture final within-replication observations before the accumulators are cleared.Observations made inside replicationEnded() are still within-replication observations and can be tallied by a Response.
| Method | When it fires |
|---|---|
beforeExperiment() |
Once, before the first replication and any events |
beforeReplication() |
Before each replication; the calendar is cleared after this action |
initialize() |
Start of each replication, after the calendar is cleared |
warmUp() |
At the warm-up event, clearing the statistical accumulators |
replicationEnded() |
Just before the end of each replication |
afterReplication() |
After each replication |
afterExperiment() |
Once, after all replications |
| Class | Purpose |
|---|---|
SimulationReporter |
Text, MarkDown, and LaTeX summary reports, at a user-specified confidence level |
ReplicationDataCollector |
Observer retaining end-of-replication values in arrays via allReplicationDataAsMap |
ResponseTrace |
Writes a per-change trace of an observed response to a file |
KSLDatabaseObserver |
Persists every within- and across-replication statistic to a relational database |
WelchFileObserver |
Captures observations across replications for warm-up analysis |
autoCSVReports = true produces two CSV files. For anything richer, attach a KSLDatabaseObserver.
| Table or view | Contents |
|---|---|
SIMULATION_RUN |
Run metadata: experiment name, replications, length, warm-up |
MODEL_ELEMENT |
The model element hierarchy per run: name, ID, parent ID, class type |
WITHIN_REP_STAT |
Per-replication ending statistics for Response and TWResponse |
WITHIN_REP_COUNTER_STAT |
Per-replication counter statistics |
ACROSS_REP_STAT |
Across-replication summary statistics |
PW_DIFF_WITHIN_REP_VIEW |
Pairwise within-replication differences \((A - B)\), where \(A\) has the higher simulation ID |
Trap
Re-running a simulation with the same name in the same output directory deletes and recreates the database, losing the previous results.
To store several experiments in the same database during one program execution, change the experimentName between calls to simulate() — not the simulation name.
A finite-horizon (terminating) simulation has a well-defined ending time or ending condition that clearly demarks the end of the simulation.
The classical method of analysis is the method of independent replications.
The AcrossReplicationHalfWidthChecker is a ModelElementObserver attached to a Response that calls endSimulation() once the across-replication half-width on that response meets a desired value.
Within-replication queueing data violates both standard IID assumptions:
Initialization bias is the bias in steady-state estimators caused by the (often non-representative) initial conditions.
Mitigation: a warm-up period, set by lengthOfReplicationWarmUp. Banks et al.’s rule of thumb: \(T_e \geq 10\,T_w\).
Trap
Even after a warm-up, within-replication observations are still not independent. And “the system has reached steady state” is not endorsed as a correct reading.
The classes live in ksl.observers.welch:
| Class | Role |
|---|---|
WelchFileObserver / WelchDataFileCollector |
Attach to a response; gather per-replication observations to disk |
WelchDataFileAnalyzer |
Read the files; compute per-row averages and cumulative averages |
WelchPlot |
Render the plot in a browser or to a file |
For a time-persistent variable, first discretize the data into equally spaced intervals (e.g. 10 time units) so each interval average is one observation.
The KSL algorithm (after Kelton et al.):
Add StatisticalBatchingElement to the model via model.statisticalBatching().
Schmeiser: use roughly 10 to 30 batches; there is little benefit beyond 30.
If a warm-up analysis used \(n_0\) replications of length \(T_e\) with warm-up \(T_w\), a reasonable single-replication starting point is run length \(n_0 T_e\) with warm-up \(n_0 T_w\).
Under independent sampling, with \(\hat D = \bar X_1 - \bar X_2\):
\[\mathrm{Var}(\hat D) = \frac{\sigma_1^2}{n} + \frac{\sigma_2^2}{n}\]
Common Random Numbers reduces \(\mathrm{Var}(\bar X_1 - \bar X_2)\) whenever there is positive correlation between the paired outputs.
resetStartStreamOption = true so all streams reset before each experiment.MultipleComparisonAnalyzer built from independent data may show a noticeably larger standard deviation of the differences than one built from CRN-paired data.\[n = \max\left\{n_0,\ \left\lceil \frac{t^2 \hat S^2}{\delta^2} \right\rceil \right\}, \qquad t = t_{1-\alpha/(k-1),\,n_0-1}\]
db.multipleComparisonAnalyzerFor(listOf(exp1, exp2), responseName) is the easy construction path.| Construct | Role |
|---|---|
KSLControl |
Annotation marking a property as a controllable input, exposed via Model.controls() |
RVParameterSetter |
Generic access to every random variable parameter, with flat keys like ProcessingTimeRV.mode |
Scenario |
A model + an input map (control or RV-parameter names to doubles) + a unique scenario name |
ScenarioRunner |
Executes a list of Scenario instances and stores results to a KSL database |
MultipleComparisonAnalyzer |
Consumes the scenario results to compute MCB and related comparisons |
elementName.propertyName. For numWorkers on a PalletWorkCenter named “PWC”, the key is PWC.numWorkers.RVParameterSetter keys are RVName.parameterName, such as ProcessingTimeRV.mode.RVParameterSetter change takes effect on the model only after applyParameterChanges(model) is invoked.The payoff of ScenarioRunner plus a KSLDatabase is that many configurations are captured automatically under unique experiment names, and can then be queried — for MCB analysis, say — without manually re-running the models.
This chapter’s question bank has no numeric items — these are practice problems built from the formulas and rules it tests in other formats. Expect the quiz to test the same relationships, not these exact numbers.
IndicatorResponse is a Response subclass, not a TWResponse subclass.replicationEnded() are still within-replication observations.experimentName.