taller ibm ilog cplex - udeceliseomelgarejo/cplex/taller_cplex.pdf · el departamento de ventas...

37
Taller IBM Ilog Cplex Eliseo Melgarejo http://www.udec.cl/~eliseomelgarejo Agradecimientos Rodrigo Linfati M. http://www.linfati.cl

Upload: others

Post on 20-May-2020

25 views

Category:

Documents


0 download

TRANSCRIPT

Taller IBM Ilog Cplex

Eliseo Melgarejo http://www.udec.cl/~eliseomelgarejo

Agradecimientos

Rodrigo Linfati M. http://www.linfati.cl

Contenidos

Contexto

Nuevo Proyecto en Visual C++

Comandos básicos

Programación lineal

Programación entera

Familia ILOG

IBM ILOG CPLEX®

IBM ILOG CPLEX is an optimization software package. It is named for the simplex method and the C programming Language. IBM ILOG CPLEX can be accessed from most programming environments and used on a wide variety of platforms, providing true portability.

Metodos de Solución

Programación Lineal

Base c++

#include <ilcplex/ilocplex.h>

ILOSTLBEGIN

int main(int, char**)

{ try {

}

}

Definición de ambiente

Antes de crear cualquier modelo se debe crear un objeto de la clase IloEnv, conocido como “Enviroment” dentro de la función main.

IloEnv env;

env.end();

Definición de modelo

Luego de crear el “Enviroment” debemos crear un modelo dentro de “try”

IloModel modelo(env);

Definición de variables

Tipos de variables IloInt IloFloat IloBool

IloIntArray IloNumArray IloBoolArray

Ej IloNumArray vector (env, 5); vector[i] , para toda i=1,..,5

IloBool vector;

IloNumArray data(env, 3, 1.0, 2.0, 3.0); cout << data << endl; [1.0, 2.0, 3.0]

Longitud arreglo

Ambiente

Definición de variables

Variables de decisión IloNumVar, IloIntVar, IloBoolVar

IloNumVarArray IloIntVarArray IloBoolVarArray

Ej IloNumVarArray x(env, 2, 0, IloInfinity ); x[0], x[1]

Longitud arreglo

Limite inferior

Limite superior

Ambiente

Definición de variables

Expresiones IloExpr

Ej: IloExpr fo = 2*x[0]+3*x[1]; (particular)

IloExpr expr(env); (general) for (int i = 0; i < x.getSize(); ++i) expr += c[i] * x[i];

expr.end(); (liberar memoria)

Longitud arreglo

Definición de variables

Expresiones IloExpr

Ej2: IloInt sizeX=5; IloNumVarArray x(env,sizeX,0,IloInfinity); IloNumArray c(env,sizeX); for (IloInt i=0; i<sizeX; i++) { c[i]=i; IloExpr sum = IloScalProd(c,x); }

Definición de variables

Definir función objetivo

Ej

modelo.add(IloMaximize(env, fo));

modelo.add(IloMinimize(env, expr));

Restricciones

Restriciones

Metodo1:

modelo.add(2*x[0] + x[1] <= 18 );

modelo.add(2*x[0] + 3*x[1] <= 42 );

modelo.add(3*x[0] + x[1] <= 24 );

Expresión

Restricciones

Restriciones

Metodo2:

IloRange r1(env,15, 2*x[0] + x[1] , 18 )); IloRange r2(env,2*x[0] + 3*x[1] , 42 )); IloRange r3(env,24, 3*x[0] + x[1]));

modelo.add(r1); modelo.add(r2); modelo.add(r3);

Expresión

Limite inferior (env,LI,expr,LS)

Limite superior

Restricciones

Restriciones

Metodo3:

IloRangeArray range(env);

range.add(IloRange(env, 4, 2*x[0] + x[1] , 18 )); range.add(IloRange(env, 2, 2*x[0] + 3*x[1] , 42 )); range.add(IloRange(env, 0, 3*x[0] + x[1] , 24 ));

modelo.add(range);

Expresión

Limite inferior Limite superior

¿Cómo resolver?

IloCplex cplex ( env );

cplex.setOut(env.getNullStream()); // omitir para problemas grandas para ver como avanza la solucion

cplex.extract(modelo); cplex.exportModel ( “salida.lp" ); env.out() << "Variables binarias: " << cplex.getNbinVars() << endl; env.out() << "Variables Enteras: " << cplex.getNintVars() << endl; env.out() << "Filas - Restricciones: " << cplex.getNrows() << endl; env.out() << "Columnas - Variables: " << cplex.getNcols() << endl;

if ( !cplex.solve() ) { env.error() << "No se pudo resolver :-(" << endl; throw ( -1 ); } env.out() << "Es optimo ? = " << cplex.getStatus() << endl; env.out() << "Valor de fo = " << cplex.getObjValue() << endl; env.out() << "Se demoro = " << env.getTime() << endl;

} catch (IloException& ex) { cerr << "Error Cplex: " << ex << endl; } catch (...) { cerr << "Error Cpp" << endl; } env.end(); return 0;

¿Cómo pedir los valores de x?

Una forma (crear una variable temporal) IloNumArray temp(env, x.getSize()); cplex.getValues( temp, x); cout << "x = "; cout << temp << endl; Otra forma(directamente) for (int i=0;i<x.getSize();++i) { cout << cplex.getValue(x[i]) << endl; }

¿Cómo crear una matriz?

IloArray <IloNumArray> matriz(env, filas); for (int i=0; i<filas; ++i) { matriz[i] = IloNumArray(env, columnas); }

IloArray <IloIntVarArray> matriz(env, filas); for (int i=0; i<filas; ++i) { matriz[i] = IloIntVarArray(env, columnas); }

Ejercicios

Practicando..

IloNumVarArray muchasx(env, Nlargo, 0, IloInfinity); cout << muchasx << endl << endl;

IloExpr suma = IloSum(muchasx); cout << suma << endl << endl;

IloNumArray costos(env,Nlargo);

for (IloInt i=0; i<Nlargo; ++i) { costos[i]=i; } IloExpr producto = IloScalProd(costos,muchasx); cout << producto << endl << endl;

//qué muestra en producto?? Para Nlargo=4?

Probemos!

Un fabricante de puertas elabora dos tipos de puertas, Puerta Estándar y Puerta de Lujo. Para su elaboración utiliza los recursos “horas-operario” y “horas-prensa”, de los cuales se dispone de 30 y 40 horas para la próxima semana, respectivamente Las características del proceso hacen que una puerta estándar utilice 1 hora-operario y 2 horas-prensa, mientras que una puerta de lujo ocupa 2 horas-operario y 2 horas prensa. Las utilidades para puertas estándar son de $7 por unidad, mientras que son de $12 para las de lujo.

Probemos!

Máx z = 7 * X1 + 12 * X2

X1 + 2 * X2 <= 30 (Restricción de horas operarios)

2 * X1 + 2 * X2 <= 40 (Restricción de horas prensa)

X1 >= 0

X2 >= 0

Probemos!

try{ IloModel modelo(env);

//función objetivo IloNumVarArray x(env, 2, 0, IloInfinity ); IloNumArray c(env, 2, 7, 12);

IloExpr expr(env); for (int i = 0; i < x.getSize(); ++i) expr += c[i] * x[i];

modelo.add(IloMaximize(env, expr));

expr.end();

Probemos!

//restricciones

IloRange r1(env, x[0] + 2*x[1] , 30 );

IloRange r2(env, 2*x[0] + 2*x[1] , 40 );

modelo.add(r1);

modelo.add(r2);

}

Probemos!

Máx z = 7 * X1 + 12 * X2

X1 + 2 * X2 <= 30 (Restricción de horas operarios)

2 * X1 + 2 * X2 <= 40 (Restricción de horas prensa)

X1 >= 0

X2 >= 0

EJEMPLO 2

Una empresa manufacturera ha discontinuado la producción de cierta línea de productos no provechosa. Esto creó un exceso considerable en la capacidad de producción. El gerente está considerando dedicar esta capacidad en exceso a uno o más de tres productos; llamémoslo productos 1, 2 y 3. La capacidad disponible de las máquinas, que podría limitar la producción y los requerimientos por unidad de producto, se resume como sigue:

Ejemplo2

El departamento de ventas indica que el potencial de ventas para los productos 1 y 2 es mayor que la tasa de producción máxima y que el potencial de ventas para el producto 3 es de 20 unidades por semana. La utilidad unitaria sería de $30, $12 y $ 15 respectivamente, para los productos 1, 2 y 3.

Modelo

X1: Cantidad producida del producto 1 en horas disponibles X2: Cantidad producida del producto 2 en horas disponibles X3: Cantidad producida del producto 3 en horas disponibles.

MAX Z = 30*X1 + 12*X2 + 15*X3 S/A

9*X1 + 3*X2 + 5*X3 <= 500 (Restricción de horas de fresadora)

5*X1 + 4*X2 + 0*X3 <= 350 (Restricción de horas de torno)

3*X1 + 0*X2 + 2*X3 <= 150 (Restricción de horas de rectificadora)

X3 <= 20 Restricción de mercado

Ejercicio2(fo)

try { IloModel modelo(env);

//función objetivo IloNumVarArray x(env, 3, 0, IloInfinity ); IloNumArray c(env, 3, 30, 12, 15);

IloExpr expr(env); for (int i = 0; i < x.getSize(); ++i) expr += c[i] * x[i];

modelo.add(IloMaximize(env, expr)); expr.end();

Ejercicio2 //restricciones IloArray <IloNumArray> matriz(env, 3); for (int i=0; i<3; ++i) { matriz[i] = IloNumArray(env, 3); } matriz[0][0]=9; matriz[0][1]=3; matriz[0][2]=5; matriz[1][0]=5; matriz[1][1]=4; matriz[1][2]=0; matriz[2][0]=3; matriz[2][1]=0; matriz[2][2]=2;

cout << matriz << endl << endl; IloNumArray RHS(env,3,500,350,150);

Ejercicio2

IloRangeArray range(env);

for(int i= 0; i < 3; i++) { IloExpr Expr(env); for(int j = 0; j < 3; j++) { Expr = Expr + matriz[i][j]*x[j]; } range.add(IloRange(env, Expr,RHS[i])); Expr.end(); }

range.add(IloRange(env, x[2],20)); modelo.add(range);

Salida excel+duales

//pido mas info IloNumArray temp(env, x.getSize()); cplex.getValues( temp, x); cout << "x = "; cout << temp << endl; cplex.getDuals(temp, range); cout << "Dual: " << temp << endl; cplex.getReducedCosts(temp, x); cout << "Costos Reducidos: " << temp << endl; cplex.getSlacks(temp, range ); cout << "Slacks: " << temp << endl; ofstream salida("salida.csv"); for (int i=0;i<x.getSize();++i) { salida << cplex.getValue(x[i]) << ", "; } salida << endl; salida.close();

Solución Ej 2

Solución Ej 2