Share via


How to: Make Investment Decisions using Mixed Integer Linear Programming

You can make investment decisions by modeling the problem as a mixed integer linear program. In this example, given an initial capital expenditure of $20 million and five different projects, you must decide which projects to invest in to maximize the total profit. This example is based on problem 12.1.3 in Hillier and Lieberman’s book Introduction to Operations Research. The following table shows the estimated profits and capital requirements for each project.

Project

Estimated profits

Capital requirements

0

$1 million

$6 million

1

$1.8 million

$12 million

2

$1.6 million

$10 million

3

$0.8 million

$4 million

4

$1.4 million

$8 million

The following steps show how to use Solver Foundation to create and solve the investment decision model using the simplex solver. The total profit is represented as a row to be maximized, and the total capital expenditure cannot be greater than the initial capital expenditure.

To make investment decisions by using a mixed integer linear program

  1. Create a console application named InvestmentDecisions.

  2. Add a reference to Microsoft Solver Foundation on the .NET tab of the Add Reference dialog box.

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

    Imports Microsoft.SolverFoundation.Common
    Imports Microsoft.SolverFoundation.Solvers
    
    using Microsoft.SolverFoundation.Common;
    using Microsoft.SolverFoundation.Solvers;
    
  4. In the Main method, add a solver by typing the following code.

    Dim solver As New SimplexSolver()
    
    SimplexSolver solver = new SimplexSolver();
    
  5. Create variables to store the data about the estimated profits, capital expenditures for each project, the initial capital expenditure, and the decision whether to invest in a project.

    Dim estimatedProfitOfProjectX As Double() = {1, 1.8, 1.6, 0.8, 1.4}
    Dim capitalRequiredForProjectX As Double() = {6, 12, 10, 4, 8}
    Dim availableCapital As Double = 20
    Dim chooseProjectX As Integer() = New Integer(4) {}
    
    double[] estimatedProfitOfProjectX = new double[] { 1, 1.8, 1.6, 0.8, 1.4 };
    double[] capitalRequiredForProjectX = new double[] { 6, 12, 10, 4, 8 };
    double availableCapital = 20;
    int[] chooseProjectX = new int[5]; 
    
  6. Create decision variables for the profit and capital expenditure, and then add row identifiers for both of these variables.

    Dim profit As Integer
    solver.AddRow("profit", profit)
    solver.AddGoal(profit, 0, False)
    
    Dim expenditure As Integer
    solver.AddRow("expenditure", expenditure)
    solver.SetBounds(expenditure, 0, availableCapital)
    
    int profit;
    solver.AddRow("profit", out profit);
    solver.AddGoal(profit, 0, false);
    
    int expenditure;
    solver.AddRow("expenditure", out expenditure);
    solver.SetBounds(expenditure, 0, availableCapital);
    
  7. Add the project names to the solver, and then add coefficients to the constraint rows by using the SetCoefficient method. Set the bounds and choices for the investment decision by using the SetBounds and SetIntegrality methods.

    For i As Integer = 0 To 4
        solver.AddVariable(String.Format("project{0}", i),
                           chooseProjectX(i))
        solver.SetBounds(chooseProjectX(i), 0, 1)
        solver.SetIntegrality(chooseProjectX(i), True)
        solver.SetCoefficient(profit,
                              chooseProjectX(i),
                              estimatedProfitOfProjectX(i))
        solver.SetCoefficient(expenditure,
                              chooseProjectX(i),
                              capitalRequiredForProjectX(i))
    Next
    
    for (int i = 0; i < 5; i++) {
      solver.AddVariable(string.Format("project{0}", i),
                          out chooseProjectX[i]);
      solver.SetBounds(chooseProjectX[i], 0, 1);
      solver.SetIntegrality(chooseProjectX[i], true);
      solver.SetCoefficient(profit, chooseProjectX[i],
                             estimatedProfitOfProjectX[i]);
      solver.SetCoefficient(expenditure, chooseProjectX[i],
                             capitalRequiredForProjectX[i]);
    }
    
  8. Configure the solver parameters to generate cuts, and then solve the model.

    Dim param As New SimplexSolverParams()
    param.MixedIntegerGenerateCuts = True
    solver.Solve(param)
    
    SimplexSolverParams param = new SimplexSolverParams();
    param.MixedIntegerGenerateCuts = true;
    solver.Solve(param);
    
  9. Show whether the solve process is optimal, and print the results of the solve process.

    Console.WriteLine(solver.MipResult.ToString())
    For i As Integer = 0 To 4
        Console.WriteLine("Project {0} is {1} selected.", i,
                          If(solver.GetValue(chooseProjectX(i)) = 1, "", "not "))
    Next
    Console.WriteLine("The estimated total profit is: ${0} million.",
                      CDbl(solver.GetValue(profit).ToDouble()))
    Console.WriteLine("The total expenditure is: ${0} million.",
                      solver.GetValue(expenditure).ToDouble())
    
    Console.WriteLine(solver.MipResult);
    for (int i = 0; i < 5; i++) {
      Console.WriteLine("Project {0} is {1} selected.", i,
                      solver.GetValue(chooseProjectX[i]) == 1 ? "" : "not ");
    }
    Console.WriteLine("The estimated total profit is: ${0} million.",
                      (double)solver.GetValue(profit).ToDouble());
    Console.WriteLine("The total expenditure is: ${0} million.",
                       solver.GetValue(expenditure).ToDouble());
    
  10. Press F5 to build and run the code.

    The command window shows the following results.

    Optimal

    Project 0 is selected.

    Project 1 is not selected.

    Project 2 is selected.

    Project 3 is selected.

    Project 4 is not selected.

    The estimated total profit is: $3.4.

    The total expenditure is: $20.

See Also

Concepts

Developing with Solver Foundation Services (SFS)