SlideShare a Scribd company logo
1 of 34
Download to read offline
© 2017 IBM Corporation
OPL best practices
Alex Fleischer afleischer@fr.ibm.com
June 2017
© 2017 IBM Corporation2
A popular linkedin post
 https://www.linkedin.com/pulse/how-opl-alex-fleischer
How to ... with OPL
783 views 44 likes 1 comment
© 2017 IBM Corporation3
Which followed even more popular
2,725 views 128 likes 24 comments
© 2017 IBM Corporation4
Agenda
 Call OPL from outside OPL
 Modeling tricks
 Practical tricks within OPL
 Decomposition
 Specific examples
 NB:
 This is an add-on to documentation and trainings
 This document will get better after feedback
 And you may find all examples at
• https://www.linkedin.com/pulse/how-opl-alex-fleischer
© 2017 IBM Corporation5
Agenda
 Call OPL from outside OPL
 Modeling tricks
 Practical tricks within OPL
 Decomposition
 Specific examples
© 2017 IBM Corporation6
Call OPL from Excel through VBA
© 2017 IBM Corporation7
Call OPL from Matlab
The main idea is to use "system" in Matlab
>> command = 'oplrun model.mod data.dat';
>> [status, cmdout] = system(command);
status is the return code given by oplrun.
© 2017 IBM Corporation8
Call OPL from Python
 import subprocess

 dat = open('diet.dat','w')
 writedat(dat,'FOODS',FOODS);
writedat(dat,'NUTRIENTS',NUTRIENTS);
writedat(dat,'FOOD_NUTRIENTS',FOOD_NUTRIENTS);
 dat.close()
 subprocess.check_call(
["C:/ILOG/CPLEXStudio1263/opl/bin/x64_win64/oplrun", "diet.mod", "diet.dat"])

© 2017 IBM Corporation9
Even further with ticdat from Opalytics
© 2017 IBM Corporation10
Call OPL from R
Diet.r is
system("oplrun diet.mod diet.dat")
To run this example, simply do
Rscript.exe diet.r
And in Rscript.exe diet.r you ll get
quantity = [0 2.1552 0 0 0 10 1.8312 0 0.9297]
cost = 2.690409172
amount = [2000 800 11.278 8518.4 25 256.81 51.174]
© 2017 IBM Corporation11
Agenda
 Call OPL from outside OPL
 Modeling tricks
 Practical tricks within OPL
 Decomposition
 Specific examples
© 2017 IBM Corporation12
How to describe a piecewise linear function with breakpoints rather than slopes
 float firstSlope=0.5;
float lastSlope=2.0;
tuple breakpoint // y=f(x)
{
key float x;
float y;
}
sorted { breakpoint } breakpoints={<0,0>,<1,1>,<2,4>};
float slopesBeforeBreakpoint[b in breakpoints]=
(b.x==first(breakpoints).x)
?firstSlope
:(b.y-prev(breakpoints,b).y)/(b.x-prev(breakpoints,b).x);
pwlFunction f=piecewise(b in breakpoints)
{ slopesBeforeBreakpoint[b]->b.x; lastSlope } (first(breakpoints).x, first(breakpoints).y);
assert forall(b in breakpoints) f(b.x)==b.y;
© 2017 IBM Corporation13
How to multiply a decision variable with a boolean decision variable
using CP;
dvar int x in 2..10;
dvar boolean b;
maximize x;
subject to
{
b*x<=7;
}
dvar int x in 2..10;
dvar boolean b;
dvar int bx;
maximize x;
subject to
{
bx<=7;
(b==1) => (bx==x);
(b==0) => (bx==0);
}
dvar int x in 2..10;
dvar boolean b;
dvar int bx;
maximize x;
subject to
{
bx<=7;
2*b<=bx;
bx<=10*b;
bx<=x-2*(1-b);
bx>=x-10*(1-b);
}
© 2017 IBM Corporation14
How to use a decision variable as an index in an array with CPLEX
using CP;
range r=1..5;
float value[r]=[2,3,4.5,1,0];
dvar int i in 1..5;
maximize value[i];
subject to
{
}
execute
{
writeln("i=",i);
}
range r=1..5;
float value[r]=[2,3,4.5,1,0];
dvar int i in 1..5;
maximize sum(k in r) value[k]*(k==i);
subject to
{
}
execute
{
writeln("i=",i);
}
© 2017 IBM Corporation15
Agenda
 Call OPL from outside OPL
 Modeling tricks
 Practical tricks within OPL
 Decomposition
 Specific examples
© 2017 IBM Corporation16
Displaying 2 dimensions objects in the OPL IDE
 tuple sequence_like {
int start;
int end;
string label;
int type;
};
{sequence_like} array2[i in 1..n] = {<j-1,j," ",Life[i][j]> | j in 1..n};
© 2017 IBM Corporation17
Export into a csv file
tuple t
{
string firstname;
int number;
}
{t} s={<"Nicolas",2>,<"Alexander",3>};
execute
{
var f=new IloOplOutputFile("export.csv");
for(var i in s)
{
f.writeln(i.firstname,";",i.number,";");
}
f.close();
}
writes a file export.csv
Nicolas;2;
Alexander;3;
© 2017 IBM Corporation18
Import from csv file
Suppose you have this export.cvs file
Nicolas;2;
Alexander;3;
Then you could write
tuple t
{
string firstname;
int number;
}
{t} s={};
execute
{
var f=new IloOplInputFile("export.csv");
while (!f.eof)
{
var str=f.readline();
//writeln(str);
var ar=str.split(";");
if (ar.length==3) s.add(ar[0],Opl.intValue(ar[1]));
}
f.close();
}
execute
{
writeln(s);
}
which will read the csv file and compute the tuple set s:
{<"Nicolas" 2> <"Alexander" 3>}
© 2017 IBM Corporation19
Cartesian product in OPL
tuple Tset {
{string} members;
}
{Tset} setOfTuples = {<{"1","2"}>,<{"4","5","6"}>,<{"8","9"}>};
int dimresult=prod(i in 1..card(setOfTuples)) card(item(setOfTuples,i-
1).members);
{string} setPool[i in 1..dimresult]={}; // pool of sets
{string} options[i in 1..card(setOfTuples)]=(item(setOfTuples,i-
1).members);
{Tset} result={};
//For this particular example, the function needs to return:
//{<{1,4,8}>,<{1,4,9}>,<{1,5,8}>,<{1,5,9}>,<{1,6,8}>,<{1,6,9}>,<{2,4,8}>,<{2
,4,9}>,<{2,5,8}>,<{2,5,9}>,<{2,6,8}>,<{2,6,9}>}
execute
{
options;
function nextone(ndimension,sizes,e)
{
e[1]++;
for(j=1;j<=ndimension;j++)
{
if (e[j]>= sizes[j] )
{
e[j]=0;
e[j+1]++;
}
}
}
var dim=setOfTuples.size;
writeln("dim=",dim);
var sizes=new Array(dim);
var e=new Array(dim);
var dimresult=1;
for(var i=1;i<=dim;i++)
{
sizes[i]=Opl.item(setOfTuples,i-1).members.size;
e[i]=0;
dimresult*=sizes[i];
writeln(sizes[i]);
}
for(var i=1;i<=dimresult;i++)
{
for(var j=1;j<=dim;j++)
{
write(e[j]," ");
setPool[i].add(Opl.item(options[j],e[j]));
}
writeln();
nextone(dim,sizes,e);
result.add(setPool[i]);
}
writeln(result);
}
© 2017 IBM Corporation20
Powerset in OPL
{string} s={"A","B","C","D"};
range r=1.. ftoi(pow(2,card(s)));
{string} s2 [k in r] = {i | i in s: ((k div (ftoi(pow(2,(ord(s,i))))) mod 2) == 1)};
execute
{
writeln(s2);
}
© 2017 IBM Corporation21
How to evaluate CPLEX random seed variability in OPL
int n=30; // number of random seeds
int d[1..n]; // duration
int o[1..n]; // objective
int iter[1..n]; // iterations
// start of the model we want to test
int Fixed = 100;
int NbWarehouses = 50;
int NbStores = 200;
assert( NbStores > NbWarehouses );
range Warehouses = 1..NbWarehouses;
range Stores = 1..NbStores;
int Capacity[w in Warehouses] =
NbStores div NbWarehouses +
w % ( NbStores div NbWarehouses );
int SupplyCost[s in Stores][w in Warehouses] =
1 + ( ( s + 10 * w ) % 100 );
dvar int Open[Warehouses] in 0..1;
dvar float Supply[Stores][Warehouses] in 0..1;
dexpr int TotalFixedCost = sum( w in Warehouses ) Fixed * Open[w];
dexpr float TotalSupplyCost = sum( w in Warehouses, s in Stores
) SupplyCost[s][w] * Supply[s][w];
minimize TotalFixedCost + TotalSupplyCost;
subject to {
forall( s in Stores )
ctStoreHasOneWarehouse:
sum( w in Warehouses )
Supply[s][w] == 1;
forall( w in Warehouses )
ctOpen:
sum( s in Stores )
Supply[s][w] <= Open[w] * Capacity[w];
}
// end of the model we want to test
main {
thisOplModel.generate();
var sum_d=0;
var sum_o=0;;
var sum_iter=0;
writeln("seed objective iteration runtime");
for(var i=1;i<=thisOplModel.n;i++)
{
var opl=new IloOplModel(thisOplModel.modelDefinition);
opl.generate();
cplex.randomseed=i;
var d1=new Date();
cplex.solve();
var d2=new Date();
thisOplModel.d[i]=d2-d1;
sum_d+=d2-d1;
thisOplModel.d[i]=d2-d1;
thisOplModel.o[i]=Opl.ftoi(Opl.round(cplex.getObjValue()));
sum_o+=thisOplModel.o[i];
thisOplModel.iter[i]=cplex.getNiterations();
sum_iter+=thisOplModel.iter[i];
writeln(i," ",thisOplModel.o[i]," ",thisOplModel.iter[i]," ",
thisOplModel.d[i]/1000);
cplex.clearModel();
}
writeln("-----------------------------------------");
writeln("average ",sum_o/thisOplModel.n," ",
sum_iter/thisOplModel.n," ",sum_d/thisOplModel.n/1000);
writeln("std dev ",Opl.standardDeviation(thisOplModel.o)," ",
Opl.standardDeviation(thisOplModel.iter)," ",Opl.standardDeviation(thisO
plModel.d)/1000);
}
© 2017 IBM Corporation22
Agenda
 Call OPL from outside OPL
 Modeling tricks
 Practical tricks within OPL
 Decomposition
 Specific examples
© 2017 IBM Corporation23
Hybrid CPO and CPLEX
int n=20;
int values[0..(n+2)*(n+2)-1];
main {
var n=20;
var source1 = new IloOplModelSource("lifegameip.mod");
var cplex = new IloCplex();
var def1 = new IloOplModelDefinition(source1);
var source2 = new IloOplModelSource("lifegamecp.mod");
var cp = new IloCP();
var def2 = new IloOplModelDefinition(source2);
var opl1 = new IloOplModel(def1,cplex);
var opl2 = new IloOplModel(def2,cp);
opl1.generate();
opl2.generate();
var objValues=new Array(2*5);
for(var iter=1;iter<=5;iter++)
{
cplex.tilim=10;
cplex.solve();
writeln("cplex objective = ",cplex.getObjValue());
objValues[iter*2-1]=cplex.getObjValue();
cp.param.timelimit=10;
cp.param.SearchType=24;
// Warmstart
var sol=new IloOplCPSolution();
for(var i=0;i<=(n+2)*(n+2)-1;i++) sol.setValue(opl2.x[i],opl1.x[i]);
cp.setStartingPoint(sol);
cp.param.SearchType=24;
//opl2.Obj.LB=cplex.getObjValue();
cp.solve();
writeln("cpo objective =",cp.getObjValue());
objValues[iter*2]=cp.getObjValue();
var vectors = new IloOplCplexVectors();
// We attach the values (defined as data) as starting solution
// for the variables x.
for(var i=0;i<=(n+2)*(n+2)-1;i++) thisOplModel.values[i]=opl2.x[i];
vectors.attach(opl1.x,thisOplModel.values);
vectors.setVectors(cplex);
}
writeln("list of objectives") ;
for(var i=1;i<=10;i++) writeln(objValues[i]);
}
© 2017 IBM Corporation24
How to change the model without regeneration, incremental cplex matrix modification
dvar float+ Gas;
dvar float+ Chloride;
maximize 40 * Gas+ 50 * Chloride;
subject to {
ctMaxTotal:
Gas+ Chloride<= 50;
ctMaxTotal2:
3 * Gas+ 4 * Chloride<= 180;
ctMaxChloride:
Chloride<= 40;
ctEmpty:
Gas<=infinity;
}
execute
{
writeln("Gas = ",Gas);
writeln("Chloride = ",Chloride);
writeln("Objective =
",cplex.getObjValue());
main
{
thisOplModel.generate();
cplex.solve();
thisOplModel.postProcess();
writeln();
writeln("And then we add the
constraint Chloride - Gas <=5");
writeln();
thisOplModel.ctEmpty.UB=5;
thisOplModel.ctEmpty.setCoef(this
OplModel.Gas,-1);
thisOplModel.ctEmpty.setCoef(this
OplModel.Chloride,1);
cplex.solve();
thisOplModel.postProcess();
}
© 2017 IBM Corporation25
How to solve the same model with different data ? Change a value and generate again
float maxOfx = ...;
dvar float x;
maximize x;
subject to {
x<=maxOfx;
}
execute
{
writeln("x= ",x);
}
main {
var source = new
IloOplModelSource("sub.mod");
var cplex = new IloCplex();
var def = new IloOplModelDefinition(source);
for(var k=1;k<=10;k++)
{
var opl = new IloOplModel(def,cplex);
var data2= new IloOplDataElements();
data2.maxOfx=k;
opl.addDataSource(data2);
opl.generate();
if (cplex.solve()) {
opl.postProcess();
writeln("OBJ = " + cplex.getObjValue());
} else {
writeln("No solution");
}
opl.end();
}
}
© 2017 IBM Corporation26
How to solve the same model with different data ? Change an array and generate again
int y[1..2][1..2]=...;
execute
{
writeln("y=",y);
}
dvar float x;
maximize x;
subject to {
x<=sum(i in 1..2, j in 1..2) y[i][j];
}
int a[1..2][1..2];
main {
var source = new IloOplModelSource("sub.mod");
var cplex = new IloCplex();
var def = new IloOplModelDefinition(source);
for(var k=11;k<=15;k++)
{
var opl = new IloOplModel(def,cplex);
var data2= new IloOplDataElements();
data2.y=thisOplModel.a;
data2.y[1][1]=k;
opl.addDataSource(data2);
opl.generate();
if (cplex.solve()) {
writeln("OBJ = " + cplex.getObjValue());
} else {
writeln("No solution");
}
data2.end();
opl.end();
}
}
© 2017 IBM Corporation27
How to solve the same model with different data ? Change a set and generate again
{int} y=...;
execute
{
writeln("y=",y);
}
dvar float x;
maximize x;
subject to {
x<=sum(i in y)i;
}
execute
{
writeln("x=",x);
}
{int} s={};
main {
var source = new IloOplModelSource("sub.mod");
var cplex = new IloCplex();
var def = new IloOplModelDefinition(source);
for(var k=1;k<=5;k++)
{
var opl = new IloOplModel(def,cplex);
var data2= new IloOplDataElements();
data2.y=thisOplModel.s;
data2.y.add(k);
opl.addDataSource(data2);
opl.generate();
if (cplex.solve()) {
writeln("OBJ = " + cplex.getObjValue());
} else {
writeln("No solution");
}
data2.end();
opl.end();
}
}
© 2017 IBM Corporation28
Solve Anyway
int prefsolveanyway1[1..1]=[0];
int prefsolveanyway2[1..1]=[0];
int prefsolveanyway3[1..1]=[0];
int priority[1..3]=[1,2,3];
dvar int x;
dvar int y;
dvar int z;
subject to
{
0<=x<=20;
0<=y<=20;
0<=z<=20;
forall(i in 1..1) ct1:y-x>=7;
forall(i in 1..1) ct2:z-y>=9;
forall(i in 1..1) ct3:z-x<=10;
}
main {
function writeRelaxation(opl)
{
var iter = opl.relaxationIterator;
for(var c in iter)
{
var constraint=c.ct;
writeln(constraint.name);
writeln("LB = ",c.LB);
writeln("UB = ",c.UB);
writeln("relaxedLB = ",c.relaxedLB);
writeln("relaxedUB = ",c.relaxedUB);
}
}
thisOplModel.generate();
var def = thisOplModel.modelDefinition;
// Default behavior
writeln("Default Behavior");
writeln();
var cplex1 = new IloCplex();
var opl1 = new IloOplModel(def, cplex1);
opl1.settings.relaxationLevel=1;
writeln("Solve Anyway");
// Priority 1 : ct1
// Priority 2 : ct2
// Priority 3 : ct3
var currentPriority = 1;
var noSolution=1;
while (noSolution==1)
{
writeln();
var cplex2 = new IloCplex();
var opl2 = new IloOplModel(def, cplex2);
opl2.generate();
writeln("relaxing priority less than ",currentPriority) ;
if (opl2.priority[1]<=currentPriority) opl2.prefsolveanyway1[1]=1; else
opl2.prefsolveanyway1[1]=0;
if (opl2.priority[2]<=currentPriority) opl2.prefsolveanyway2[1]=1; else
opl2.prefsolveanyway2[1]=0;
if (opl2.priority[3]<=currentPriority) opl2.prefsolveanyway3[1]=1; else
opl2.prefsolveanyway3[1]=0;
opl2.relaxationIterator.attach(opl2.ct1, opl2.prefsolveanyway1);
opl2.relaxationIterator.attach(opl2.ct2, opl2.prefsolveanyway2);
opl2.relaxationIterator.attach(opl2.ct3, opl2.prefsolveanyway3);
writeRelaxation(opl2);
writeln("cplex status = ",cplex2.getCplexStatus());
if (cplex2.getCplexStatus()==14)
{
noSolution=0;
writeln("x,y,z = ",opl2.x," ",opl2.y," ",opl2.z);
}
currentPriority++;
}
opl2.end();
cplex2.end();
© 2017 IBM Corporation29
Agenda
 Call OPL from outside OPL
 Modeling tricks
 Practical tricks within OPL
 Decomposition
 Specific examples
© 2017 IBM Corporation30
TSP with CPO
 minimize endOf(itvs[n+1]) - (n+1);
subject to
{
startOf(itvs[1])==0; // break sym
noOverlap(seq,Dist,true); // nooverlap with a distance matrix
last(seq, itvs[n+1]); // last node
}
 NB:
 For big instances, CPLEX works better than CPO but as soon as you add side
constraints then CPO can tackle whereas CPLEX not always can
 Plus CPO gives a solution any time wheras with CPLEX you need a flow
control to remove circuits.
© 2017 IBM Corporation31
DEA (Data Envelopment Analysis)
 "Data envelopment analysis (DEA) is a nonparametric method in
operations research and economics for the estimation of production
frontiers. It is used to empirically measure productive efficiency of
decision making units (or DMUs). Although DEA has a strong link to
production theory in economics, the tool is also used for
benchmarking in operations management, where a set of measures
is selected to benchmark the performance of manufacturing and
service operations." (Wikipedia)
 This method relies on linear programming and looks at the past
 ( ex post)
 Always the same model, no ad hoc model so quick to implement
© 2017 IBM Corporation32
Data Envelopment Analysis (DEA) in OPL
int nbDMU=...;
int nbInputs= ...;
int nbOutputs=...;
range DMU=1..nbDMU;
range Input=1..nbInputs;
range Output=1..nbOutputs;
// Input
float X[DMU][Input]=...;
// Output
float Y[DMU][Output]=...;
int refDMU=...; // We want to measure efficiency of that DMU
assert refDMU in DMU;
dvar float+ theta;
dvar float+ lambda[DMU];
minimize theta;
subject to
{
forall(j in Input)
ctInput:
sum(i in DMU) (lambda[i]*X[i][j]) <= theta*X[refDMU][j];
forall(j in Output)
ctOutput:
sum(i in DMU) (lambda[i]*Y[i][j]) >= Y[refDMU][j];
}
execute
{
writeln("theta= ",theta);
if (theta==1) writeln("Efficient DMU");
// Loop to measure efficiency for all
DMU
main
{
thisOplModel.generate();
for(var dmu in thisOplModel.DMU)
{
writeln("DMU",dmu);
for(j in thisOplModel.Input)
thisOplModel.ctInput[j].setCoef(thisO
plModel.theta,-
thisOplModel.X[dmu][j]);
for(j in thisOplModel.Output)
thisOplModel.ctOutput[j].LB=thisOplM
odel.Y[dmu][j];
cplex.solve();
thisOplModel.postProcess();
}
© 2017 IBM Corporation33
How to import docplexcloud solution into a local OPL session
from docloud.job import JobClient
client = JobClient(url, key)
// Run the model in docplexcloud
with open("model/diet.mod", "rb") as modFile:
resp = client.execute(input=[{"name":"diet.mod",
"file":modFile},
"model/diet.dat"],
output="results.json",
log="solver.log",
gzip=True,
waittime=300,
delete_on_completion=True)
// import the json result file
import json
with open('results.json') as data_file:
data = json.load(data_file)
// write that into a .dat
res = open("sol.dat", "w")
res.write("s={");
quote='"'
for i in data["s"]:
res.write("<"+quote+i["food"]+quote+
","
+quote+i["nutrient"]+quote+","+str(i["
value"])+",>")
res.write("};")
res.close()
OPL best practices - Doing more with less easier

More Related Content

Similar to OPL best practices - Doing more with less easier

ES6 Simplified
ES6 SimplifiedES6 Simplified
ES6 SimplifiedCarlos Ble
 
Ecmascript 2015 – best of new features()
Ecmascript 2015 – best of new features()Ecmascript 2015 – best of new features()
Ecmascript 2015 – best of new features()Miłosz Sobczak
 
filesHeap.h#ifndef HEAP_H#define HEAP_H#includ.docx
filesHeap.h#ifndef HEAP_H#define HEAP_H#includ.docxfilesHeap.h#ifndef HEAP_H#define HEAP_H#includ.docx
filesHeap.h#ifndef HEAP_H#define HEAP_H#includ.docxssuser454af01
 
ESCMAScript 6: Get Ready For The Future. Now
ESCMAScript 6: Get Ready For The Future. NowESCMAScript 6: Get Ready For The Future. Now
ESCMAScript 6: Get Ready For The Future. NowKrzysztof Szafranek
 
Twins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingTwins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingRichardWarburton
 
Introduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy CresineIntroduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy CresineMovel
 
李建忠、侯捷设计模式讲义
李建忠、侯捷设计模式讲义李建忠、侯捷设计模式讲义
李建忠、侯捷设计模式讲义yiditushe
 
JavaScript - Agora nervoso
JavaScript - Agora nervosoJavaScript - Agora nervoso
JavaScript - Agora nervosoLuis Vendrame
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonCodemotion
 
C++totural file
C++totural fileC++totural file
C++totural filehalaisumit
 
C++aptitude questions and answers
C++aptitude questions and answersC++aptitude questions and answers
C++aptitude questions and answerssheibansari
 

Similar to OPL best practices - Doing more with less easier (20)

ES6 Simplified
ES6 SimplifiedES6 Simplified
ES6 Simplified
 
Ecmascript 2015 – best of new features()
Ecmascript 2015 – best of new features()Ecmascript 2015 – best of new features()
Ecmascript 2015 – best of new features()
 
Day 1
Day 1Day 1
Day 1
 
C Tutorials
C TutorialsC Tutorials
C Tutorials
 
filesHeap.h#ifndef HEAP_H#define HEAP_H#includ.docx
filesHeap.h#ifndef HEAP_H#define HEAP_H#includ.docxfilesHeap.h#ifndef HEAP_H#define HEAP_H#includ.docx
filesHeap.h#ifndef HEAP_H#define HEAP_H#includ.docx
 
ESCMAScript 6: Get Ready For The Future. Now
ESCMAScript 6: Get Ready For The Future. NowESCMAScript 6: Get Ready For The Future. Now
ESCMAScript 6: Get Ready For The Future. Now
 
Twins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingTwins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional Programming
 
Introduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy CresineIntroduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy Cresine
 
Es6 hackathon
Es6 hackathonEs6 hackathon
Es6 hackathon
 
李建忠、侯捷设计模式讲义
李建忠、侯捷设计模式讲义李建忠、侯捷设计模式讲义
李建忠、侯捷设计模式讲义
 
JavaScript - Agora nervoso
JavaScript - Agora nervosoJavaScript - Agora nervoso
JavaScript - Agora nervoso
 
C++ aptitude
C++ aptitudeC++ aptitude
C++ aptitude
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - Warburton
 
Typescript barcelona
Typescript barcelonaTypescript barcelona
Typescript barcelona
 
C++ tutorial
C++ tutorialC++ tutorial
C++ tutorial
 
C to perl binding
C to perl bindingC to perl binding
C to perl binding
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
 
C++totural file
C++totural fileC++totural file
C++totural file
 
Ds lab handouts
Ds lab handoutsDs lab handouts
Ds lab handouts
 
C++aptitude questions and answers
C++aptitude questions and answersC++aptitude questions and answers
C++aptitude questions and answers
 

Recently uploaded

GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 

Recently uploaded (20)

GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 

OPL best practices - Doing more with less easier

  • 1. © 2017 IBM Corporation OPL best practices Alex Fleischer afleischer@fr.ibm.com June 2017
  • 2. © 2017 IBM Corporation2 A popular linkedin post  https://www.linkedin.com/pulse/how-opl-alex-fleischer How to ... with OPL 783 views 44 likes 1 comment
  • 3. © 2017 IBM Corporation3 Which followed even more popular 2,725 views 128 likes 24 comments
  • 4. © 2017 IBM Corporation4 Agenda  Call OPL from outside OPL  Modeling tricks  Practical tricks within OPL  Decomposition  Specific examples  NB:  This is an add-on to documentation and trainings  This document will get better after feedback  And you may find all examples at • https://www.linkedin.com/pulse/how-opl-alex-fleischer
  • 5. © 2017 IBM Corporation5 Agenda  Call OPL from outside OPL  Modeling tricks  Practical tricks within OPL  Decomposition  Specific examples
  • 6. © 2017 IBM Corporation6 Call OPL from Excel through VBA
  • 7. © 2017 IBM Corporation7 Call OPL from Matlab The main idea is to use "system" in Matlab >> command = 'oplrun model.mod data.dat'; >> [status, cmdout] = system(command); status is the return code given by oplrun.
  • 8. © 2017 IBM Corporation8 Call OPL from Python  import subprocess   dat = open('diet.dat','w')  writedat(dat,'FOODS',FOODS); writedat(dat,'NUTRIENTS',NUTRIENTS); writedat(dat,'FOOD_NUTRIENTS',FOOD_NUTRIENTS);  dat.close()  subprocess.check_call( ["C:/ILOG/CPLEXStudio1263/opl/bin/x64_win64/oplrun", "diet.mod", "diet.dat"]) 
  • 9. © 2017 IBM Corporation9 Even further with ticdat from Opalytics
  • 10. © 2017 IBM Corporation10 Call OPL from R Diet.r is system("oplrun diet.mod diet.dat") To run this example, simply do Rscript.exe diet.r And in Rscript.exe diet.r you ll get quantity = [0 2.1552 0 0 0 10 1.8312 0 0.9297] cost = 2.690409172 amount = [2000 800 11.278 8518.4 25 256.81 51.174]
  • 11. © 2017 IBM Corporation11 Agenda  Call OPL from outside OPL  Modeling tricks  Practical tricks within OPL  Decomposition  Specific examples
  • 12. © 2017 IBM Corporation12 How to describe a piecewise linear function with breakpoints rather than slopes  float firstSlope=0.5; float lastSlope=2.0; tuple breakpoint // y=f(x) { key float x; float y; } sorted { breakpoint } breakpoints={<0,0>,<1,1>,<2,4>}; float slopesBeforeBreakpoint[b in breakpoints]= (b.x==first(breakpoints).x) ?firstSlope :(b.y-prev(breakpoints,b).y)/(b.x-prev(breakpoints,b).x); pwlFunction f=piecewise(b in breakpoints) { slopesBeforeBreakpoint[b]->b.x; lastSlope } (first(breakpoints).x, first(breakpoints).y); assert forall(b in breakpoints) f(b.x)==b.y;
  • 13. © 2017 IBM Corporation13 How to multiply a decision variable with a boolean decision variable using CP; dvar int x in 2..10; dvar boolean b; maximize x; subject to { b*x<=7; } dvar int x in 2..10; dvar boolean b; dvar int bx; maximize x; subject to { bx<=7; (b==1) => (bx==x); (b==0) => (bx==0); } dvar int x in 2..10; dvar boolean b; dvar int bx; maximize x; subject to { bx<=7; 2*b<=bx; bx<=10*b; bx<=x-2*(1-b); bx>=x-10*(1-b); }
  • 14. © 2017 IBM Corporation14 How to use a decision variable as an index in an array with CPLEX using CP; range r=1..5; float value[r]=[2,3,4.5,1,0]; dvar int i in 1..5; maximize value[i]; subject to { } execute { writeln("i=",i); } range r=1..5; float value[r]=[2,3,4.5,1,0]; dvar int i in 1..5; maximize sum(k in r) value[k]*(k==i); subject to { } execute { writeln("i=",i); }
  • 15. © 2017 IBM Corporation15 Agenda  Call OPL from outside OPL  Modeling tricks  Practical tricks within OPL  Decomposition  Specific examples
  • 16. © 2017 IBM Corporation16 Displaying 2 dimensions objects in the OPL IDE  tuple sequence_like { int start; int end; string label; int type; }; {sequence_like} array2[i in 1..n] = {<j-1,j," ",Life[i][j]> | j in 1..n};
  • 17. © 2017 IBM Corporation17 Export into a csv file tuple t { string firstname; int number; } {t} s={<"Nicolas",2>,<"Alexander",3>}; execute { var f=new IloOplOutputFile("export.csv"); for(var i in s) { f.writeln(i.firstname,";",i.number,";"); } f.close(); } writes a file export.csv Nicolas;2; Alexander;3;
  • 18. © 2017 IBM Corporation18 Import from csv file Suppose you have this export.cvs file Nicolas;2; Alexander;3; Then you could write tuple t { string firstname; int number; } {t} s={}; execute { var f=new IloOplInputFile("export.csv"); while (!f.eof) { var str=f.readline(); //writeln(str); var ar=str.split(";"); if (ar.length==3) s.add(ar[0],Opl.intValue(ar[1])); } f.close(); } execute { writeln(s); } which will read the csv file and compute the tuple set s: {<"Nicolas" 2> <"Alexander" 3>}
  • 19. © 2017 IBM Corporation19 Cartesian product in OPL tuple Tset { {string} members; } {Tset} setOfTuples = {<{"1","2"}>,<{"4","5","6"}>,<{"8","9"}>}; int dimresult=prod(i in 1..card(setOfTuples)) card(item(setOfTuples,i- 1).members); {string} setPool[i in 1..dimresult]={}; // pool of sets {string} options[i in 1..card(setOfTuples)]=(item(setOfTuples,i- 1).members); {Tset} result={}; //For this particular example, the function needs to return: //{<{1,4,8}>,<{1,4,9}>,<{1,5,8}>,<{1,5,9}>,<{1,6,8}>,<{1,6,9}>,<{2,4,8}>,<{2 ,4,9}>,<{2,5,8}>,<{2,5,9}>,<{2,6,8}>,<{2,6,9}>} execute { options; function nextone(ndimension,sizes,e) { e[1]++; for(j=1;j<=ndimension;j++) { if (e[j]>= sizes[j] ) { e[j]=0; e[j+1]++; } } } var dim=setOfTuples.size; writeln("dim=",dim); var sizes=new Array(dim); var e=new Array(dim); var dimresult=1; for(var i=1;i<=dim;i++) { sizes[i]=Opl.item(setOfTuples,i-1).members.size; e[i]=0; dimresult*=sizes[i]; writeln(sizes[i]); } for(var i=1;i<=dimresult;i++) { for(var j=1;j<=dim;j++) { write(e[j]," "); setPool[i].add(Opl.item(options[j],e[j])); } writeln(); nextone(dim,sizes,e); result.add(setPool[i]); } writeln(result); }
  • 20. © 2017 IBM Corporation20 Powerset in OPL {string} s={"A","B","C","D"}; range r=1.. ftoi(pow(2,card(s))); {string} s2 [k in r] = {i | i in s: ((k div (ftoi(pow(2,(ord(s,i))))) mod 2) == 1)}; execute { writeln(s2); }
  • 21. © 2017 IBM Corporation21 How to evaluate CPLEX random seed variability in OPL int n=30; // number of random seeds int d[1..n]; // duration int o[1..n]; // objective int iter[1..n]; // iterations // start of the model we want to test int Fixed = 100; int NbWarehouses = 50; int NbStores = 200; assert( NbStores > NbWarehouses ); range Warehouses = 1..NbWarehouses; range Stores = 1..NbStores; int Capacity[w in Warehouses] = NbStores div NbWarehouses + w % ( NbStores div NbWarehouses ); int SupplyCost[s in Stores][w in Warehouses] = 1 + ( ( s + 10 * w ) % 100 ); dvar int Open[Warehouses] in 0..1; dvar float Supply[Stores][Warehouses] in 0..1; dexpr int TotalFixedCost = sum( w in Warehouses ) Fixed * Open[w]; dexpr float TotalSupplyCost = sum( w in Warehouses, s in Stores ) SupplyCost[s][w] * Supply[s][w]; minimize TotalFixedCost + TotalSupplyCost; subject to { forall( s in Stores ) ctStoreHasOneWarehouse: sum( w in Warehouses ) Supply[s][w] == 1; forall( w in Warehouses ) ctOpen: sum( s in Stores ) Supply[s][w] <= Open[w] * Capacity[w]; } // end of the model we want to test main { thisOplModel.generate(); var sum_d=0; var sum_o=0;; var sum_iter=0; writeln("seed objective iteration runtime"); for(var i=1;i<=thisOplModel.n;i++) { var opl=new IloOplModel(thisOplModel.modelDefinition); opl.generate(); cplex.randomseed=i; var d1=new Date(); cplex.solve(); var d2=new Date(); thisOplModel.d[i]=d2-d1; sum_d+=d2-d1; thisOplModel.d[i]=d2-d1; thisOplModel.o[i]=Opl.ftoi(Opl.round(cplex.getObjValue())); sum_o+=thisOplModel.o[i]; thisOplModel.iter[i]=cplex.getNiterations(); sum_iter+=thisOplModel.iter[i]; writeln(i," ",thisOplModel.o[i]," ",thisOplModel.iter[i]," ", thisOplModel.d[i]/1000); cplex.clearModel(); } writeln("-----------------------------------------"); writeln("average ",sum_o/thisOplModel.n," ", sum_iter/thisOplModel.n," ",sum_d/thisOplModel.n/1000); writeln("std dev ",Opl.standardDeviation(thisOplModel.o)," ", Opl.standardDeviation(thisOplModel.iter)," ",Opl.standardDeviation(thisO plModel.d)/1000); }
  • 22. © 2017 IBM Corporation22 Agenda  Call OPL from outside OPL  Modeling tricks  Practical tricks within OPL  Decomposition  Specific examples
  • 23. © 2017 IBM Corporation23 Hybrid CPO and CPLEX int n=20; int values[0..(n+2)*(n+2)-1]; main { var n=20; var source1 = new IloOplModelSource("lifegameip.mod"); var cplex = new IloCplex(); var def1 = new IloOplModelDefinition(source1); var source2 = new IloOplModelSource("lifegamecp.mod"); var cp = new IloCP(); var def2 = new IloOplModelDefinition(source2); var opl1 = new IloOplModel(def1,cplex); var opl2 = new IloOplModel(def2,cp); opl1.generate(); opl2.generate(); var objValues=new Array(2*5); for(var iter=1;iter<=5;iter++) { cplex.tilim=10; cplex.solve(); writeln("cplex objective = ",cplex.getObjValue()); objValues[iter*2-1]=cplex.getObjValue(); cp.param.timelimit=10; cp.param.SearchType=24; // Warmstart var sol=new IloOplCPSolution(); for(var i=0;i<=(n+2)*(n+2)-1;i++) sol.setValue(opl2.x[i],opl1.x[i]); cp.setStartingPoint(sol); cp.param.SearchType=24; //opl2.Obj.LB=cplex.getObjValue(); cp.solve(); writeln("cpo objective =",cp.getObjValue()); objValues[iter*2]=cp.getObjValue(); var vectors = new IloOplCplexVectors(); // We attach the values (defined as data) as starting solution // for the variables x. for(var i=0;i<=(n+2)*(n+2)-1;i++) thisOplModel.values[i]=opl2.x[i]; vectors.attach(opl1.x,thisOplModel.values); vectors.setVectors(cplex); } writeln("list of objectives") ; for(var i=1;i<=10;i++) writeln(objValues[i]); }
  • 24. © 2017 IBM Corporation24 How to change the model without regeneration, incremental cplex matrix modification dvar float+ Gas; dvar float+ Chloride; maximize 40 * Gas+ 50 * Chloride; subject to { ctMaxTotal: Gas+ Chloride<= 50; ctMaxTotal2: 3 * Gas+ 4 * Chloride<= 180; ctMaxChloride: Chloride<= 40; ctEmpty: Gas<=infinity; } execute { writeln("Gas = ",Gas); writeln("Chloride = ",Chloride); writeln("Objective = ",cplex.getObjValue()); main { thisOplModel.generate(); cplex.solve(); thisOplModel.postProcess(); writeln(); writeln("And then we add the constraint Chloride - Gas <=5"); writeln(); thisOplModel.ctEmpty.UB=5; thisOplModel.ctEmpty.setCoef(this OplModel.Gas,-1); thisOplModel.ctEmpty.setCoef(this OplModel.Chloride,1); cplex.solve(); thisOplModel.postProcess(); }
  • 25. © 2017 IBM Corporation25 How to solve the same model with different data ? Change a value and generate again float maxOfx = ...; dvar float x; maximize x; subject to { x<=maxOfx; } execute { writeln("x= ",x); } main { var source = new IloOplModelSource("sub.mod"); var cplex = new IloCplex(); var def = new IloOplModelDefinition(source); for(var k=1;k<=10;k++) { var opl = new IloOplModel(def,cplex); var data2= new IloOplDataElements(); data2.maxOfx=k; opl.addDataSource(data2); opl.generate(); if (cplex.solve()) { opl.postProcess(); writeln("OBJ = " + cplex.getObjValue()); } else { writeln("No solution"); } opl.end(); } }
  • 26. © 2017 IBM Corporation26 How to solve the same model with different data ? Change an array and generate again int y[1..2][1..2]=...; execute { writeln("y=",y); } dvar float x; maximize x; subject to { x<=sum(i in 1..2, j in 1..2) y[i][j]; } int a[1..2][1..2]; main { var source = new IloOplModelSource("sub.mod"); var cplex = new IloCplex(); var def = new IloOplModelDefinition(source); for(var k=11;k<=15;k++) { var opl = new IloOplModel(def,cplex); var data2= new IloOplDataElements(); data2.y=thisOplModel.a; data2.y[1][1]=k; opl.addDataSource(data2); opl.generate(); if (cplex.solve()) { writeln("OBJ = " + cplex.getObjValue()); } else { writeln("No solution"); } data2.end(); opl.end(); } }
  • 27. © 2017 IBM Corporation27 How to solve the same model with different data ? Change a set and generate again {int} y=...; execute { writeln("y=",y); } dvar float x; maximize x; subject to { x<=sum(i in y)i; } execute { writeln("x=",x); } {int} s={}; main { var source = new IloOplModelSource("sub.mod"); var cplex = new IloCplex(); var def = new IloOplModelDefinition(source); for(var k=1;k<=5;k++) { var opl = new IloOplModel(def,cplex); var data2= new IloOplDataElements(); data2.y=thisOplModel.s; data2.y.add(k); opl.addDataSource(data2); opl.generate(); if (cplex.solve()) { writeln("OBJ = " + cplex.getObjValue()); } else { writeln("No solution"); } data2.end(); opl.end(); } }
  • 28. © 2017 IBM Corporation28 Solve Anyway int prefsolveanyway1[1..1]=[0]; int prefsolveanyway2[1..1]=[0]; int prefsolveanyway3[1..1]=[0]; int priority[1..3]=[1,2,3]; dvar int x; dvar int y; dvar int z; subject to { 0<=x<=20; 0<=y<=20; 0<=z<=20; forall(i in 1..1) ct1:y-x>=7; forall(i in 1..1) ct2:z-y>=9; forall(i in 1..1) ct3:z-x<=10; } main { function writeRelaxation(opl) { var iter = opl.relaxationIterator; for(var c in iter) { var constraint=c.ct; writeln(constraint.name); writeln("LB = ",c.LB); writeln("UB = ",c.UB); writeln("relaxedLB = ",c.relaxedLB); writeln("relaxedUB = ",c.relaxedUB); } } thisOplModel.generate(); var def = thisOplModel.modelDefinition; // Default behavior writeln("Default Behavior"); writeln(); var cplex1 = new IloCplex(); var opl1 = new IloOplModel(def, cplex1); opl1.settings.relaxationLevel=1; writeln("Solve Anyway"); // Priority 1 : ct1 // Priority 2 : ct2 // Priority 3 : ct3 var currentPriority = 1; var noSolution=1; while (noSolution==1) { writeln(); var cplex2 = new IloCplex(); var opl2 = new IloOplModel(def, cplex2); opl2.generate(); writeln("relaxing priority less than ",currentPriority) ; if (opl2.priority[1]<=currentPriority) opl2.prefsolveanyway1[1]=1; else opl2.prefsolveanyway1[1]=0; if (opl2.priority[2]<=currentPriority) opl2.prefsolveanyway2[1]=1; else opl2.prefsolveanyway2[1]=0; if (opl2.priority[3]<=currentPriority) opl2.prefsolveanyway3[1]=1; else opl2.prefsolveanyway3[1]=0; opl2.relaxationIterator.attach(opl2.ct1, opl2.prefsolveanyway1); opl2.relaxationIterator.attach(opl2.ct2, opl2.prefsolveanyway2); opl2.relaxationIterator.attach(opl2.ct3, opl2.prefsolveanyway3); writeRelaxation(opl2); writeln("cplex status = ",cplex2.getCplexStatus()); if (cplex2.getCplexStatus()==14) { noSolution=0; writeln("x,y,z = ",opl2.x," ",opl2.y," ",opl2.z); } currentPriority++; } opl2.end(); cplex2.end();
  • 29. © 2017 IBM Corporation29 Agenda  Call OPL from outside OPL  Modeling tricks  Practical tricks within OPL  Decomposition  Specific examples
  • 30. © 2017 IBM Corporation30 TSP with CPO  minimize endOf(itvs[n+1]) - (n+1); subject to { startOf(itvs[1])==0; // break sym noOverlap(seq,Dist,true); // nooverlap with a distance matrix last(seq, itvs[n+1]); // last node }  NB:  For big instances, CPLEX works better than CPO but as soon as you add side constraints then CPO can tackle whereas CPLEX not always can  Plus CPO gives a solution any time wheras with CPLEX you need a flow control to remove circuits.
  • 31. © 2017 IBM Corporation31 DEA (Data Envelopment Analysis)  "Data envelopment analysis (DEA) is a nonparametric method in operations research and economics for the estimation of production frontiers. It is used to empirically measure productive efficiency of decision making units (or DMUs). Although DEA has a strong link to production theory in economics, the tool is also used for benchmarking in operations management, where a set of measures is selected to benchmark the performance of manufacturing and service operations." (Wikipedia)  This method relies on linear programming and looks at the past  ( ex post)  Always the same model, no ad hoc model so quick to implement
  • 32. © 2017 IBM Corporation32 Data Envelopment Analysis (DEA) in OPL int nbDMU=...; int nbInputs= ...; int nbOutputs=...; range DMU=1..nbDMU; range Input=1..nbInputs; range Output=1..nbOutputs; // Input float X[DMU][Input]=...; // Output float Y[DMU][Output]=...; int refDMU=...; // We want to measure efficiency of that DMU assert refDMU in DMU; dvar float+ theta; dvar float+ lambda[DMU]; minimize theta; subject to { forall(j in Input) ctInput: sum(i in DMU) (lambda[i]*X[i][j]) <= theta*X[refDMU][j]; forall(j in Output) ctOutput: sum(i in DMU) (lambda[i]*Y[i][j]) >= Y[refDMU][j]; } execute { writeln("theta= ",theta); if (theta==1) writeln("Efficient DMU"); // Loop to measure efficiency for all DMU main { thisOplModel.generate(); for(var dmu in thisOplModel.DMU) { writeln("DMU",dmu); for(j in thisOplModel.Input) thisOplModel.ctInput[j].setCoef(thisO plModel.theta,- thisOplModel.X[dmu][j]); for(j in thisOplModel.Output) thisOplModel.ctOutput[j].LB=thisOplM odel.Y[dmu][j]; cplex.solve(); thisOplModel.postProcess(); }
  • 33. © 2017 IBM Corporation33 How to import docplexcloud solution into a local OPL session from docloud.job import JobClient client = JobClient(url, key) // Run the model in docplexcloud with open("model/diet.mod", "rb") as modFile: resp = client.execute(input=[{"name":"diet.mod", "file":modFile}, "model/diet.dat"], output="results.json", log="solver.log", gzip=True, waittime=300, delete_on_completion=True) // import the json result file import json with open('results.json') as data_file: data = json.load(data_file) // write that into a .dat res = open("sol.dat", "w") res.write("s={"); quote='"' for i in data["s"]: res.write("<"+quote+i["food"]+quote+ "," +quote+i["nutrient"]+quote+","+str(i[" value"])+",>") res.write("};") res.close()