La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Profesor: Julio Canales

Presentaciones similares


Presentación del tema: "Profesor: Julio Canales"— Transcripción de la presentación:

1 Profesor: Julio Canales
ILOG OPL 3.7 Profesor: Julio Canales

2 Introducción OPL es un lenguaje de programación, que es empleado en el software ILOG OPL STUDIO, el cual permite el modelado, análisis y resolución de modelos matemáticos, tales como son problemas de optimización.

3 Características más Importantes
Dado la estructura de su código, OPL permite utilizar un mismo modelo con base, para la resolución de problemas de diferentes dimensiones, realizando solo ajustes para que este se adapte a su nuevo tamaño. También permite escribir de forma compacta las distintas restricciones que componen el modelo, mediante el adecuado empleo de los sub-índices de las variables y parámetros que lo componen . El proceso de modelado y resolución del problema son independientes, lo que permite al modelador concentrarse en la construcción del modelo, procurando que este sea consistente con el problema que se desea resolver y dejar que el software se encargue de su resolución del modelo, mediante el empleo de los algoritmo internos que este posee.

4 Características más Importantes
La estructura del lenguaje que emplea OPL, es similar a la estructura matemática con la cual se modelan los problemas, lo cual facilita la comprensión de los modelos desarrollados en OPL, aquellas personas que no se encuentran familiarizadas con el programa y además permite un rápido aprendizaje de este lenguaje.

5 Ejemplo Problema de transporte
Considérese un conjunto de consumidores y productores. Conocida la demanda de cada consumidor, la producción máxima de los productores, y el coste del transporte de los productos desde los productores hasta los consumidores, el problema del transporte consiste en determinar la cantidad de producto a transportar de forma que el costo sea mínimo. Se tienen i productores y j consumidores. Variables de decision xij: Cantidad de producto que se transporta desde el productor i hasta el consumidor j, en toneladas. Datos cij: costo de tranportar desde el productor i al consumidor j, en euros por toneladas y kilómetros.

6 Ejemplo Datos cij: costo de tranportar desde el productor i al consumidor j, en euros por toneladas y kilómetros. ai: producción máxima del productor i, en toneladas. bj: demanda del consumidor j, en toneladas Las distancias en kilometros entre productores y consumidores se muestran en la siguiente tabla: Las producciones máximas son de 300 y 500 toneladas respectivamente. Las demandas son de 100, 200 y 300 toneladas respectivamente. Y el costo de transporte en euros es de 0.09 por tonelada y kilómetro. Consumidores Productores m1 m2 m3 p1 2.0 1.6 1.8 p2 2.5 1.2 1.4

7 Ejemplo Formulación del problema Minimizar: Sujeto a:

8 Ejemplo En OPL, el problema anterior se codifica y almacena en un fichero cuya extensión por defecto es “.mod”. El contenido de este fichero es el siguiente: //Definición de sub-índices. int productores = 2; range i 1..productores; int consumidores = 3; range j 1..consumidores; //Definición Parámetros float+ d[i,j] =[[2, 1.6, 1.8],[2.5,1.2,1.4]]; float+ a[i] = [300,500]; float+ b[j] = [100, 200, 300]; float+ f = 0.09;

9 Ejemplo //Definición de variable var float+ X[i, j]; // F.O. minimize
sum(ii in i, jj in j) ((d[ii,jj]*f) * X[ii,jj]) // S.A. subject to { forall(ii in i) sum(jj in j)X[ii,jj] <= a[ii]; forall(jj in j) sum(ii in i)X[ii,jj] >= b[jj]; };

10 Ejemplo Si se observa el modelo matemático propuesto para resolver el problema y el modelo escrito en OPL, se puede examinar que ambos modelos poseen la misma estructura lógica y solo varia la estructura, donde la simbología matemática es remplazada por los comandos que tiene definido OPL. La primera parte del modelo corresponde a la definición de los sub-indices que serán empleados en el modelo, los cuales establecerán la dimensión de este. Para este fin se utilizan el comando int, que define que se esta haciendo referencia a un valor entero y el comando range hace referencia a la creación de un sub-índice. Cabe señalar que el comando “//” tiene la finalidad de indicar que lo que se esta escribiendo no debe ser considerado como parte del modelo y se emplea principalmente para poner notas en el modelo que permitan una mejor comprensión de esté. En la definición de los parámetros se utiliza el comando float+ que hace referencia a la creación de un valor positivo. En este punto se le pueden instaurar los valores de forma directa a los parámetro, como se realiza en el ejemplo, o estos pueden ser llamados desde una base de datos.

11 Ejemplo En la creación de variables solo se hace referencia al tipo y se antepone el comando var, en este ejemplo se crea mediante el comando var float+ que crea una variable no negativa. Para construir la función objetivo primero se identifica si esta busca minimizar (cuyo comando es minimize) o maximizar (cuyo comando es maximize), para después poner la función objetivo que se quiere resolver. Para instaurar las condiciones bajo las cuales se construye el modelo, se emplea el comando subject to, en el cual se deben de escribir todas las condiciones que serán analizadas. Para la construcción de las ecuaciones se emplean los comando sum, que hace referencias a sumatoria y el comando forall, el cual indica se debe analizar una condición para todos las condiciones que en ella se indiquen.

12 Ejemplo OPL entrega los valores de todas las variables que son procesadas y el valor de la función objetico como se muestra a continuación. Optimal Solution with Objective Value: X[1,1] = X[1,2] = X[1,3] = X[2,1] = X[2,2] = X[2,3] = Cabe señalar que si el número de variables es muy grande, OPL solo entre el valor de la función objetivo y los valores de las variables deben ser solicitados por medio del comando display, que se escribe después de las condiciones o enviados a una planilla de datos.

13 Comandos Básicos de OPL
Para poder instancia un parámetro simple, se le debe identificar el tipo al cual esté pertenecerá y asignarle un valor. int par_int = 4; (parámetro entero) float par_float = 4; (parámetro entero) string par_sting = “Hola”; (parámetro entero)  Obs: Un parámetro puede ser creado sin valor, par después asignarle una más adelante en el modelo de la siguiente manera. int par_int = …; Siempre que se termina una línea de comando se debe de poner ; al final de está. int par_int = 4;

14 Comandos Básicos de OPL
Para poder crear un parámetro con un sub-índice y poder asignarle los valores correspondientes se realiza de la siguiente forma. int CAP[ind] = [3, 2, 3, 4]; En el caso que el parámetro tenga dos o más sub-índices, se define de la siguiente forma. float demanda[ind, ind] = [[3, 1, 4, 5], [5, 2, 1, 1], [0, 0, 5, 1], [5, 8, 2, 3]];

15 Comandos Básicos de OPL
Para crea una variable de decisión se debe anteponer var antes de indicar el tipo al cual corresponde esta. var float+ var[ind]; Para poder definir una variables binarias, se debe indicar que esta es int y despues de definir la variable agregar in 0..1. var int+ varbin[ind] in 0..1;

16 Comandos Básicos de OPL
Para poder definir que las variables y parámetros empleados en el modelo sean valores positivos mayores a 0, se debe al escribí el tipo al cual corresponde agregar el signo mas. int+ CAP[ind] = [3, 2, 3, 4]; float+ demanda[ind, ind] = [[3, 1, 4, 5], [5, 2, 1, 1], [0, 0, 5, 1], [5, 8, 2, 3]]; var float+ var[ind]; var int+ varbin[ind] in 0..1;

17 Comandos Básicos de OPL
La función objetivo se define, primero indicando al tipo que pertenece (maximizar o minimizar), para luego escribir la ecuación que le corresponda a está. minimize sum(i in ind) (var[i]) OBS: La estructura de la operación sumatoria es la siguiente: sum(i in ind) var[i], donde la sentencia entre paréntesis indica el intervalo de la sumatoria y lo que va posterior a la sumatoria indica el o los valores que será empleados en esta.

18 Comandos de OPL Para definir la restricciones del modelo, se utiliza la sentencia subject to. subject to { Restricciones }; Para poder instanciar un grupo de restricciones, el comando más sencillo de emplear es el forall, en este se define primero el rango de los casos a analizar, para luego escribir el planteamiento matemático que corresponde a la restricción a analizar. forall(i in ind) var[i] <= varbin[i]*500;

19 Comandos de OPL Al interior de las restricciones se pueden ingresar condiciones utilizando :, tal como se muestra a continuación. subject to { forall(i in ind : i <= 4) var[i] <= varbin[i]*500; }; También se puede emplear mas de una condición, para lo cual se debe poner una , ó el símbolo & entre estás, como se muestra a continuación. forall(nn in n, xx in x) sum(pp in p)VE[pp,nn,xx] + VEF[xx,nn] = PE[xx,nn]; forall(nn in n & xx in x)

20 Características del Lenguajes Reglas de Uso de OPL
A continuación se describen las reglas más importantes para el uso de OPL. En OPL no es indiferente el uso de mayúsculas o minúsculas. Cada línea de comando debe terminar con un punto y coma. El olvido de este separador de órdenes puede provocar muchos errores de compilación. Se debe seguir el orden para la construcción del modelo, siendo este el siguiente: Cargar las hojas de calculo con las que trabaja el modelo. (opcional) Definir los rangos (sub-índices) Definir los parámetros. Carga datos de los parámetros desde las hojas de datos. (opcional) Definir las variables. Definir la Función Objetivo. Establecer la restricciones. Escribir los resultados en las hojas de calculo correspondientes. (opcional)

21 Características del Lenguajes Reglas de Uso de OPL
Como en cualquier otro lenguaje de programación, los identificadores que se utilicen para declarar datos o variables no pueden coincidir con las palabras reservadas de OPL. Es posible escribir varios comandos en una misma línea siempre que estén separadas por punto y coma. El compilador considera sucesivos espacios en blanco como uno solo. Los identificadores usados en OPL deben comenzar por una letra y pueden ir seguidos por hasta nueve caracteres alfanuméricos, no estando permitida la letra ñ, ni los caracteres especiales como los acentos (esto último tampoco está permitido en los textos explicativos).

22 Comandos Avanzados de OPL
Grabar y leer datos desde documentos Excel Lo primero que se debe realizar es conectar el modelo en OPL con el archivo Excel, esto se realiza por medio del siguiente comando: SheetConnection sheet(“dirección del archivo\NombreArchivo.xls”, 1); El numero que se pone al final, indica si el archivo va a ser empleado solo para lectura, en cuyo caso se pone el número 1 o si se quiere leer y escribir sobre el mismo archivo donde se debe poner el número 0. OBS: sheet corresponde al nombre del documento Excel dentro del modelo, por lo que este puede ser cambiado por otro nombre que sea mas adecuado para el modelo SheetConnection Data1("C:\Modelo_Proyecto_OPL3.7\Datos_Pedido.xls",1);

23 Comandos Avanzados de OPL
Lectura de Datos. Esta se puede realizar de tres formas: Se extraen los rango de los datos indicando el nombre de las celdas, y luego los otros datos que se agregan a sus respectivas matrices. En vez de rangos (range) se utilizan conjuntos (Set), tienen la misma utilidad. {string} Ciudad from SheetRead(sheet, “ciudades”); {string} Productos from SheetRead (sheet, “productos”); float costos[Products, Cities] from SheetRead(sheet, “costos”);

24 Comandos Avanzados de OPL
El comando from SheetRead se utiliza para leer los valores desde el archivo Excel, los parámetros son nombre del SheetConnection y el nombre de la celda. Se extraen los rangos de los datos indicando sólo las coordenadas dentro de la planilla Excel. {string} Ciudad from SheetRead(sheet, “C2:E2”); {string} Productos from SheetRead (sheet, “B3:B5”); float costos[Products, Cities] from SheetRead(sheet, “C3:E5”);

25 float costo[0..2,0..2] from SheetRead(sheet, “C3:E5”);
Comandos Avanzados de OPL Indicando sólo las coordenadas en la planilla de los datos o parámetros a utilizar. float costo[0..2,0..2] from SheetRead(sheet, “C3:E5”);

26 Comandos Avanzados de OPL
Grabar Datos en documento Excel Se utiliza el comando SheetWrite, el que lleva como parámetro el nombre del SheetConnection y las coordenadas de las celdas donde queremos pegar los valores dentro de la planilla Excel. Posterior al comando se pone entre paréntesis el nombre de las variables o parámetros que se desea almacenar. SheetWrite(sheet, “A2:D3”)(produccion); SheetWrite(sheet, “A4”)(Venta); SheetWrite(sheet, “A5:E6”)(Inv); OBS: Esto siempre se escribe al final del modelo.

27 Comandos Avanzados de OPL
Un detalle relevante al momento de emplear los comandos de lectura y escritura, es el asegurarse que las dimensiones de la matriz que están siendo ingresadas son las adecuada. Lo anterior es importante ya que se pueden genera errores de lectura, que ingresen datos incorrectos al motor de resolución, entregado una resultado incorrecto. En el caso de la escritura un mal dimensionamiento de la matriz, provocara el que programa tire un error, al no poder escribir todos los valore pertinentes que se le han solicitado.

28 {string} S2 = {casa, auto, lápiz, bota};
Comandos Avanzados de OPL Cabe señalar que los conjuntos (set) se pueden definir dentro de OPL o al interior de los documentos Excel. En OPL: {Tipo de conjunto} Nombre_conjunto = …; Ejemplo: {int} S1 = {1, 2, 3, 4, 5}; {string} S2 = {casa, auto, lápiz, bota};

29 Comandos Avanzados de OPL
Como definir conjuntos en Excel. Se ingresa a inserta y se selecciona nombre a rango, a continuación se selecciona el rango y se le entrega un nombre. De esta manera se puede llamar al interior de OPL a las celdas seleccionadas mediante el siguiente comando y crear el conjunto {string} Nombre_Conjunto from SheetRead(sheetData," Nombre_dado_en_Excel ");

30 Comandos Avanzados de OPL
OPL también cuenta con la opción de crear súper clases, los cuales pueden contener una gran cantidad de información relacionada a un elemento. Para la creación de estos clases se debe emplear el comando struct de la siguiente forma: Primero se crea la clase struct EJ { int a; int b; }; Se instancia sus valores {EJ} datos = {<1,2>, <2,5>, <4,2>, <3,2>}; //Como un conjunto EJ dato = <1,2>; //Como un valor

31 Comandos Avanzados de OPL
Una clase struct puede soporta cualquier cantidad y variedad de campos, tal como se muestra en el siguiente ejemplo. struct Persona { int edad; string nombre; string dirección; string nacionalidad; };

32 Comandos Avanzados de OPL
La ventaja de las clases struct, es permiten recuperar el valor de uno de los campos específicos que lo componen, tal como se muestra en el siguiente ejemplo. struct Point { int x; int y; }; Sea Point p = <2,3>; Se quiere crear un valor entero que contenga el valor 2 del objeto p. int ej = p.x;

33 Comandos Avanzados de OPL
En relación al manejo de sub-índices, OPL 3.7 reconoce que puede existir mas dos 2, como se muestra en el siguiente ejemplo. Sea: int productor = 2; range o 1..productor; int pedido = 2; range p 1..pedido; int dia = 3; range t 1..dia; Se definir el parámetro cantidad solicitada que depende del producto, pedido y día de entrega. float+ C_S[o,p,t] = …;

34 Comandos Avanzados de OPL
En relación al manejo de sub-índices, OPL 3.7 reconoce que puede existir mas dos 2, como se muestra en el siguiente ejemplo. Sea: int productor = 2; range o 1..productor; int pedido = 2; range p 1..pedido; int dia = 3; range t 1..dia; Se puede definir la variable cantidad enviada desde un producto para un pedido y día especifico. Var float+ C_E[o,p,t];

35 Comandos Avanzados de OPL
La dificulta de emplear sub-índices mayores a 2, es que las bases de datos están diseñadas para trabajar en dos dimensiones, como es el caso de Excel. Por este motivo al momento de asignarle los valores un parámetro, este debe ser construido mediante el comando initialize, el cual permite realizar procesos los parámetros del modelo, antes de que este inicie la resolución de esté. Sea el parámetro: float+ C_S[o,p,t] = …; Con sus datos almacenado en el documento con nombre en el modelo de sheet. Se instancia de la forma que se presenta a continuación.

36 Comandos Avanzados de OPL
Primero se crea un parámetro auxiliar en el que en este caso sel le agregar el número del sub-índice t al final (C_S[o,p,1] = C_S1[o,p]) float+ C_S1[o,p] from SheetRead(sheet, "O5:V9"); float+ C_S2[o,p] from SheetRead(sheet, "W5:AD9"); float+ C_S3[o,p] from SheetRead(sheet, "AE5:AL9");

37 Comandos Avanzados de OPL
Luego se procede con el comando initialize definir una función que le asigne los nuevos valores a los parámetros. initialize forall (oo in o, pp in p) C_S[oo,pp,1] = C_S1[oo,pp]; C_S[oo,pp,2] = C_S2[oo,pp]; C_S[oo,pp,3] = C_S3[oo,pp];

38 Comandos Avanzados de OPL
En el caso de las variables, el motor no tiene problemas para resolver aquellas que tiene un subíndice superior a 2, pero al momento de obtener los resultados se presenta el mismo problema que con los parámetros. Esto se soluciona generando una variable auxiliar de forma similar a la empleada para los parámetros, a la cual dentro del conjunto de restricciones del problema se emplea la misma condición que la empleada en el initialize para los parámetros.

39 Comandos Avanzados de OPL
Var float+ C_E1[oo,pp]; Var float+ C_E2[oo,pp]; Var float+ C_E3[oo,pp]; Subject to { forall (oo in o, pp in p) C_E[oo,pp,1] = C_E1[oo,pp]; C_E[oo,pp,2] = C_E2[oo,pp]; C_E[oo,pp,3] = C_E3[oo,pp]; } SheetWrite(sheet,"B3:G10")(C_E1); SheetWrite(sheet,”B15:G22")(C_E2); SheetWrite(sheet, "B27:G34")(C_E3);

40 Comandos Avanzados de OPL
Otra forma en que se puede trabajar con mas de dos sub-índices, es mediante el empleo de las súper clases (struct), con la cual se pueden definir como un rango para que corran las variables sobre ella, como se muestra en el siguiente ejemplo. Sea la siguiente clase: struct Ejemplo { int e; int p; }; Se genera la clase que contendrá el sub-índice: {Ejemplo} Ej = {<1,1>, <1,2>, <1,3>, <2,1>, <2,2>, <2,3>}; Se define el parámetro valor y la variable Y, en relación al sub-índice Ej. float+ Valor[Ej] = [3, 4, 5, 6, 8, 10] ; var float+ Y[Ej];

41 Comandos Avanzados de OPL
Otra forma en que se puede trabajar con mas de dos sub-índices, es mediante el empleo de las súper clases (struct), con la cual se pueden definir como un rango para que corran las variables sobre ella, como se muestra en el siguiente ejemplo. Se genere una la condición que recorre todos los valores del sub-índice forall(<e, p> in EJ) Valor[<e, p>] * Y <= LIM; ó forall(s in EJ) Valor[s] * Y <= LIM; //Donde s es un elemento del tipo Ejemplo.

42 Comandos Avanzados de OPL
Otra forma en que se puede trabajar con mas de dos sub-índices, es mediante el empleo de las súper clases (struct), con la cual se pueden definir como un rango para que corran las variables sobre ella, como se muestra en el siguiente ejemplo. Para generar una la condición que recorra solo los valores de la primera componente del subíndice se debe: Definir de forma independiente los rango e y p. range ee 1..2; //para el valor de e range pp 1..3; //para el valor de p forall(e in ee) sum( <e, p> in Ej) (Valor[<e, p>] * Y [<e, p>]) <= LIM;


Descargar ppt "Profesor: Julio Canales"

Presentaciones similares


Anuncios Google