CPLEX: An introduction to Linear Programming with OPL

IBM’s CPLEX is a commercial quality Optimization product. It can handle 10’s of 1000’s of variables as well as massive data sets. As with most commercial software it is very expensive, but they do offer a limited edition you can download to get some experience working with it.

You can find the free downloads here: CPLEX Download

In this example, we will be using CPLEX OPL (optimization programming language) to solve a very simple linear problem. Check out the already solved solution below:

As you can see, we are deciding which of 2 types of furniture, Table and Chairs. Our goal is maximize our profit, however we only have 300 units of material and 110 units of labor available.

phpsimplex1

Let’s break it down into some basic formulas now.

First, what are the two main elements we have here? Furniture (Table, Chair) and Resources (Material and Labor). All other elements are related to either Furniture or Resources in some way.

How Many? is related to Furniture. To make this easier to follow we will shorten How Many? to HM

Profit per Unit is also related to furniture – let’s call it P

So Total Profit = HM[Table]*P[Table] + HM[Chair]+P[Chair]

In a bit more formal format: cplexFurn.jpg

Coding in CPLEX

Now let’s code this in CPLEX. First we need to create a new OPL Project

cplexFurn1.jpg

Name your project and make sure to check Create Model and Create Data

cplexFurn2.jpg

You will note you now have two new files, a .mod and .dat

  • .mod = model file
  • .dat = data file

cplexFurn3.jpg

We are going to start by building our model file.

The model file consists of 4 parts

  • Variable declaration
  • Decision variable declaration
  • Objective
  • Constraints

Variable Declaration

{string} furniture = ...;   
{string} resources = ...;
int P[furniture] = ...;
int Avail[resources] = ...;
int ResValue[resources][furniture] = ...;

First- the =…; means the variable will find its values in the .dat file. We will get there soon.

{string} furniture = …;   — blue box
{string} resources = …;  — red box

cplexFurn4.jpg

int P[furniture] = …;  – red box
int Avail[resources] = …;  –  green box
int ResValues[resources][furniture] = …;  – purple box

cplexFurn5

The [] after the variable name tells which string the variable is related to. If you having trouble seeing what I am talking about, look at the images below.

cplexFurn6.jpg

cplexFurn7

cplexFurn8.jpg

I know this is confusing, but hopefully it will clear up as we move forward.

Decision variable declaration

dvar int HM[furniture];

Our decision variable (dvar) is how many units to build (HM). This is of course related to furniture. As the picture below shows:

cplexFurn9.jpg

Objective:

maximize 
      sum(i in furniture)
                  HM[i]*P[i];

Our object is to maximize profit. The equation above is simply the OPL way of writing:

HM[Table]*P[Table] + HM[Chair]+P[Chair]

sum(i in furniture) is like a for loop where the results of each iteration are summed up. The two values passed through i would be Table and Chair.

Constraints:

subject to {

      forall(i in resources)
               ct1:
                   sum(j in furniture)
                         ResValue[i][j]*HM[j]<=Avail[i];

}

Our final chunk of code in our model (.mod) file is our Constraints. Constraints are started by using the code: subject to {}

Forall(i in resources) – is just a for loop iterating through (materials, labor)

ct1: – just names your constraint – an issue in bigger problems where you might have many constraints.

To clarify I will walk you through the sum(j in furniture) loop.

  1. ResValue[Materials][Table]*HM[Table]<=Avail[Materials]
  2. ResValue[Materials][Chair]*HM[Chair]<=Avail[Materials]
  3. ResValue[Labor][Table]*HM[Table]<=Avail[Labor]
  4. ResValue[Labor][Chair]*HM[Chair]<=Avail[Labor]

Here is what the code looks like in CPLEX

cplexFurn10.jpg

Now, let’s fill in our .dat (data file)

The code should be pretty self explanatory, note the use of {} for our string variables

furniture = {"Table","Chair"};
resources = {"Wood", "Labor"};
P = [6,8];
Avail = [300,110];
ResValue = [[30,20],[5,10]];

Here is the code in CPLEX

cplexFurn11.jpg

Run the code

To run the code, we first need to create a running configuration. Right click on Run Configurations > New > Run Configuration

cplexFurn12.jpg

Name your run configuration

cplexFurn13.jpg

Now, select you .mod and .dat files one at a time and drag them into your new running config. When you get the pop up warning, just click okay. Repeat this task for both files

cplexFurn14.jpg

Here is what your screen should look like.

cplexFurn15.jpg

Right click your running config and click Run this

cplexFurn16.jpg

Click Okay to save your mod and dat file

cplexFurn17.jpg

And now we have our results. 96 is out total profit with 4 Tables and 9 Chairs being built. Just like our Solver solution above.

cplexFurn18.jpg

The Code

.mod file

{string} furniture = ...; 
{string} resources = ...;
int P[furniture] = ...;
int Avail[resources] = ...;
int ResValue[resources][furniture] = ...;

dvar int HM[furniture];

maximize 
 sum(i in furniture)
    P[i]*HM[i];
 
subject to {

forall(i in resources)
 ct1:
 sum(j in furniture)
 ResValue[i,j]*HM[j]<=Avail[i];

}

.dat file

furniture = {"Table","Chair"};
resources = {"Wood", "Labor"};
P = [6,8];
Avail = [300,110];
ResValue = [[30,20],[5,10]];

 

 

Leave a Reply