How to: Use Linear Programming using the Solver Foundation Services APIs

You can use linear programming to minimize or maximize functions. In this example, an oil refinery must procure crude oil from two sources. The objective is to minimize the purchase cost of different quality crude oils and meet minimum production levels of 2000 barrels of gasoline, 1500 barrels of jet fuel, and 500 barrels of machine lubricant. Meanwhile, the suppliers cannot exceed their maximum daily production of crude oil. The following table shows the cost and capabilities of the two different crude oils.

Source

Saudi Arabia Refining

Venezuela Refining

Cost

$20/barrel

$15/barrel

Maximum

9000 barrels

6000 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 show how to create and solve the refining model by demonstrating how to use the Solver Foundation Services layer.

To use linear programming and the Solver Foundation Services to minimize the cost of petroleum production

  1. Create a Console Application named PetroChem.

  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.

    Imports Microsoft.SolverFoundation.Common
    Imports Microsoft.SolverFoundation.Services
    
    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.

    Dim context As SolverContext = SolverContext.GetContext()
    Dim model As Model = context.CreateModel()
    
    SolverContext context = SolverContext.GetContext();
    Model model = context.CreateModel();
    
  5. Create new decision variables that represent the two sources of crude oil: Saudi Arabia and Venezuela. Then, add the decisions to the model.

    Dim vz As New Decision(Domain.RealNonnegative, "barrels_venezuela")
    Dim sa As New Decision(Domain.RealNonnegative, "barrels_saudiarabia")
    model.AddDecisions(vz, sa)
    
    Decision vz = new Decision(Domain.RealNonnegative, "barrels_venezuela");
    Decision sa = new Decision(Domain.RealNonnegative, "barrels_saudiarabia");
    model.AddDecisions(vz, sa);
    
  6. Add two constraints that define the maximum daily production levels for the two refineries.

    model.AddConstraints("limits",
                         0 <= vz <= 9000,
                         0 <= sa <= 6000)
    
    model.AddConstraints("limits",
      0 <= vz <= 9000,
      0 <= sa <= 6000);
    
  7. Add three constraints that define the refining capabilities of each crude oil. The constraints for the two suppliers are added as decimals. For example, the Saudi Arabian crude oil produces 30% gasoline and the Venezuelan crude oil produces 40% gasoline. The first half of the constraint is added as 0.3 * sa + 0.4 * vz. The second half of the constraint identifies the minimum production of 2000 barrels of gasoline. Similar constraints are added for 1500 barrels of jet fuel and 500 barrels of machine lubricant.

    model.AddConstraints("production",
                         0.3 * sa + 0.4 * vz >= 2000,
                         0.4 * sa + 0.2 * vz >= 1500,
                         0.2 * sa + 0.3 * vz >= 500)
    
    model.AddConstraints("production",
      0.3 * sa + 0.4 * vz >= 2000,
      0.4 * sa + 0.2 * vz >= 1500,
      0.2 * sa + 0.3 * vz >= 500);
    
  8. Add the costs of the crude oils to the model and then specify that the solver should minimize the goal by setting the second parameter to GoalKind.Minimize.

    model.AddGoal("cost", GoalKind.Minimize,
                  20 * sa + 15 * vz)
    
    model.AddGoal("cost", GoalKind.Minimize,
      20 * sa + 15 * vz);
    
  9. Solve the model and get the report.

    Dim solution As Solution = context.Solve(New SimplexDirective())
    
    Dim report As Report = solution.GetReport()
    Console.WriteLine("vz: {0}, sa: {1}", vz, sa)
    Console.Write("{0}", report)
    Console.ReadLine()
    
    Solution solution = context.Solve(new SimplexDirective());
    
    Report report = solution.GetReport();
    Console.WriteLine("vz: {0}, sa: {1}", vz, sa);
    Console.Write("{0}", report);
    Console.ReadLine();
    
  10. Press F5 to build and run the code.

    The command window shows the following results.

    vz: 3500, sa: 2000

    ===Solver Foundation Service Report===

    Date: Date

    Version: Version

    Model Name: Default

    Capabilities Applied: LP

    Solve Time (ms): 358

    Total Time (ms): 515

    Solve Completion Status: Optimal

    Solver Selected: Microsoft.SolverFoundation.Solvers.SimplexSolver

    Directives:

    Simplex(TimeLimit = -1, MaximumGoalCount = -1, Arithmetic = Default, Pricing = Default, IterationLimit = -1, Algorithm = Default, Basis = Default, GetSensitivity = False)

    Algorithm: Primal

    Arithmetic: Double

    Variables: 2 -> 2 + 4

    Rows: 6 -> 4

    Nonzeros: 10

    Eliminated Slack Variables: 0

    Pricing (double): SteepestEdge

    Basis: Slack

    Pivot Count: 3

    Phase 1 Pivots: 3 + 0

    Phase 2 Pivots: 0 + 0

    Factorings: 4 + 0

    Degenerate Pivots: 0 (0.00 %)

    Branches: 0

    ===Solution Details===

    Goals:

    cost: 92500

    Decisions:

    barrels_venezuela: 3500

    barrels_saudiarabia: 2000

See Also

Concepts

Developing with Solver Foundation Services (SFS)