Cola única con cuatro empleados atendiendo En este ejemplo, supondremos que hay cuatro empleados que atienden clientes. Los empleados están representados, en el modelo, por cuatro facilities y cuatro transacciones. Atienden a clientes, que esperan ser llamados linkeados a una cadena ESPERA (mientras están en dicha cadena están asociadas al grupo de transacciones ESPERA, para permitir que el empleado le copie su número). Los empleados están numerados de 1 a 4 (en el parámetro 3). Cada empleado es una transacción que se encarga de llamar clientes, sacándolos de la cadena ESPERA donde están linkeados. El empleado, previo a llamar a un cliente, le copia el número de empleado al cliente (el *3 del empleado lo copia en el *3 del cliente), para luego sacarlo de la cadena y hacer que ese cliente use dicho número de empleado para tomarlo como FACILITY (es decir, simular que dicho empleado lo está atendiendo). El cliente, encadenado a la cadena ESPERA, puede llegar a irse, sin ser atendido, si ve colmada su paciencia, ya que hay una transacción "hermanita" del cliente, que tiene el número de cliente en el *1, que espera el tiempo de paciencia del cliente luego de lo cual intenta llevarse al cliente por impaciencia (intenta llevarse a la transacción con el que tiene coincidencia en el valor del parámetro 1). La atención del cliente se representa en el subsistema cliente. El tiempo que demora el cliente puede ser f(tipo de cliente), como en el ejemplo, o incluso f(tipo de cliente, número de empleado que lo atiende). En el subsistema empleados, la transacción que representa al empleado aguarda que la FACILITY, que también representa al empleado, haya sido utilizada por el cliente (es decir, esté "not used"1). En este subsistema, podemos resumir la conducta de los empleados, como sigue: 1. El empleado llama a un cliente (antes le copia al cliente su número de empleado). 2. Espera que sea atendido (en el subsistema por donde transitan los clientes). 3. Si el empleado ha atendido más de dos horas sin hacer una pausa, la hace, tomándose un refrigerio. Esta consulta se realiza preguntando si MP5 supera las dos horas (MP5 mide el tiempo transcurrido desde que la transacción ejecutó el MARK 5). Si ese tiempo ha sido superado, el empleado toma el refrigerio, ejecutando luego el MARK 5, para reinicializar el MP5 en cero y así esperar otras dos horas antes de repetir la pausa. 4. En un FN$xxx de las veces procede a llamar a otro cliente. Es decir, pese a que puede haber gente esperando, existe una probabilidad que decida no llamar al cliente siguiente, definida mediante una función f(número de empleado) que representa la citada probabilidad de llamar a otra persona luego de haber atendido a la persona anterior (al ser menor que 1000, hay una probabilidad de que no llame al siguiente porque, simplemente, no quiere hacerlo). 5. Al llamar a un cliente puede ser que no haya nadie. Es decir, lo detecta porque no hay nadie a quien colocarle el número de empleado. En ese caso bifurca a un rótulo alternativo especificado como último operando del ALTER. En ese rótulo, al que bifurca el empleado representamos otra actividad que el empleado hace antes de volver a fijarse si hay gente esperando. Hay una diferencia entre este último caso (el empleado hace otra cosa con "la conciencia tranquila" porque no había nadie esperando) y el caso anterior en que decide hacer otra cosa, sin saber si hay gente esperando. Esta manera de representar la realidad nos permite, no sólo representar la impaciencia del cliente, sino también representar todas las acciones que el empleado realiza (a la izquierda vemos al subsistema clientes, a la derecha el subsistema empleados). Encabeza al subsistema empleados la función XXX que representa el tanto por mil de probabilidad de llamar al siguiente cliente. El empleado 1, en el 15% de las veces hace otra cosa antes de volver a llamar; el 4 en el 2% de los casos: GENERATE clientes ASSIGN 3,0 ASSIGN TIPO,FN$TIPO SAVEVALUE 1+,1 ASSIGN 1,X1 SPLIT 1,IMPA JOIN ESPERA QUEUE ESPERA LINK ESPERA,FIFO ATIE REMOVE ESPERA SEIZE *3 DEPART ESPERA ADVANCE tiempo f(P$TIPO) RELEASE *3 ... TERMINATE CHAU DEPART ESPERA TERMINATE IMPA ADVANCE tiempo de impaciencia UNLINK ESPERA,CHAU,1,1,P1 TERMINATE XXX FUNCTION *3,D4 1,850/2,950/3,900/4,980 El empleado 1 es el más "vago", el 4 el más "trabajador" GENERATE 900,,,4 (se generan 4 empleados) MARK 5 SAVEVALUE 3+,1 ASSIGN 3,X3 OTROAT ALTER ESPERA,1,3,P3,3,0,NOHAY UNLINK ESPERA,ATIE,1,3,P3 ADVANCE 1 puede ser reemplazado por BUFFER GATE NU *3 TEST G MP5,7200,SIGUE ADVANCE toma un refrigerio MARK 5 (reinicializa MP5 para tomar refrigerio en otras dos horas) SIGUE TRANSFER FN$XXX,,OTROAT ADVANCE hace otra cosa sin fijarse si hay gente esperando TRANSFER ,OTROAT NOHAY ADVANCE hace otra cosa porque no hay nadie TRANSFER ,OTROAT En el subsistema de la izquierda hemos representado a clientes que aguardan ser atendidos por los empleados representados por el subsistema de la derecha. Si se le colma la paciencia al cliente (ha pasado el tiempo límite de paciencia sin ser llamado por ningún empleado) deja de esperar, retirándose del sistema llevado por su propia impaciencia bifurcando al rótulo CHAU. 1 GATE NU *3 bloquea el paso a la transacción si la facility representada por el parámetro 3 está en uso (queda bloqueada hasta que dicha facility esté "sin usar"). -1- Al ser atendido, el cliente sale del grupo de los que están esperando (para no ser alcanzado por otro empleado que mediante el bloque ALTER prepara la llamada de otro cliente), toma al empleado que lo acaba de llamar, es atendido por él y libera al empleado para luego continuar su camino por el sistema en estudio. Los empleados comienzan a atender con intervalos regulares de 15 minutos (son cuatro). El primer empleado recibe el número 1 en su parámetro 3, el segundo empleado recibe el número 2, el tercero recibe el número 3, el cuarto recibe el número 4 en el citado parámetro 3. En forma más detallada, y a la vista del modelo construido utilizando el lenguaje GPSS, cada empleado repite el ciclo que se describe a continuación: 1. Al primer cliente que está esperando, le copia su número de empleado2 en el parámetro 3 del mismo. (si no hay nadie, hace otra cosa, tarea representada por el ADVANCE del rótulo NOHAY) 2. Llama a ese cliente (lo saca de la cadena y lo manda al rótulo ATIE) 3. Espera un segundo (para dar tiempo que el cliente tome al empleado que lo llamó)3 4. Aguarda que la facility que representa la propia actividad del empleado esté desocupada (es decir, espera que lo haya atendido). 5. El empleado pregunta si han pasado dos horas sin interrumpir su labor4. Si es así, se toma un refrigerio, reinicializa el parámetro cinco en cero para así volver a contar de nuevo las dos horas antes de tomar nuevamente un refrigerio. 6. El empleado procede a llamar a otro cliente en un FN$xxx de los casos. El valor de la función se divide por 1000 para calcular la probabilidad de llamar a un cliente. Dicha función depende de cuál empleado se trate que, tal como se comenta en el modelo, va desde un empleado 4 muy "trabajador" (2% de las veces no llama al siguiente) a un empleado 1 muy "vago" (15% de las veces no llama al siguiente). 7. La probabilidad restante, comentada en el párrafo anterior, es la que le hace hacer otra cosa sin fijarse si hay gente esperando, volviendo a llamar a otro cliente, recién cuando ha hecho eso otro. Es importante destacar que una transacción al hacerse miembro de un grupo de transacciones pierde su privacidad, es decir, sus parámetros pueden ser alterados, desde cualquier otro subsistema, por cualquier otra transacción. Se aprovecha esta circunstancia, haciendo que los empleados le copien el número de empleado al cliente que van a llamar (es decir, que van a sacar de la cadena ESPERA, cadena donde aguardan ser llamados). Al ser liberado, el cliente debe apresurarse a salir del grupo de transacciones ESPERA y así no ser "alcanzado" por otro empleado, quien antes de llamar, copia el número de empleado a la primera transacción (la más antigua), del grupo ESPERA. El cliente es numerado en forma correlativa en su parámetro 1. A cada cliente se le genera una transacción idéntica a sí misma (un "clon") mediante el bloque SPLIT 1,IMPA. Dicha transacción bifurca al rótulo IMPA donde aguarda el llamado "tiempo de impaciencia" luego de lo cual, si todavía no ha sido llamado, se retira. La transacción "clon" intenta sacar a la original de la cadena ESPERA5. El bloque ALTER actúa sobre una transacción miembro de un grupo, sin importar el lugar donde esté. Le cambia el valor de uno de sus parámetros (o de la prioridad) dejándola en el lugar donde está. Si no hay transacciones en el grupo, o ninguna cumple con la condición para ser alterada el bloque ALTER no realiza acción alguna. El bloque UNLINK actúa sobre una transacción que está en el bloque LINK respectivo. La saca de donde está (linkeado a la cadena donde se está haciendo el UNLINK) y la manda al rótulo que figura como operando B del citado UNLINK. Si no hay transacciones encadenadas o las que hay no cumplen la condición para ser liberadas el UNLINK no realiza acción alguna. 2 En ALTER ESPERA,1,3,P3,,,NOHAY, se intenta alterar en el grupo ESPERA de transacciones, siendo 1 la cantidad de transacciones que se intenta alterar, 3 el número de parámetro que se quiere alterar, P3 es el valor que se le quiere poner a dicho parámetro, siendo NOHAY el rótulo al que bifurca la transacción que intenta hacer el ALTER si no pudo alterar a una transacción en el grupo de transacciones ESPERA (los operandos quinto y sexto se utilizan para definir una condición que debe cumplir la transacción para ser alterada. Aquí en blanco, ya que en este caso no hay ninguna condición en especial). 3 Podríamos reemplazar el ADVANCE 1 por el bloque BUFFER (BUFFER detiene a la transacción que lo ejecuta, colocándola como última transacción a mover. Le da la oportunidad al cliente de hacer el SEIZE de la FACILITY, de manera que cuando ésta transacción reanuda su movimiento y ejecuta el GATE NU la encuentra usada por el cliente. Todo esto realizado sin que pase el tiempo) 4 Cada transacción ejecuta el bloque TEST GE MP5,7200,SIGUE donde compara el valor que tiene almacenado en su parámetro 5 (tiempo desde que ejecutó el bloque MARK 5) con 7200; si dicho valor (MP5) es mayor o igual (GE: greater equal) que 7200 atraviesa el bloque TEST como si éste no estuviera, caso contrario bifurca al rótulo SIGUE (si el bloque TEST no tuviera un tercer operando la transacción quedaría retenida hasta que la proposición lógica sea verdadera; o sea para este caso, hasta que MP5 sea >= 7200). 5 El bloque UNLINK ESPERA,CHAU,1,1,P1 intenta liberar una transacción de la cadena ESPERA, enviándola al rótulo CHAU, siempre y cuando esa transacción tenga el parámetro 1 (cuarto operando) igual al parámetro 1 de la transacción que hace el UNLINK. O sea, la transacción "clon" que ejecuta el UNLINK, sólo actúa sobre la transacción original, si es que continúa esperando ser atendida. -2-