taller ibm ilog cplex - udeceliseomelgarejo/cplex/taller_cplex.pdf · el departamento de ventas...
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
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.
Visual C++
Es un entorno de desarrollo integrado (IDE) para lenguajes de programación C, C++ y C++/CLI Cuenta con una versión Express, llamada Microsoft Visual C++ Express Edition, la cual es gratuita y se puede descargar desde el sitio de Microsoft. Visual C++ ocupa librerias como por ejemplo librerías de Ilog Cplex
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); }
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();