Languages bar chart generated from OPL CPLEX through a python call

Part 1 is now in 23 human languages, 23 like the number of chromosomes we humans all have and that’s time to give more options with computer languages.

In that previous post, I gave 2 examples with the most popular languages for CPLEX : OPL and python, an algebraic modeling language (AML) and a general programming language (GPL)

API pie chart generated from OPL CPLEX through a python call

With both OPL and python docplex API, we can

call CPLEX Linear Programming and Constraint Programming (CPOptimizer)

call CPLEX on a given machine, in the cloud (WML) and on an optimization server

I really recommend OPL and the use of OPL C++/JAVA/.NET/python API. For the ones who really need to write python only I suggest the python docplex api.

But there are many other options with CPLEX.

docplex is not the only CPLEX python API JAVA, C++, Scala,Julia,Optano CPLEX specific formats Other AML (Algebraic Modeling Languages) like GAMS , AIMMS and AMPL

But also with other tools that won’t scale

opensource like GLPK geometry plain enumeration

In the past, this bus and kids example has not only helped many to understand what optimization is but also some to start with a small model and then improve. So let me share what helped.

docplex is not the only CPLEX python API

CPLEX matrix python API

# Import packages.

import cplex my_prob = cplex.Cplex() my_obj = [500, 400]

my_ub = [cplex.infinity, cplex.infinity]

my_lb = [0.0, 0.0]

my_ctype = "II"

my_colnames = ["nbBus40", "nbBus30"]

my_rhs = [300]

my_rownames = ["nbKids"]

my_sense = "G" my_prob.objective.set_sense(my_prob.objective.sense.minimize) my_prob.variables.add(obj=my_obj, lb=my_lb, ub=my_ub, types=my_ctype,

names=my_colnames) rows = [[["nbBus40", "nbBus30"], [40,30]]] my_prob.linear_constraints.add(lin_expr=rows, senses=my_sense,

rhs=my_rhs, names=my_rownames) my_prob.solve() print("cost = ", my_prob.solution.get_objective_value()) numcols = my_prob.variables.get_num()



sol = my_prob.solution.get_values() for j in range(numcols):

print(my_colnames[j]," = ", sol[j])

pyomo

import pyomo.environ as pyo

from pyomo.opt import SolverFactory opt = pyo.SolverFactory('cplex') model = pyo.ConcreteModel() model.nbBus = pyo.Var([40,30], domain=pyo.PositiveIntegers) model.OBJ = pyo.Objective(expr = 500*model.nbBus[40] + 400*model.nbBus[30]) model.Constraint1 = pyo.Constraint(expr = 40*model.nbBus[40] + 30*model.nbBus[30] >= 300) results = opt.solve(model) print("nbBus40=",model.nbBus[40].value)

print("nbBus30=",model.nbBus[30].value)

pulp

import pulp

import cplex bus_problem = pulp.LpProblem("bus", pulp.LpMinimize) nbBus40 = pulp.LpVariable('nbBus40', lowBound=0, cat='Integer')

nbBus30 = pulp.LpVariable('nbBus30', lowBound=0, cat='Integer') # Objective function

bus_problem += 500 * nbBus40 + 400 * nbBus30, "cost" # Constraints

bus_problem += 40 * nbBus40 + 30 * nbBus30 >= 300 bus_problem.solve(pulp.CPLEX())

print(pulp.LpStatus[bus_problem.status]) for variable in bus_problem.variables():

print ("{} = {}".format(variable.name, variable.varValue))

cvxpy

# Import packages.

import cvxpy as cp # Define and solve the CVXPY problem.

nbBus40 = cp.Variable(integer=True)

nbBus30 = cp.Variable( integer=True)

cost = 500*nbBus40+400*nbBus30

prob = cp.Problem(cp.Minimize(cost),[40*nbBus40+30*nbBus30>=300,

nbBus40>=0,nbBus30>=0

]) prob.solve(solver=cp.CPLEX,verbose=True) # Print result.

print("

The minimal cost is", prob.value) print("number buses 40 seats = ",nbBus40.value)

print("number buses 30 seats = ",nbBus30.value)

JAVA, C++, Scala,Julia

JAVA

import ilog.concert.*;

import ilog.cplex.*;

import ilog.opl.*; static public void main(String[] args) throws Exception

{

IloCplex cplexBus = new IloCplex(); // decision variables

IloNumVar nbbus40 = cplexBus.numVar(0, 10000,IloNumVarType.Int);

IloNumVar nbbus30 = cplexBus.numVar(0, 10000,IloNumVarType.Int); // move at least 300 kids to the zoo

cplexBus.addGe(cplexBus.sum(cplexBus.prod(40,nbbus40), cplexBus.prod(30,nbbus30)),300); // objective : minimize cost = 500*nbbus40+400*nbBus30

cplexBus.addMinimize(cplexBus.sum(cplexBus.prod(500,nbbus40), cplexBus.prod(400,nbbus30))); cplexBus.solve(); System.out.println("nbbus40 : " +cplexBus.getValue(nbbus40) );

System.out.println("nbbus30 : " +cplexBus.getValue(nbbus30) ); }

C++

#include <iostream>

#include <ilcplex/ilocplex.h> using std::cout;

using std::cerr;

using std::endl; int

main(void)

{

IloEnv env;

try {

IloModel model(env); // int nbKids = 300

int nbKids = 300;

// float costBus40 = 500

// float costBus30 = 400

double costBus40 = 500;

double costBus30 = 400; // dvar int+ nbBus40;

// dvar int+ nbBus30;

IloIntVar nbBus40(env, 0, IloInfinity, "nbBus40");

IloIntVar nbBus30(env, 0, IloInfinity, "nbBus30"); // minimize costBus40 * nbBus40 + costBus30 * nbBus30

IloExpr cost = costBus40 * nbBus40 + costBus30 * nbBus30;

model.add(IloMinimize(env, cost)); // subjec to {

// 40 * nbBus40 + 30 * nbBus30 >= nbKids

// }

model.add(40 * nbBus40 + 30 * nbBus30 >= nbKids); IloCplex cplex(model);

cplex.solve(); cout << "Use " << cplex.getValue(nbBus40) << " buses of type 40" << endl;

cout << "Use " << cplex.getValue(nbBus30) << " buses of type 30" << endl;

cout << "Total cost: " << cplex.getValue(cost) << endl; env.end();

}

catch (IloException &e) {

cerr << "exception: " << e << endl;

throw;

}

return 0;

}

SCALA

import com.decisionbrain.cplexscala.Modeler._



object Buses {



def solve(): Unit = {



val nbKids: Int = 300

val costBust40: Double = 500

val costBust30: Double = 400



implicit val model: MpModel = MpModel("buses")



val nbBus40 = model.intVar(name="nbBus40")

val nbBus30 = model.intVar(name="nbBus30")



model.add(nbBus40*40 + nbBus30*30 >= nbKids)



model.add(minimize(costBust40*nbBus40 + costBust30*nbBus30))



model.solve()



println(s"# bus of size 40: ${model.getValue(nbBus40)}")

println(s"# bus of size 30: ${model.getValue(nbBus30)}")

}



def main(args: Array[String]): Unit = {

solve()

}

}

Julia

import Pkg

Pkg.add("JuMP")

Pkg.add("CPLEX") model = Model(CPLEX.Optimizer)

(model, nbbus30, lower_bound=0, integer=true) @variable (model, nbbus40, lower_bound=0, integer=true) @variable (model, nbbus30, lower_bound=0, integer=true)

(model, Min, 500*nbbus40+400*nbbus30) # Objective - minimize cost @objective (model, Min, 500*nbbus40+400*nbbus30)

(model,40*nbbus40+30*nbbus30>=300) # 300 kids at least @constraint (model,40*nbbus40+30*nbbus30>=300) # Solve

JuMP.optimize!(model) # Display

print("nbbus40=",(JuMP.value(nbbus40)))

print("

");

print("nbbus30=",(JuMP.value(nbbus30)))

Optano

// create a new dotnet project // > dotnet new console // Add OPTANO Modeling // > dotnet add package

optano.modeling // add this code to project.cs as a

var nbKids = 300; var costBus40 = 500d;

var costBus30 = 400d;

var nbBus40 = new Variable("nbBus40", type: VariableType.Integer); var nbBus30 = new Variable("nbBus30", type: VariableType.Integer); var model = new Model();

model.AddObjective(

new Objective(costBus40 * nbBus40 + costBus30 * nbBus30));

model.AddConstraint(40 * nbBus40 + 30 * nbBus30 >= nbKids, "Kids"); var solver = new CplexSolver();

var solution = solver.Solve(model);



Console.WriteLine($"Objective {solution.ObjectiveValues.Single()}"); Console.WriteLine($"nbBus40: {nbBus40.Value}"); Console.WriteLine($"nbBus30: {nbBus30.Value}");

CPLEX specific formats

LP format

Minimize

obj1: 500 nbBus40 + 400 nbBus30

Subject To

c1: 40 nbBus40 + 30 nbBus30 >= 300

Bounds

nbBus40 >= 0

nbBus30 >= 0

Generals

nbBus40 nbBus30

End

MPS format

NAME Zoo

ROWS

N obj1

G c1

COLUMNS

MARK0000 'MARKER' 'INTORG'

nbBus40 obj1 500

nbBus40 c1 40

nbBus30 obj1 400

nbBus30 c1 30

MARK0001 'MARKER' 'INTEND'

RHS

rhs c1 300

BOUNDS

LI bnd nbBus40 0

LI bnd nbBus30 0

ENDATA

Other AML (Algebraic Modeling Languages) like GAMS , AIMMS and AMPL

GAMS

Variable

cost;Integer Variables

nbbus40, nbbus30;Equations

obj, c1;obj.. cost =e= 500 * nbbus40 + 400 * nbbus30;

c1.. 40 * nbbus40 + 30 * nbbus30 =g= 300;option optcr = 1e-3;

Model buses / all /;

Solve buses using MIP minimizing cost;

AIMMS

AMPL

param nbKids = 300;

param costBus40 = 500;

param costBus30 = 400;



var nbBus40 integer >= 0;

var nbBus30 integer >= 0;



minimize TotalBuses:

costBus40*nbBus40 + costBus30*nbBus30;



subject to TravelNeeds:

40*nbBus40 + 30*nbBus30 >= nbKids;

Other tools that won’t scale

opensource like GLPK

var nbBus40, integer, >=0;

var nbBus30, integer, >=0; s.t. ctKids:40*nbBus40+30*nbBus30>=300; minimize obj: 500*nbBus40+400*nbBus30; /* solve the problem */

solve; /* and print its optimal solution */

printf("nbBus40 = ");

printf(nbBus40);

printf("

");

printf("nbBus30 = ");

printf(nbBus30);

printf("

"); end;

geometry

plain enumeration (In python or any language)

nbKids=300

costBus40=500

costBus30=400

minCost=100000

nbBus40min=0

nbBus30min=0 for nbBus40 in range(0,nbKids // 40+1):

for nbBus30 in range(0,nbKids // 30+1):

if (40*nbBus40+30*nbBus30>=nbKids):

newCost=costBus40*nbBus40+costBus30*nbBus30

if newCost<minCost:

minCost=newCost

nbBus40min=nbBus40

nbBus30min=nbBus30



print("Result")

print("nbBus40=",nbBus40min)

print("nbBus30=",nbBus30min)

PS:

My bus and kids example escaped me. Others started to use it: