How to: Use Stochastic Programming to Solve Two-Stage Linear Models

# How to: Use Stochastic Programming to Solve Two-Stage Linear Models

Solver Foundation 3.0

You can use linear programming to minimize or maximize functions, and also account for fluctuating demand by using random parameters and recourse decisions. In this example, an oil refinery must procure crude oil from two sources. The objective is to minimize the purchase cost of crude oils of varying quality and to meet minimum production levels of 2,000 barrels of gasoline, 1,500 barrels of jet fuel, and 500 barrels of machine lubricant. Meanwhile, the suppliers cannot exceed their maximum daily production of crude oil. If demand cannot be met, the refinery must purchase pre-refined products at these prices: \$38.40 for gas, \$35.20 for jet fuel, and \$28.80 for lubricant. The following table shows the costs and capabilities of the two different crude oils.

Source

Saudi Arabia refining

Venezuela refining

Cost of crude oil

\$20 per barrel

\$15 per barrel

Maximum daily production

9,000 barrels

6,000 barrels

Refining percentages

30% gasoline

40% jet fuel

20% lubricant

10% waste

40% gasoline

20% jet fuel

30% lubricant

10% waste

The following example uses Solver Foundation to create, solve, and adjust the refining model to account for demand. This example demonstrates how to use the Solver Foundation Services layer.

### To use stochastic programming and Solver Foundation Services to account for demand

1. Create a console application named PetroChemStoch.

2. Add a reference to Microsoft Solver Foundation on the .NET tab.

3. Add the following Imports or using statements to the top of the Program code file.

```
using Microsoft.SolverFoundation.Common;
using Microsoft.SolverFoundation.Services;

```
4. In the Main method, add the following code to get the context environment for a solver and create a new model.

```
SolverContext context = SolverContext.GetContext();
context.ClearModel();
Model model = context.CreateModel();

```
5. Create decision variables that represent the two sources of crude oil: Saudi Arabia and Venezuela. Then add the decisions to the model.

```
Decision sa = new Decision(Domain.RealRange(0, 9000), "SA");
Decision vz = new Decision(Domain.RealRange(0, 6000), "VZ");

```
6. Create recourse decision variables that represent the demand for the three products: gas, jet fuel, and lubricant. If the refining process does not meet demand, pre-refined product must be purchased. Add the decisions to the model.

```

```
7. Add the costs of the crude oils and the demand for the three products to the model. Then specify that the solver should minimize the goal by setting the second parameter to GoalKind.Minimize.

```

```
8. Create and add random parameters that correspond to a normal bell-shaped probability distribution.

```
RandomParameter gasDemand = new NormalDistributionParameter("GasDemand", 1900, 50);
RandomParameter jetFuelDemand = new NormalDistributionParameter("JetFuelDemand", 1500, 25);
RandomParameter lubricantDemand = new NormalDistributionParameter("LubricantDemand", 500, 5);

```
9. Add three second-stage constraints that evaluate the expected value of the recourse decision over all possible scenarios.

```
model.AddConstraint("demand1", 0.3 * sa + 0.4 * vz + gasBuy >= gasDemand);
model.AddConstraint("demand2", 0.4 * sa + 0.2 * vz + jetFuelBuy >= jetFuelDemand);
model.AddConstraint("demand3", 0.2 * sa + 0.3 * vz + lubricantBuy >= lubricantDemand);

```
10. Solve the model and get the report.

```
Solution solution = context.Solve();
Report report = solution.GetReport();
Console.WriteLine(report);

```
11. Press F5 to build and run the code.

The Command window shows the following results.

===Solver Foundation Service Report===

Date: Date

Version: Version

Model Name: Default

Capabilities Applied: LP

Solve Time (ms): 235

Total Time (ms): 548

Solve Completion Status: Optimal

Solver Selected: Microsoft.SolverFoundation.Solvers.SimplexSolver

Directives:

Microsoft.SolverFoundation.Services.Directive

Algorithm: Primal

Arithmetic: Hybrid

Variables: 302 -> 302 + 301

Rows: 301 -> 301

Nonzeros: 1202

Eliminated Slack Variables: 0

Pricing (exact): SteepestEdge

Pricing (double): SteepestEdge

Basis: Slack

Pivot Count: 435

Phase 1 Pivots: 300 + 0

Phase 2 Pivots: 135 + 0

Factorings: 12 + 1

Degenerate Pivots: 0 (0.00 %)

Branches: 0

Stochastic Measures:

Stochastic Solution Type: Sampled

Sampling Method: LatinHypercube

Sample Count: 100

Random Seed: 123456

Solving Method: Deterministic Equivalent

EV: 90500

VSS: 338.107860596763

EVPI: 779.794594168023

===Solution Details===

Goals:

goal: 91279.5357087704

Decisions:

SA: 1961.5464827093

VZ: 3269.78028997898

Second stage decisions (Average [Min, Max]):