Skip to contents

Some decisions have to be made before all the data is known: how much stock to order before demand is known, which jobs to accept before knowing how long they will take. quicopt models such a decision by describing each uncertain quantity as a random variable. The service draws many possible outcomes of the random variables, called scenarios, and finds the decision that does best across them.

Building blocks

  • rand_var() declares a random variable with a distribution such as normal(); set_empirical() declares random variables from the columns of a data frame instead, one row per scenario.

  • set_scenarios() sets how many scenarios the service draws, and the seed it draws them from.

  • Any expression that contains a random variable has one value per scenario; it is called random (see is_random()). The objective and the constraints must each be one number, so a random expression is summarized across the scenarios before it is used there.

Summaries across the scenarios

holds() turns a comparison into a 0/1 value in each scenario, which can be combined with other quantities before it is summarized.

Checking a solution

A solution is chosen to do well on the model's scenarios, so it tends to do a little worse on others, and the objective the service reports is optimistic. evaluate() and resample() compute the figures on new scenarios, and the margin argument of add() raises the target of a requirement on a probability to allow for this.

vignette("stochastic", package = "quicopt") introduces all of this with a worked example.

Examples

if (FALSE) { # \dontrun{
# Order stock at 3 per unit before demand is known, pay 10 for each unit
# of demand that cannot be met, and meet demand in at least 90% of scenarios.
m <- model()
stock  <- num_var(m, "stock", lower = 0, upper = 200)
demand <- rand_var(m, "demand", normal(100, 15))
set_scenarios(m, 512, seed = 42)
minimize(m, 3 * stock + 10 * expectation(max(demand - stock, 0)))
add(m, prob(demand <= stock) >= 0.9)
res <- solve(m)
res$solution

# Does the requirement still hold on 1000 new scenarios?
resample(m, res, seed = 7, n_scenarios = 1000)$feasible
} # }