Estoy tratando de resolver el siguiente ejercicio, pero en realidad no tengo idea de cómo comenzar a hacerlo. Encontré un código en mi libro que parece, pero es un ejercicio completamente diferente y no sé cómo relacionarlos entre sí. ¿Cómo puedo comenzar a simular llegadas y cómo sé cuándo están terminadas? Sé cómo almacenarlos y calcular a, b, c, d de acuerdo con eso. Pero no sé cómo realmente necesito simular la simulación de Monte Carlo. ¿Podría alguien ayudarme a comenzar? Sé que este no es un lugar donde sus preguntas son respondidas por usted, sino que solo se resuelven. Pero el problema es que no sé cómo empezar.
Una mesa de ayuda de soporte de TI representa un sistema de colas con cinco asistentes que reciben llamadas de los clientes. Las llamadas se realizan de acuerdo con un proceso de Poisson con la tasa promedio de una llamada cada 45 segundos. Los tiempos de servicio para los asistentes primero, segundo, tercero, cuarto y quinto son variables aleatorias exponenciales con parámetros λ1 = 0.1, λ2 = 0.2, λ3 = 0.3, λ4 = 0.4 y λ5 = 0.5 min − 1, respectivamente (el jth help desk assistant tiene λk = k / 10 min − 1). Además de los clientes que reciben asistencia, se puede poner en espera a otros diez clientes. En los momentos en que se alcanza esta capacidad, las nuevas personas que llaman reciben una señal de ocupado. Utilice los métodos de Monte Carlo para estimar las siguientes características de rendimiento:
(a) la fracción de clientes que reciben una señal de ocupado;
(b) el tiempo de respuesta esperado;
(c) el tiempo de espera promedio;
(d) la porción de clientes atendidos por cada asistente de mesa de ayuda;
EDITAR: lo que tengo hasta ahora es (no mucho):
pa = 1/45sec-1
jobs = rep(1,5); onHold = rep(1,10);
jobsIndex = 0;
onHoldIndex = 0;
u = runif(1)
for (i in 1:1000) {
if(u <= pa){ # new arrival
if(jobsIndex < 5) # assistant is free, #give job to assistant
jobsIndex++;
else #add to onHold array
onHoldIndex++;
}
}
fuente
Respuestas:
Este es uno de los tipos de simulación más instructivos y divertidos para realizar: crea agentes independientes en la computadora, los deja interactuar, realiza un seguimiento de lo que hacen y estudia lo que sucede. Es una forma maravillosa de aprender sobre sistemas complejos, especialmente (pero no limitado a) aquellos que no se pueden entender con un análisis puramente matemático.
La mejor manera de construir tales simulaciones es con un diseño de arriba hacia abajo.
En el nivel más alto, el código debería ser similar a
(Este y todos los ejemplos posteriores son código ejecutable
R
, no solo pseudocódigo). El bucle es una simulación dirigida por eventos :get.next.event()
encuentra cualquier "evento" de interés y le pasa una descripciónprocess
, que hace algo con él (incluido el registro de cualquier información al respecto). RegresaTRUE
mientras las cosas funcionen bien; Al identificar un error o el final de la simulación, regresaFALSE
y finaliza el ciclo.Si imaginamos una implementación física de esta cola, como personas que esperan una licencia de matrimonio en la ciudad de Nueva York o una licencia de conducir o un boleto de tren en casi cualquier lugar, pensamos en dos tipos de agentes: clientes y "asistentes" (o servidores) . Los clientes se anuncian apareciendo; los asistentes anuncian su disponibilidad encendiendo una luz o señal o abriendo una ventana. Estos son los dos tipos de eventos para procesar.
El entorno ideal para tal simulación es una verdadera orientación a objetos en la que los objetos son mutables : pueden cambiar de estado para responder de forma independiente a las cosas que los rodean.
R
es absolutamente terrible para esto (¡incluso Fortran sería mejor!). Sin embargo, aún podemos usarlo si tenemos cuidado. El truco consiste en mantener toda la información en un conjunto común de estructuras de datos a las que se puede acceder (y modificar) mediante muchos procedimientos separados e interactivos. Adoptaré la convención de usar nombres de variables EN TODAS LAS MAYÚSCULAS para dichos datos.El siguiente nivel del diseño de arriba hacia abajo es codificar
process
. Responde a un solo descriptor de eventose
:Tiene que responder a un evento nulo cuando
get.next.event
no tiene eventos para informar. De lo contrario,process
implementa las "reglas de negocio" del sistema. Prácticamente se escribe a partir de la descripción en la pregunta. Su funcionamiento debería requerir pocos comentarios, excepto para señalar que eventualmente tendremos que codificar subrutinasput.on.hold
erelease.hold
(implementar una cola de retención de clientes) eserve
(implementar las interacciones cliente-asistente).¿Qué es un "evento"? Debe contener información sobre quién está actuando, qué tipo de acción están tomando y cuándo está ocurriendo. Por lo tanto, mi código usa una lista que contiene estos tres tipos de información. Sin embargo,
get.next.event
solo necesita inspeccionar los tiempos. Es responsable solo de mantener una cola de eventos en los queCualquier evento se puede poner en la cola cuando se recibe y
El primer evento en la cola se puede extraer y pasar fácilmente a la persona que llama.
La mejor implementación de esta cola prioritaria sería un montón, pero eso es demasiado exigente
R
. Siguiendo una sugerencia en The Art of R Programming de Norman Matloff (que ofrece un simulador de cola más flexible, abstracto pero limitado), he usado un marco de datos para contener los eventos y simplemente buscarlo por el tiempo mínimo entre sus registros.Hay muchas formas en que esto podría haberse codificado. La versión final que se muestra aquí refleja una elección que hice al codificar cómo
process
reacciona a un evento "Asistente" y cómonew.customer
funciona:get.next.event
simplemente saca a un cliente de la cola de espera, luego se sienta y espera otro evento. A veces será necesario buscar un nuevo cliente de dos maneras: primero, para ver si uno está esperando en la puerta (por así decirlo) y segundo, si uno ha entrado cuando no estábamos buscando.Claramente,
new.customer
ynext.customer.time
son rutinas importantes , así que cuidémoslas a continuación.CUSTOMERS
es una matriz 2D, con datos para cada cliente en columnas. Tiene cuatro filas (que actúan como campos) que describen a los clientes y registran sus experiencias durante la simulación : "Llegado", "Servido", "Duración" y "Asistente" (un identificador numérico positivo del asistente, si lo hay, que sirvió ellos, y de lo contrario-1
para señales de ocupado). En una simulación altamente flexible, estas columnas se generarían dinámicamente, pero debido a cómoR
le gusta trabajar, es conveniente generar todos los clientes desde el principio, en una única matriz grande, con sus tiempos de llegada ya generados al azar.next.customer.time
puede echar un vistazo a la siguiente columna de esta matriz para ver quién vendrá después. La variable globalCUSTOMER.COUNT
indica el último cliente en llegar. Los clientes se gestionan de manera muy simple mediante este puntero, avanzando para obtener un nuevo cliente y mirando más allá (sin avanzar) para echar un vistazo al próximo cliente.serve
implementa las reglas de negocio en la simulación.Esto es sencillo.
ASSISTANTS
es un marco de datos con dos campos:capabilities
(indicando su tasa de servicio) yavailable
, que marca la próxima vez que el asistente estará libre. Se atiende a un cliente generando una duración de servicio aleatoria de acuerdo con las capacidades del asistente, actualizando el tiempo cuando el asistente esté disponible y registrando el intervalo de servicio en laCUSTOMERS
estructura de datos. ElVERBOSE
indicador es útil para probar y depurar: cuando es verdadero, emite una secuencia de oraciones en inglés que describe los puntos clave de procesamiento.Cómo se asignan los asistentes a los clientes es importante e interesante. Uno puede imaginar varios procedimientos: asignación al azar, por algún orden fijo, o de acuerdo con quién ha estado libre el tiempo más largo (o más corto). Muchos de estos se ilustran en código comentado:
El resto de la simulación es realmente solo un ejercicio de rutina para persuadir
R
a implementar estructuras de datos estándar, principalmente un búfer circular para la cola en espera. Debido a que no quieres correr sin control con los globales, puse todo esto en un solo procedimientosim
. Sus argumentos describen el problema: el número de clientes a simular (n.events
), la tasa de llegada de clientes, las capacidades de los asistentes y el tamaño de la cola de espera (que puede establecerse en cero para eliminar la cola por completo).Devuelve una lista de las estructuras de datos mantenidas durante la simulación; el de mayor interés es la50 250
CUSTOMERS
matriz.R
hace que sea bastante fácil trazar la información esencial en esta matriz de una manera interesante. Aquí hay una salida que muestra los últimos clientes en una simulación más larga de clientes.250La experiencia de cada cliente se traza como una línea de tiempo horizontal, con un símbolo circular al momento de la llegada, una línea negra sólida para cualquier espera en espera y una línea de color durante la interacción con un asistente (el color y el tipo de línea diferenciar entre los asistentes). Debajo de esta trama de Clientes hay una que muestra las experiencias de los asistentes, marcando los momentos en que estaban y no estaban comprometidos con un cliente. Los puntos finales de cada intervalo de actividad están delimitados por barras verticales.
Cuando se ejecuta con
verbose=TRUE
, la salida de texto de la simulación se ve así:(Los números a la izquierda son las horas en que se emitió cada mensaje). Puede hacer coincidir estas descripciones con las partes del diagrama de Clientes que se encuentran entre los tiempos y .165160 165
Podemos estudiar la experiencia de los clientes en espera trazando las duraciones en espera por identificador de cliente, usando un símbolo especial (rojo) para mostrar a los clientes que reciben una señal de ocupado.
(¡No todas estas parcelas serían un maravilloso tablero en tiempo real para cualquiera que administre esta cola de servicio!)
Es fascinante comparar los gráficos y las estadísticas que obtienes al variar los parámetros que se pasan
sim
. ¿Qué sucede cuando los clientes llegan demasiado rápido para ser procesados? ¿Qué sucede cuando la cola de espera se hace más pequeña o se elimina? ¿Qué cambia cuando los asistentes son seleccionados de diferentes maneras? ¿Cómo influyen los números y las capacidades de los asistentes en la experiencia del cliente? ¿Cuáles son los puntos críticos en los que algunos clientes comienzan a ser rechazados o quedan en espera por mucho tiempo?Normalmente, para preguntas evidentes de autoaprendizaje como esta, nos detendríamos aquí y dejaríamos los detalles restantes como un ejercicio. Sin embargo, no quiero decepcionar a los lectores que pueden haber llegado tan lejos y están interesados en probar esto por sí mismos (y tal vez modificarlo y desarrollarlo para otros fines), así que a continuación se adjunta el código de trabajo completo.
(El procesamiento de en este sitio estropeará la sangría en cualquier línea que contenga un símbolo , pero la sangría legible debe restaurarse cuando el código se pega en un archivo de texto).$TEX $
fuente
R
que desean otra perspectiva (pero bastante similar) en las simulaciones de colas. Mientras escribía este pequeño simulador, me encontré pensando mucho sobre cuánto aprendí al estudiar el código en (la primera edición del texto) Sistemas operativos / Diseño e implementación de Andrew Tanenbaum . También aprendí sobre estructuras prácticas de datos, como montones, de los artículos de Jon Bentley en CACM y su serie de libros Programming Pearls . Tanenbaum y Bentley son grandes autores que todos deberían leer.