Funciones – TEST con operador de relación – Matrices – Generar Transacciones de una familia I) COMPROBACION DEL FUNCIONAMIENTO DE LAS FUNCIONES DE MÁS DE UNA VARIABLE IMPLEMENTADAS MEDIANTE EL LENGUAJE GPSS: Las funciones que maneja el GPSS son de una sola variable, pero, hemos visto que se puede definir funciones que son función de más de una variable. Verificaremos su correcto funcionamiento a través de un nuevo ejemplo, donde simularemos “una bifurcación que es función, no sólo del azar, sino también del horario”, es decir, la distribución de probabilidad cambia función del horario. Vamos a simular las bifurcaciones que se suceden en el horario de 8 a 16 horas de acuerdo a un relevamiento que muestra que el comportamiento es distinto según el horario, detectándose cuatro períodos de tiempo donde la bifurcación al BAR, a la OFICINA o a la SALIDA tiene los siguientes porcentajes de probabilidad: Período 1 Lugar donde va BAR OFICINA SE VA 2 3 4 8 a 10 10 a 12 12 a 14 14 a 16 35,00% 50,00% 15,00% 15,00% 75,00% 10,00% 55,00% 40,00% 5,00% 10,00% 70,00% 20,00% 1) Hay varias maneras de simularlo. Una forma de hacerlo sería colocando el período de tiempo en que nos encontramos en un SAVEVALUE –elegimos un SAVEVALUE porque el período de tiempo es el mismo para todas las transacciones, al cambiar les cambia a todas–: INITIAL GENERATE SAVEVALUE ADVANCE SAVEVALUE ADVANCE SAVEVALUE ADVANCE TERMINATE X$PERIODO,1 ,,7200,1 PERIODO,2 7200 PERIODO,3 7200 PERIODO,4 7200 Es un subsistema de control que se encarga de hacer que el SAVEVALUE PERIODO tome el valor correcto a lo largo del día (de 8 a 10 vale 1 –valor inicial-, de 10 a 12 vale 2, de 12 a 14 vale 3 y de 14 a 16 vale 4) El subsistema anterior mantiene el valor del SAVEVALUE PERIODO en el valor correspondiente de acuerdo al horario. Las transacciones pueden utilizarlo sabiendo que está correctamente actualizado. En este caso la simulación la haremos por tiempo (la extensión de la simulación será de ocho horas, o sea, representará el horario de 8 a 16 para el cual está definido la probabilidad de bifurcación a cada lugar). 2) En lugar del subsistema de control podríamos definir una función que nos devuelve el período: PERIODO FUNCTION AC1,D4 7200,1/14400,2/21600,3/28800,4 Para resolver el problema planteado definimos cuatro funciones, una para cada período de tiempo, y de acuerdo al período en que nos encontramos, es la función que tenemos que utilizar: 1 FUNCTION RN4,D3 .35,BAR/.85,OFICINA/1,SEVA 2 FUNCTION RN3,D3 .15,BAR/.90,OFICINA/1,SEVA 3 FUNCTION RN5,D3 .55,BAR/.95,OFICINA/1,SEVA 4 FUNCTION RN6,D3 .10,BAR/.80,OFICINA/1,SEVA Bifurcaremos utilizando la función, cuyo número de función sea el número de período (el número de período lo tenemos actualizado mediante el subsistema de control especificado antes que lo almacena en el Savevalue PERIODO, ó lo obtenemos utilizando la función PERIODO, o sea FN$PERIODO nos da el período de tiempo que en cada instante estamos). Dos modos de resolver lo mismo. Dado que el direccionamiento indirecto sólo se puedo hacer con parámetros, no podemos utilizar el Savevalue PERIODO ni la Función PERIODO para realizar el direccionamiento indirecto, sino que debemos asignar el valor del período a un parámetro. Luego utilizamos ese parámetro para hacer el direccionamiento indirecto, eligiendo de esta manera la función que nos devuelve el rótulo a bifurcar. -1 - Funciones – TEST con operador de relación – Matrices – Generar Transacciones de una familia Vamos a hacer una generación de transacciones en forma determinística para ver si la bifurcación de las transacciones en el TRANSFER ,FN*4 es la que nosotros queremos (ver para creer) O sea, generamos 150 clientes por hora mediante un GENERATE GENERATE ASSIGN TRANSFER 24 4,FN$PERIODO ,FN*4 24 (3600/24=150) generación de clientes (determinística), λ=150 por hora el parámetro 4 recibe el período se bifurca al rótulo que devuelve la función cuyo número es el número de período Para contar utilizaremos un objeto nuevo: la MATRIZ de SAVEVALUES. Definiremos una matriz llamada GUARDO con tres filas y cuatro columnas –dado que tenemos tres destinos y cuatro períodos de tiempo- para contar la cantidad de transacciones que a cada rótulo y en cada período de tiempo van: GUARDO MATRIX ,3,4 SINTAXIS del bloque MATRIX: identificador MATRIX ,cant_filas,cant_columnas Se saltea el primer operando porque se utilizaba para pedir Half Word para cada elemento de la matriz y así ahorrar memoria (Half Word ocupaba dos bytes por elemento mientras que Full Word ocupaba cuatro bytes) Vamos a contabilizar en la fila 1 la cantidad de transacciones que bifurcan al rótulo BAR, en la fila 2 la cantidad de transacciones que bifurcan al rótulo OFICINA y en la fila 3 la cantidad de transacciones que bifurcan al rótulo SEVA. Vamos a hacer que la columna donde contabilizamos la cantidad dependa del valor que tenga el período en que se registra la bifurcación (período 1 en la columna 1, período 2 en la columna 2, etc) O sea, se contabiliza cada vez que una transacción va a cada uno de los rótulos (es el viejo I=I+1 que, para contar, utilizamos en los lenguajes de programación tradicionales). SINTAXIS para contar (sumar 1) MSAVEVALUE nombre+,fila,columna,1 MSAVEVALUE A,B,C,D MSAVEVALUE A+,B,C,D MSAVEVALUE A-,B,C,D A: identificador de matriz B: fila de la matriz C: columna de la matriz D: valor a asignar, sumar ó restar, respectivamente. Quedando entonces: BAR OFICINA SEVA MSAVEVALUE GUARDO+,1,X$PERIODO,1 TERMINATE MSAVEVALUE GUARDO+,2,X$PERIODO,1 TERMINATE MSAVEVALUE GUARDO+,3,X$PERIODO,1 TERMINATE NUESTRO MODELO COMPLETO ES EL SIGUIENTE: GUARDO MATRIX ,3,4 PERIODO FUNCTION AC1,D4 7200,1/14400,2/21600,3/28800,4 1 FUNCTION RN4,D3 .35,BAR/.85,OFICINA/1,SEVA 2 FUNCTION RN3,D3 .15,BAR/.90,OFICINA/1,SEVA 3 FUNCTION RN5,D3 .55,BAR/.95,OFICINA/1,SEVA 4 FUNCTION RN6,D3 .10,BAR/.80,OFICINA/1,SEVA GENERATE 3600 TERMINATE 1 GENERATE 24 ASSIGN 4,FN$PERIODO TRANSFER ,FN*4 Al terminar la simulación, haciendo Clic en Entidades, Clic en Matriz de Savevalues se llega a: BAR OFICINA SEVA MSAVEVALUE GUARDO+,1,*4,1 TERMINATE MSAVEVALUE GUARDO+,2,*4,1 TERMINATE MSAVEVALUE GUARDO+,3,*4,1 TERMINATE Si iluminamos lo que está en negrita en el modelo anterior, lo copiamos con Ctrl-C y, en el SNAKE, abrimos un modelo nuevo, lo pegamos (Ctrl-V), lo podemos simular con START 8: Como resultado de esta simulación, obtendremos los siguientes resultados: -2 - Funciones – TEST con operador de relación – Matrices – Generar Transacciones de una familia Bifurcaciones que realizó el GPSS: 8 a 10 10 a 12 BAR 93 43 OFICINA 158 231 SE VA 48 26 299 300 12 a 14 168 118 14 300 Calculamos los porcentajes generados en el cuadro anterior: 8 a 10 10 a 12 12 a 14 BAR 31,10% 14,33% 56,00% OFICINA 52,84% 77,00% 39,33% SE VA 16,05% 8,67% 4,67% Recordamos el Enunciado: 8 a 10 BAR 35,00% OFICINA 50,00% SE VA 15,00% 10 a 12 15,00% 75,00% 10,00% 12 a 14 55,00% 40,00% 5,00% 14 a 16 28 210 62 300 14 a 16 9,33% 70,00% 20,67% 14 a 16 10,00% 70,00% 20,00% Las funciones utilizadas en GPSS: PERIODO FUNCTION AC1,D4 7200,1/14400,2/21600,3/28800,4 1 FUNCTION RN4,D3 .35,BAR/.85,OFICINA/1,SEVA 2 FUNCTION RN3,D3 .15,BAR/.90,OFICINA/1,SEVA 3 FUNCTION RN5,D3 .55,BAR/.95,OFICINA/1,SEVA 4 FUNCTION RN6,D3 .10,BAR/.80,OFICINA/1,SEVA Se realiza el TRANSFER a la función cuyo número es el número de período Se consideró el período 1 el que va de 8 a 10, el período 2 el que va de 10 a 12, el período 3 el que va de 12 a 14 y el período 4 el que va de 14 a 16 Se contabilizó en una matriz de SAVEVALUE donde: La fila 1 corresponde a la cantidad que fue al BAR La fila 2 corresponde a los que fueron a la OFICINA La fila 3 corresponde a los que se fueron (rótulo SEVA) La columna lo da el número de período. Es decir, en el ejercicio anterior, se elige la función de acuerdo al período de tiempo en que nos encontramos (hay 4 períodos) y esa función, a su vez, es función del azar con una distribución de probabilidad distinta para cada período. Una solución más comprensible para el alumno: Dado que el direccionamiento indirecto que permite el GPSS no es lo que el alumno acostumbra a usar, vamos a resolverlo definiendo una función intermedia tipo E (función de atributos). O sea, vemos otra forma de resolver el ejercicio anterior: GUARDO MATRIX ,3,4 PERIODO FUNCTION AC1,D4 7200,1/14400,2/21600,3/28800,4 BIFUR FUNCTION P4,E4 1,FN1/2,FN2/3,FN3/4,FN4 1 FUNCTION RN4,D3 .35,BAR/.85,OFICINA/1,SEVA 2 FUNCTION RN3,D3 .15,BAR/.90,OFICINA/1,SEVA -3- Funciones – TEST con operador de relación – Matrices – Generar Transacciones de una familia 3 FUNCTION RN5,D3 .55,BAR/.95,OFICINA/1,SEVA 4 FUNCTION RN6,D3 .10,BAR/.80,OFICINA/1,SEVA GENERATE 3600 TERMINATE 1 GENERATE 24 ASSIGN 4,FN$PERIODO TRANSFER ,FN$BIFUR BAR MSAVEVALUE GUARDO+,1,*4,1 TERMINATE OFICINA MSAVEVALUE GUARDO+,2,*4,1 TERMINATE SEVA MSAVEVALUE GUARDO+,3,*4,1 TERMINATE Con el fin de fijar los conocimientos, vamos a plantear y resolver un segundo ejemplo, muy similar al anterior. En este nuevo ejemplo, tenemos el caso en que hay cuatro tipos de cliente, los cuales en determinado lugar bifurcan: al BAR, a INFORMES y a CAJA. Los porcentajes con que bifurcan a cada rótulo son función del tipo de cliente al que pertenece la transacción. El relevamiento nos ha dado que los porcentajes con que bifurca cada tipo de cliente y la distribución de los tipos de cliente, son: Enunciado (bifurcación función del tipo de cliente con % distintos para cada tipo de cliente): BAR INFORMES CAJAS TOTAL TIPO DE CLIENTE 1 2 3 4 50% 15% 5% 30% 5% 30% 30% 35% 20% 50% 90% 40% 100% 100% 100% 100% Modelo en GPSS: Tipo Probabilidad 1 30% 2 40% 3 20% 4 10% Si hacemos Clic en Entidades, GUARDO MATRIX ,3,4 Clic en Matrix Savevalues obtenemos: TIPO FUNCTION RN8,D4 .3,1/.7,2/.9,3/1.,4 1 FUNCTION RN2,D3 .5,BAR/.8,INFORMES/1,CAJAS Haciendo clic en el botón “Exportar los datos a 2 FUNCTION RN3,D3 .15,BAR/.5,INFORMES/1,CAJAS 3 FUNCTION RN4,D3 .05,BAR/.10,INFORMES/1,CAJAS Excel”: 4 FUNCTION RN5,D3 .3,BAR/.6,INFORMES/1,CAJAS Conseguimos que los datos aparezcan en Excel: GENERATE 24 ASSIGN TIPO,FN$TIPO TRANSFER ,FN*TIPO ;bifurca a función cuyo número es tipo de cliente BAR MSAVEVALUE GUARDO+,1,P$TIPO,1 TERMINATE 1 INFORMES MSAVEVALUE GUARDO+,2,P$TIPO,1 TERMINATE 1 CAJAS MSAVEVALUE GUARDO+,3,P$TIPO,1 TERMINATE 1 BAR INFORMES CAJAS TOTAL TIPO DE CLIENTE 1 2 3 1510 571 106 855 1438 79 612 2065 1847 2977 4074 2032 4 277 280 360 917 -4- Funciones – TEST con operador de relación – Matrices – Generar Transacciones de una familia Los valores anteriores equivalen a los siguientes %: Los comparamos con el enunciado TIPO DE CLIENTE TIPO DE CLIENTE 1 2 3 4 1 2 3 4 BAR 50,72% 14,02% 5,22% 30,21% BAR 50% 15% 5% 30% INFORMES 28,72% 35,30% 3,89% 30,53% INFORMES 30% 35% 5% 30% CAJAS 20,56% 50,69% 90,90% 39,26% CAJAS 20% 50% 90% 40% TOTAL TOTAL 100% 100% 100% 100% 100% 100% 100% 100% Nuevamente hemos construido un modelo para comprobar si realmente, para cada tipo de cliente, el GPSS utilizó las distribuciones de probabilidad definidas por nosotros. Podemos llegar a decir que existe una concordancia entre los realmente generados y los que nosotros quisimos generar. Una solución más comprensible para el alumno: Sabemos que esta forma de direccionamiento indirecto que permite el GPSS no es lo que el alumno acostumbra a usar. Por tanto, vamos a resolverlo definiendo una función intermedia que vincula el tipo de cliente con la función que se debe utilizar (una función de atributos, tipo E) O sea, vemos otra forma de resolver el ejercicio anterior: GUARDO MATRIX ,3,4 TIPO FUNCTION RN8,D4 .3,1/.7,2/.9,3/1.,4 1 FUNCTION RN2,D3 .5,BAR/.8,INFORMES/1,CAJAS 2 FUNCTION RN3,D3 .15,BAR/.5,INFORMES/1,CAJAS 3 FUNCTION RN4,D3 .05,BAR/.10,INFORMES/1,CAJAS 4 FUNCTION RN5,D3 .3,BAR/.6,INFORMES/1,CAJAS BIF FUNCTION P$TIPO,E4 1,FN1/2,FN2/3,FN3/4,FN4 GENERATE 24 ASSIGN TIPO,FN$TIPO TRANSFER ,FN$BIF BAR MSAVEVALUE GUARDO+,1,P$TIPO,1 TERMINATE 1 INFORMES MSAVEVALUE GUARDO+,2,P$TIPO,1 TERMINATE 1 CAJAS MSAVEVALUE GUARDO+,3,P$TIPO,1 TERMINATE 1 El modelo de la izquierda es idéntico al original que transcribimos a continuación: GUARDO MATRIX ,3,4 TIPO FUNCTION RN8,D4 .3,1/.7,2/.9,3/1.,4 1 FUNCTION RN2,D3 .5,BAR/.8,INFORMES/1,CAJAS 2 FUNCTION RN3,D3 .15,BAR/.5,INFORMES/1,CAJAS 3 FUNCTION RN4,D3 .05,BAR/.10,INFORMES/1,CAJAS 4 FUNCTION RN5,D3 .3,BAR/.6,INFORMES/1,CAJAS GENERATE 24 ASSIGN TIPO,FN$TIPO TRANSFER ,FN*TIPO BAR MSAVEVALUE GUARDO+,1,P$TIPO,1 TERMINATE 1 INFORMES MSAVEVALUE GUARDO+,2,P$TIPO,1 TERMINATE 1 CAJAS MSAVEVALUE GUARDO+,3,P$TIPO,1 TERMINATE 1 En negrita está lo que cambiamos/agregamos entre una versión y otra. Mediante esta repetición de ejemplos similares entre sí pretendemos que el alumno tome confianza respecto a la validez que tienen los modelos construidos en GPSS (la distribución de probabilidad que quisimos representar tiene un gran parecido con los resultados de la simulación). PROPONEMOS UN EJEMPLO PARA QUE LO PIENSE EL ALUMNO, CONSTRUYA EL MODELO Y LO SIMULE (en cursiva hay “help” para el alumno) Se quiere simular la producción de productos en cuatro líneas de producción, que comprende tres etapas que debe recorrer cada producto para ser terminado. Se reciben productos cada 5±2 segundos que luego de tenerlos durante 120±30 segundos en observación se le asigna una línea al azar entre las cuatro líneas existentes –un 2% es descartado y sacado del sistemaElegida la línea el producto debe pasar por la etapa 1, la etapa 2 y la etapa 3 del proceso. Se puede procesar un único producto por etapa y línea. (Necesito una FACILITY por etapa y línea, podríamos pensar en tener la FACILITY 41 que representa línea 4, etapa 1; la FACILITY 13 que representa la línea 1, etapa 3; la FACILITY 32 que representa la línea 3, etapa 2; la FACILITY 23 que representa la línea 2, etapa 3, la FACILITY 12 que representa la línea 1, etapa 2, etc) -5- Funciones – TEST con operador de relación – Matrices – Generar Transacciones de una familia El tiempo que se demora es función de la línea y la etapa en que se encuentra –ver cuadro siguiente–. El tiempo promedio, en segundos, que demora en cada línea y etapa está dado por el siguiente cuadro: LINEA 1 2 3 4 Etapa 1 20 10 8 15 2 15 8 6 10 3 25 15 12 18 Podríamos definir cuatro funciones, una función por línea, con tres puntos cada función (un punto por cada etapa) para colocar en el ADVANCE que representa la tarea respectiva. Suponer que el tiempo no es determinístico sino que existe un ± 2 segundos que puede alargar o achicar la duración de cada proceso. Luego de pasar las tres etapas el producto está terminado. Tabular el tiempo que cada producto estuvo en el sistema -desde que llegó hasta que fue terminado- en cuatro tablas distintas –una por línea de producciónSimular hasta que haya 10000 productos terminados. II) TEST: "bloque IF del GPSS". La sintaxis es la siguiente: TEST operador de relación A,B[,C] Operador de relación: L significa < (menor) LE significa <= (menor o igual) G significa > (mayor) GE significa >= (mayor o igual) E significa =(igual) NE significa ≠ (Distinto) A es un SNA cualquiera, B es otro SNA cualquiera, C es el rótulo al que bifurca si la proposición: “A operador de relación B” es falsa Si no se coloca el rótulo C la transacción queda bloqueada si la proposición es falsa (este bloqueo se mantiene hasta que la proposición lógica sea verdadera). Es como si el bloque TEST dejara pasar a las transacciones “que dicen la verdad”, es decir que hacen la proposición lógica verdadera. Si la proposición lógica es falsa la transacción bifurca al rótulo “C” Si no existe rótulo alternativo (operando C) y la proposición lógica es falsa, la transacción queda bloqueada hasta que la proposición lógica sea verdadera. Ejemplo de uso del TEST (evita el error de restar de un STORAGE más unidades que las disponibles): .... TEST LE P$QUIERO,S$STOCK LEAVE STOCK,P$QUIERO .... En el ejemplo anterior suponemos que la transacción tiene almacenada en el parámetro cuyo nombre es QUIERO, la cantidad de piezas del STOCK que desea, y que la transacción queda esperando hasta que haya piezas en STOCK –no se va hasta que haya-. La cantidad de piezas que se fabrican y/o se compran se almacenan en el STORAGE STOCK Por cada compra o fabricación de piezas se ejecuta: ENTER STOCK,cantidad_de_piezas. Es decir, se representa y registra la producción de esa fábrica, mediante el siguiente subsistema: .... GENERATE ASSIGN ENTER TERMINATE producción PROD,FN$PRODUCE STOCK,P$PROD ....la transacción que simula la producción “muere” pero la acumulación en el STOCK ya está realizada. Si quisiéramos agregar una eventual compra de piezas a otro productor para reforzar nuestro STOCK la representaríamos con: GENERATE compras .... ASSIGN ENTER TERMINATE COMPR,FN$COMPRA STOCK,P$COMPR -6- Funciones – TEST con operador de relación – Matrices – Generar Transacciones de una familia Acabamos de simular en forma concurrente que tengo una producción de piezas y a la vez tengo una compra de piezas. Todo va a parar al mismo STOCK ES MUY IMPORTANTE ENTENDER QUE: a) EN EL SUBSISTEMA de COMPRAS ó PRODUCCIÓN: Se coloca el ENTER b) En el subsistema de ventas/entrega/consumo de producto: Se coloca el LEAVE El TEST está puesto para no cometer el error de querer entregar mercadería que no tengo en STOCK. Si se intenta desocupar más unidades que las existentes en un STORAGE la simulación termina con el mensaje de error que dice: Si el cliente aguarda a que traigan el producto debemos representar esa circunstancia colocando el TEST sin rótulo alternativo. Si el cliente se va cuando no hay producto, representamos esa circunstancia colocando el TEST con rótulo alternativo (rótulo del TERMINATE que simula que el cliente se va sin comprar). Como ejemplo final, supondremos que se trata de un caso "mixto": un % de los clientes se queda a esperar que haya STOCK, el resto de los clientes se va sin esperar. Por ejemplo, supongamos que el 30% se va si no hay producto en existencia (Storage STOCK), el 70% restante se queda a esperar que repongan. El caso propuesto lo representaremos mediante: SUBSISTEMA Compradores. Existe un 30% que se retira si no hay productos en existencia, el 70% restante se queda esperando en un TEST sin rótulo alternativo: .... TEST LE P$QUIERO,S$STOCK,VEO TRANSFER ,LLEVO VEO TRANSFER .3,,SEVA TEST LE P$QUIERO,S$STOCK LLEVO LEAVE STOCK,P$QUIERO SEVA TERMINATE Para el ejemplo propuesto, el subsistema de producción/compras queda inalterable (por enunciado hemos supuesto que lo único que cambió fue la conducta de los clientes que van a comprar). III) Un ejemplo interesante: Cola única, elige FACILITY desocupada (una de 4 FACILITIES) UNICO STORAGE 4 GENERATE clientes ... QUEUE UNICO ENTER UNICO DEPART UNICO SELECT NU 4,11,14 SEIZE *4 ADVANCE tiempo de atención RELEASE *4 LEAVE UNICO ... Dado que el ENTER UNICO está simulando el ingreso a un STORAGE de capacidad 4, a lo sumo habrá cuatro transacciones haciendo el SELECT por lo que no es necesario poner rótulo alternativo porque nunca se da el caso de que no encuentre ninguna FACILITY desocupada. Si existe un gerente que con prioridad 100 quiere ser atendido por alguno de los empleados: GENERATE veces que viene el gerente PRIORITY 100 ... QUEUE UNICO ENTER UNICO DEPART UNICO SELECT NU 4,11,14 SEIZE *4 ADVANCE tiempo de atención -7- Funciones – TEST con operador de relación – Matrices – Generar Transacciones de una familia RELEASE *4 LEAVE UNICO ... Si existe un proveedor que va al empleado 12 quien es el único que lo puede atender: GENERATE PRIORITY ... QUEUE ENTER DEPART SEIZE ADVANCE RELEASE LEAVE ... proveedor 50 UNICO UNICO UNICO 12 tiempo de atención 12 UNICO Mediante esta manera de simular tenemos el defecto de que el proveedor realiza el ENTER UNICO cuando se produce un lugar libre y puede hacer cola frente al empleado 12 mientras hay otro empleado desocupado (la situación se regulariza al desocuparse el empleado 12). Para solucionarlo, es preferible hacer al revés: que el proveedor tome al Empleado 12, y una vez que lo tomó entre al Storage UNICO (si puede tomar la Facility 12 es porque alguien la dejó, y al hacerlo también liberó un lugar en el Storage). GENERATE proveedor PRIORITY 50 ... QUEUE UNICO SEIZE 12 ENTER UNICO DEPART UNICO ADVANCE tiempo de atención LEAVE UNICO RELEASE 12 ... IV) ¿Cómo hacemos para colocar en el parámetro 5 de una transacción la cantidad de gente que hay en la cola con mayor cantidad de gente entre las colas 11 y 19?: SELECT MAX 4,11,19,,Q ASSIGN 5,Q*4 En el parámetro 4 le asignamos el número de cola con mayor cantidad de gente (si hay empate entre dos o más colas, tendremos allí el número más chico de las colas que empataron) En el parámetro 5 vamos a tener la cantidad de gente que hay en esa cola, tal como nos pide el “minienunciado” de este punto. V) Ver Clase nº 5 en http://www.fi.uba.ar/materias/7526/apuntes.html repasamos los conceptos fundamentales, seguido por 3 simulaciones de un modelo donde se refuerzan los recursos procurando mejorar la situación (se sugiere seguir mejorando). Simular que un supervisor, cada 15 minutos (comenzando 10 minutos después del inicio de la simulación) mira cuántas personas tiene la cola más larga, y si hay más de 5 personas (y menos de 8 cajas) se incrementa en 1 el número de cajas habilitadas, mientras que si hay menos de 3 personas (y más de 2 cajas) se decrementa en 1 el número de cajas habilitadas. El código para resolver esto sería: GENERATE 900,,600 En la citada referencia la elección de la caja es SELECT MAX 1,11,X$CAJAS,,Q inteligente (desocupada o cola mínima): ASSIGN 2,Q*1 TEST G *2,5,VERBAJO TEST L X$CAJAS,18,BYE SAVEVALUE CAJAS+,1 BYE TERMINATE VERBAJO TEST L *2,3,BYE TEST G X$CAJAS,12,BYE SAVEVALUE CAJAS-,1 TERMINATE Observar que la numeración de las FACILITIES que representa a las cajas comienza en 11. -8- VI) Funciones – TEST con operador de relación – Matrices – Generar Transacciones de una familia FAMILIAS DE TRANSACCIONES, bloques SPLIT/ASSEMBLE/GATHER: Introducción: Existen situaciones en las que una transacción se subdivide en varias transacciones y luego vuelve a convertirse en una sola. Por ejemplo, una orden de fabricación de un auto genera la orden de fabricación de un chasis, de un motor y de una carrocería. Cuando las tres partes del auto están listas se pueden ensamblar y da como resultado la fabricación del auto de la citada orden de fabricación. En el lenguaje GPSS están definidos el bloque SPLIT (para generar copias de una transacción original) y el bloque ASSEMBLE (las partes se fusionan, dando origen a una única transacción de cada familia). Necesitamos conocer que, cada transacción tiene un "POINTER" (puntero) que apunta al primer miembro de la familia, que, al nacer cada transacción, apunta a sí misma (las transacciones que genera el GENERATE pertenecen a familias independientes entre sí). El bloque SPLIT genera transacciones idénticas a la transacción original, que se enlazan entre sí debido a que pertenecen a una misma familia (se establece la relación a través de este puntero). Por ejemplo: Si la transacción número 84 ejecuta un SPLIT 3 se generan tres transacciones idénticas a la original que pertenecen a una misma familia. Supongamos que al ejecutar el SPLIT 3, se generan la transacción 24, la 90 y la 91, con lo que se arma un encadenamiento simple entre la transacción original y las transacciones “clones” de la transacción original: La transacción original (la 84) apunta a la primera transacción generada (la 24), La primera (la 24) apunta a la segunda (la 90), La segunda (la 90) apunta a la tercera (la 91) y La tercera (la 91) apunta a la original (la 84). El GPSS tiene identificadas a las cuatro transacciones como pertenecientes a una misma familia, pero desconoce cuál era la transacción original. SINTAXIS del bloque SPLIT: SPLIT A,B[,C] A es el número de copias B es el bloque al que bifurcan las copias C identificador del parámetro donde se numeran las transacciones Nota: la transacción original continúa su camino (o sea, va al bloque siguiente al SPLIT). ¿Existe alguna manera de identificar a las transacciones generadas en el SPLIT? (original, primera copia, segunda copia, etc.) Sí, utilizando el operando C del bloque SPLIT que es el parámetro donde se numeran las transacciones. EJEMPLO: SPLIT 3,COPIAS,8 Se generan tres "clones" de la transacción original utilizándose el parámetro 8 para numerar las transacciones. ¡Son tres transacciones exactamente iguales a la original! (mismo M1, mismo PR, mismos parámetros) A la original le suma 1 al parámetro 8 (si el parámetro 8 no existía se instancia con el valor cero, por lo que, para este caso, la original pasa a tener un 1 en el parámetro 8). A la primera copia le suma 2 al parámetro 8 (para el supuesto anterior pasa a tener un 2 en el parámetro 8). A la segunda copia le suma 3 al parámetro 8 (para el supuesto anterior pasa a tener un 3 en el parámetro 8). A la tercera copia le suma 4 al parámetro 8 (para el supuesto anterior pasa a tener un 4 en el parámetro 8). De esta manera hay cuatro miembros de la familia (la original y las tres copias) y cada una de ellas está identificada por el valor del parámetro 8 (tiene un valor distinto y correlativo en el citado parámetro). Si se define una función cuya variable independiente sea el parámetro 8, y esta función devuelve un rótulo, se puede hacer que la original y cada una de las copias vaya a un lugar distinto. Dicha bifurcación se realizaría mediante un TRANSFER ,FN$nombfunc (nombfunc FUNCTION f(P8)) ¿Es posible reunir al grupo y hacer que salga una única transacción que represente al grupo? Sí, mediante el bloque ASSEMBLE: ASSEMBLE A -9- Funciones – TEST con operador de relación – Matrices – Generar Transacciones de una familia Siendo A la cantidad de transacciones que se reúnen. Deja pasar a una única transacción luego de reunidas las A transacciones (pasa la primera transacción que ejecuta el ASSEMBLE de cada familia, las A-1 transacciones restantes son destruidas). El GPSS ejecuta el ASSEMBLE en forma independiente para cada familia sin que éstas se mezclen. ¿Si en un modelo no se ejecutó ningún SPLIT, tiene sentido poner un ASSEMBLE 2? ¿qué pasaría? Un ASSEMBLE 2 haría que todas las transacciones que llegan al ASSEMBLE queden retenidas esperando una transacción hermana que no tienen -esperarán hasta el infinito a ese hermano que no tienen- (alguien que es "hijo único" es condenado a prisión perpetua si le exigen que venga un hermano a sacarlo de donde está detenido). ¿Es posible reunir un grupo de transacciones de la misma familia dejando pasar a todos una vez reunida la cantidad especificada, sin destruir ninguna transacción? Sí, mediante el bloque GATHER: GATHER A Reúne a A transacciones de una misma familia, una vez reunidas las A transacciones de una familia, las deja pasar a todas en el mismo instante de tiempo. EJEMPLO DE APLICACIÓN (SPLIT, con su posterior ASSEMBLE, con un GATHER intermedio): Supongamos que queremos simular lo que sucede con ómnibus de excursión que aparecen cada 20±10 minutos y traen 20±10 pasajeros cada bus, y que los turistas recorren una zona de parques (durante 1800±600 segundos), luego de lo cual se esperan a la entrada de un museo. Una vez que está el grupo reunido, entran al museo (entran de a una persona por vez demorando 4±2 segundos en hacerlo). Las personas pasean por el museo durante 2700±900 segundos, luego de lo cual salen del museo, demorando otros 600±300 segundos en el parque hasta llegar al bus que los aguarda. Cuando todo el conjunto está reunido el bus parte demorando 1800±900 segundos en llevarlos al hotel, fin de nuestro estudio. Simular 200 buses de excursión que hicieron el recorrido completo que aquí se describe. CANPER CANTI PASEO BUSCA VARIABLE VARIABLE GENERATE ASSIGN SPLIT TRANSFER ENTER ADVANCE GATHER ENTER SEIZE DEPART ADVANCE LEAVE ADVANCE ... ADVANCE LEAVE ASSEMBLE ADVANCE TERMINATE 10+RN3@21 ;(20±10 personas) P$CANTI+1 1200,600,,200 ;Hago generar los 200 buses del enunciado CANTI,V$CANPER P$CANTI,PASEO ;es más exacto hacer que bajen de a uno utilizando bloque LOOP combinado con SPLIT 1,PASEO pero, como ejemplo inicial, esto es suficiente. ,BUSCA PARQ 1800,600 P$CANTI PUERTA PUERTA PUERTA 4,2 PUERTA 2700,900 ;aquí se podría simular una puerta que deja pasar de a uno 600,300 PARQ V$CANTI 1800,900 1 Con un START 200 se simularía lo pedido. ¿Por qué el ASSEMBLE utiliza una cantidad que es uno más que los miembros del grupo? El bus lo hemos mantenido y lo hemos mandado a buscar los pasajeros -rótulo BUSCA- 10 - Funciones – TEST con operador de relación – Matrices – Generar Transacciones de una familia Tenemos además los P$CANTI pasajeros por lo que el grupo está compuesto por P$CANTI+1 transacciones. De allí la necesidad de ensamblar P$CANTI+1 transacciones (llegan las P$CANTI personas más el bus). ¿Cómo sería el modelo construido mediante el lenguaje GPSS si queremos simular que el grupo se junta en un lugar, luego de lo cual el grupo se dirige al lugar dónde está el micro esperando? CANPER PARQ PUERTA VARIABLE STORAGE STORAGE GENERATE ASSIGN SPLIT 10+RN3@21 ;(20±10 personas) 30000 2 1200,600,,200 ; Hago generar los 200 buses del enunciado CANTI,V$CANPER P$CANTI,PASEO ;sería más exacto decir que bajan de a uno utilizando bloque LOOP combinado con SPLIT 1,PASEO ;por aquí pasa el bus (se debe simular lo que hace el bus antes de buscar a los turistas) TRANSFER ,BUSCA ENTER PARQ ADVANCE 1800,600 GATHER P$CANTI ;aquí se junta el grupo, para entrar cuando están todos QUEUE PUERTA ENTER PUERTA ;entran de a dos por vez DEPART PUERTA ADVANCE 4,2 ;demora 4±2 en entrar LEAVE PUERTA ADVANCE 2700,900 ;aquí pasean por el museo ADVANCE 600,300 ;aquí se representa el paseo luego de salir del museo. ASSEMBLE P$CANTI ;aquí se reúne el grupo (sale una única transacción) ADVANCE 180,60 ;aquí el grupo se dirige al bus LEAVE PARQ,P$CANTI ;aquí el grupo se retira del parque BUSCA ASSEMBLE 2 ;aquí se reúne el grupo con el bus ADVANCE 1800,900 ;aquí transita el bus con los turistas de regreso al hotel TERMINATE 1 Con un START 200 se simulan los 200 buses pedidos por el enunciado. PASEO ¿Por qué, en el rótulo BUSCA, se coloca ASSEMBLE 2? ¿para cada grupo de turistas cuáles transacciones arriban a ese ASSEMBLE? A ese ASSEMBLE 2 llega el grupo de turistas por un lado (como una única transacción) y por otro lado llega el bus. El ASSEMBLE 2 reúne a los dos y hace salir a una única transacción que representa al BUS con los turistas. VII) Generando muchas transacciones, todas de la misma familia: A la izquierda de la siguiente tabla tenemos el GENERATE tradicional que genera una transacción cada 60±30 segundos, a la derecha también se genera una transacción cada 60±30 segundos pero mediante esta generación todas las transacciones son hermanas entre sí (hay una única “madre”) Todas transacciones independientes GENERATE 60,30 ENTRA Todas transacciones “hermanas” GENERATE ,,,1 OTRA ADVANCE 60,30 SPLIT 1,ENTRA TRANSFER ,OTRA ENTRA MARK Recordar que el GENERATE genera “cabezas de familia”, mientras que el SPLIT amplía la familia de la transacción que ejecuta el SPLIT (le crea una transacción “hermana”). En la generación de transacciones en el subsistema de la derecha, tenemos un problema porque la transacción “madre” nació en el instante inicial, por lo tanto, todas las copias tendrán su M1, en lugar de tener su M1 inicializado en cero al momento de ser generadas por el SPLIT. Para solucionar este problema le hacemos ejecutar, a las transacciones generadas en el SPLIT, el bloque MARK al bifurcar al rótulo ENTRA. De esta manera hacemos que las transacciones, al bifurcar al rótulo ENTRA inicialicen su M1 en cero (evitamos de esta manera que las transacciones “copia” continúen teniendo el M1 de la transacción “madre”). - 11 - Funciones – TEST con operador de relación – Matrices – Generar Transacciones de una familia VIII) Buscando el máximo de una clase de SNA: En la página de los SNA (http://www.fi.uba.ar/materias/7526/docs/snas.pdf) tenemos definidas las clases de SNA (es lo que aparece en la tabla sin la letra i que es el identificador del objeto): EJEMPLO: Para obtener cuál es la FACILITY que más trabajó de un conjunto de FACILITIES, pediría el máximo FR de ese conjunto de FACILITIES. O sea, una transacción puede obtener la “Facility trabajadora” ejecutando el siguiente bloque: SELECT MAX 4,11,18,,FR De esta manera, obtiene la FACILITY que más trabajó entre la FACILITY 11 y la FACILITY 18. El GPSS colocará el número de esa FACILITY trabajadora en el parámetro 4 de la transacción que ejecuta el SELECT MAX (es la más trabajadora al instante en que se ejecuta el SELECT MAX) La sintaxis del SELECT MAX es la siguiente: SELECT MAX A,B,C,,E A: Número o nombre del parámetro donde el GPSS coloca el número de recurso que es máximo. B: Desde cuál número de recurso se busca el máximo: C: Hasta cuál número de recurso se busca el máximo: E: Clase de recurso para el cual se busca el máximo: El parámetro identificado por el operando A recibirá un número x tal que B≤x≤C Resumiendo, hemos visto: FUNCIONES. Verificando su validez utilizando matrices MATRIX MSAVEVALUE TEST operador de relación A,B,C 11/abril/12 SPLIT ASSEMBLE GATHER Generar transacciones de una misma familia. SELECT MAX A,B,C,,E - 12 -