pythonpandasexcelcplexopl

Translate from Cplex to Python


using CP;
int numI = 4;
int numP = 3;
int B = 90000000;
// Define sets
range I = 1..numI;
range P = 1..numP;

// Define parameters
int scale=1000;
float v[I][P]=...;
float f[I][P]=...;
float u1[I][I]=...;
float u2[I][I]=...;
float u3[I][I]=...;
float C[I][P]=...;
float MOQ[I][P]=...;
int D[1..1][P]=...; 
int Nmax[P] = [3,2,3];
int Nstr[P]=[2,1,2];
int strat[I][P]=...;
float u[I][I][P];

execute
{
for (var i in I)
    for (var j in I)
        for (var p in P)
            if (p == 1)
                u[i][j][p] = u1[i][j]
            else if (p == 2)
                u[i][j][p] = u2[i][j]
            else
                u[i][j][p] =  u3[i][j];       
              }                
// Define decision variables
dvar boolean y[I][P];
dvar int+ scalex[I][P];
// Decision expressions
dexpr float x[i in I][p in P]=scalex[i][p]/scale;
dexpr float Z = sum(i in I, p in P) (D[1][p]*v[i][p]*x[i][p]) + sum(i in I, p in P) (f[i][p]*y[i][p]);
dexpr float K = sum(i in I, j in I, p in P) u[i][j][p]*x[i][p]*x[j][p];

minimize staticLex(Z, K);

// Define constraints
subject to {
 forall(p in P) {
    sum(i in I) x[i][p] == 1;
    sum(i in I) (D[1][p]*v[i][p]*x[i][p] + f[i][p]*y[i][p]) <= B;
    2 <=  sum(i in I) y[i][p];
    sum(i in I) y[i][p] <= Nmax[p];
    Nstr[p] <= sum(i in I) y[i][p]*strat[i][p];
 }
 forall(i in I, p in P) {
   x[i][p] <= C[i][p]*y[i][p];
   MOQ[i][p]*y[i][p] <= x[i][p];
   0<= x[i][p] <= 1;
   0<= y[i][p] <= 1;
   0<= C[i][p] <= 1;
   0<= MOQ[i][p] <= 1;
   0<= strat[i][p] <= 1;
  }
}

//Python
import pandas as pd
df = pd.read_excel(r'D:\final\DATA.xlsx', sheet_name='Set1', header=None)
I in range(1,4)
P in range(1,3)
v={}
for i in I
   for p in P
       v[i][p] = df.iloc[1:4, 2:6].values.tolist()
f = df.iloc[6:9, 2:6].values.tolist()
u1 = df.iloc[12:16, 2:6].values.tolist()
u2 = df.iloc[12:16, 9:13].values.tolist()
u3 = df.iloc[12:16, 15:19].values.tolist()
C = df.iloc[20:23, 2:6].values.tolist()
MOQ = df.iloc[26:29, 2:6].values.tolist()
D = df.iloc[41, 1:4].tolist()
strat = df.iloc[32:35, 2:6].values.tolist()
Nmax = df.iloc[37, 1:4].values.tolist()
Nstr = df.iloc[37, 5:8].values.tolist()

The Cplex code has been completed and produces the expected result. But I have problems with Python trying to do the same thing as Cplex. I don't know how to format parameter like in Cplex v[I][P] with Python. The above Pytohn code was written to import data from excel into Python, at that point I was stuck. Please help me fix the unfinished Python code or help it developed more.


Solution

  • First, you could call your OPL CPLEX model from python. Either by using doopl or using an external call from python.

    If you want to use arrays from dataframes in docplex you can see https://github.com/AlexFleischerParis/zoodocplex/blob/master/zoopandas.py

    from docplex.mp.model import Model
    from pandas import *
    
    # Data
    
    dfBuses = pandas.DataFrame({'size': [40,30], 'cost': [500,400]},
                          index = ['bus1', 'bus2'], columns=['size','cost'])
    
    print(dfBuses)
    
    nbKids=300
    
    for b in dfBuses.itertuples():
        print("buses with ",b.size," seats cost ",b.cost)
    
    mdl = Model(name='buses')
    
    #decision variables
    mdl.nbBus=mdl.integer_var_dict(dfBuses.itertuples(),name="nbBus")
    
    # Constraint
    mdl.add_constraint(mdl.sum(mdl.nbBus[b]*b.size for b in dfBuses.itertuples()) >= nbKids, 'kids')
    
    # Objective
    mdl.minimize(mdl.sum(mdl.nbBus[b]*b.cost for b in dfBuses.itertuples()))
    
    mdl.solve()
    
    # Dislay solution
    for b in dfBuses.itertuples():
        print(mdl.nbBus[b].solution_value," buses with ",b.size," seats")