Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C#...

32
PONTIFICIA UNIVERSIDAD CATÓLICA DE CHILE ESCUELA DE INGENIERÍA DEPARTAMENTO DE CIENCIA DE LA COMPUTACIÓN Curso: IIC 1102 INTRODUCCIÓN A LA PROG. ORIENTADA A OBJETO Profesor: Rodrigo Sandoval U. Simulación Computacional con C# 1 INTRODUCCIÓN ............................................................................................................................................... 1 2 MODELO DE SIMULACIÓN............................................................................................................................ 2 2.1 PARÁMETROS DE LA SIMULACIÓN .................................................................................................................. 2 2.2 DATOS O INPUT DE LA SIMULACIÓN................................................................................................................ 2 2.2.1 Generación de Números Aleatorios ....................................................................................................... 2 2.2.2 Carga de Datos Reales desde Archivos.................................................................................................. 4 2.3 EJECUCIÓN DE LA SIMULACIÓN....................................................................................................................... 5 2.3.1 El Manejo del Tiempo ............................................................................................................................ 5 2.3.2 Colas en C# ............................................................................................................................................ 7 3 EJEMPLOS .......................................................................................................................................................... 9 3.1 SIMULACIÓN DE CADENA DE CORREO ............................................................................................................ 9 3.2 LLEGADA DE CLIENTES A CAJA EN EL BANCO .............................................................................................. 10 3.2.1 Solución 1.0.......................................................................................................................................... 11 3.2.2 Solución 2.0.......................................................................................................................................... 13 3.2.3 Solución 3.0.......................................................................................................................................... 15 3.3 SIMULACIÓN DE LAS COLAS EN UN SUPERMERCADO .................................................................................... 17 3.3.1 Definición del Problema ...................................................................................................................... 17 3.3.2 Características del Modelo .................................................................................................................. 17 3.3.3 Mediciones Requeridas ........................................................................................................................ 17 3.3.4 Solución................................................................................................................................................ 18 3.4 SIMULACIÓN DE UNA PLAZA DE PEAJE.......................................................................................................... 24 3.4.1 Definición del Problema ...................................................................................................................... 24 3.4.2 Solución................................................................................................................................................ 26 Material preparado por Rodrigo Sandoval U en Agosto 2005, ([email protected]) basado en los apuntes de clase del curso IIC1102, año 2003, de M. Nussbaum, Marcos Sepúlveda, et.al.

Transcript of Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C#...

Page 1: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

PONTIFICIA UNIVERSIDAD CATÓLICA DE CHILE ESCUELA DE INGENIERÍA DEPARTAMENTO DE CIENCIA DE LA COMPUTACIÓN Curso: IIC 1102 INTRODUCCIÓN A LA PROG. ORIENTADA A OBJETO Profesor: Rodrigo Sandoval U.

Simulación Computacional con C#

1 INTRODUCCIÓN ............................................................................................................................................... 1 2 MODELO DE SIMULACIÓN............................................................................................................................ 2

2.1 PARÁMETROS DE LA SIMULACIÓN .................................................................................................................. 2 2.2 DATOS O INPUT DE LA SIMULACIÓN................................................................................................................ 2

2.2.1 Generación de Números Aleatorios ....................................................................................................... 2 2.2.2 Carga de Datos Reales desde Archivos.................................................................................................. 4

2.3 EJECUCIÓN DE LA SIMULACIÓN....................................................................................................................... 5 2.3.1 El Manejo del Tiempo ............................................................................................................................ 5 2.3.2 Colas en C#............................................................................................................................................ 7

3 EJEMPLOS .......................................................................................................................................................... 9 3.1 SIMULACIÓN DE CADENA DE CORREO ............................................................................................................ 9 3.2 LLEGADA DE CLIENTES A CAJA EN EL BANCO .............................................................................................. 10

3.2.1 Solución 1.0.......................................................................................................................................... 11 3.2.2 Solución 2.0.......................................................................................................................................... 13 3.2.3 Solución 3.0.......................................................................................................................................... 15

3.3 SIMULACIÓN DE LAS COLAS EN UN SUPERMERCADO .................................................................................... 17 3.3.1 Definición del Problema ...................................................................................................................... 17 3.3.2 Características del Modelo .................................................................................................................. 17 3.3.3 Mediciones Requeridas ........................................................................................................................ 17 3.3.4 Solución................................................................................................................................................ 18

3.4 SIMULACIÓN DE UNA PLAZA DE PEAJE.......................................................................................................... 24 3.4.1 Definición del Problema ...................................................................................................................... 24 3.4.2 Solución................................................................................................................................................ 26

Material preparado por Rodrigo Sandoval U en Agosto 2005, ([email protected]) basado en los apuntes de clase del curso IIC1102, año 2003, de M. Nussbaum, Marcos Sepúlveda, et.al.

Page 2: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

1 Introducción La simulación mediante programas de computador permite el estudio detallado de sistemas complejos, sobre los que resulta costoso, difícil o peligroso llevar a cabo estudios reales. La simulación se basa en analizar el comportamiento de un modelo derivado de una situación real, de la forma más equivalente posible, para obtener resultados de la medición del comportamiento de este modelo y así sacar conclusiones.

En otras palabras, un modelo de simulación intenta recrear de la mejor manera posible las características del sistema representado y se comporta de manera similar a como lo haría en la realidad. La idea es que la ejecución de la simulación produzca resultados en la forma de valores estadísticos, o simplemente permita monitorear el desempeño del sistema durante su funcionamiento.

Modelo de Simulación

Los modelos de simulación distinguen en general cuatro elementos esenciales:

A. Parámetros de Funcionamiento. Estos datos, muchas veces valores numéricos fijos para una simulación, determinan ciertas condiciones de la ejecución, que también se define como el escenario a analizar. Siempre será posible cambiar los valores de estos parámetros y como consecuencia, observar el comportamiento del modelo con esas nuevas condiciones y eventualmente sacar conclusiones al comparar los resultados de un escenario con los de otro.

B. Datos o Input de la Simulación. Para representar situaciones del modelo real, se cuenta con datos de diverso tipo que alimentarán la simulación completando el escenario a implementar con este modelo. Estos datos generalmente son de tres tipos: datos fijos, conceptualizados como promedios constantes; datos aleatorios que le dan un factor de variabilidad y ofrecen un escenario con elementos impredecibles al modelo; y datos reales, que fueron medidos en una situación equivalente en la vida real, y que le aportarán el factor realista directo al modelo.

C. Ejecución de la Simulación. Consiste en realizar la simulación propiamente tal, por medio de la ejecución iterativa de pasos que emulan el comportamiento de la situación modelada. Entre los elementos que se consideran en esta ejecución, posiblemente el más importante es el manejo del tiempo, en el cual el modelo es capaz de identificar los eventos que ocurren en un instante relevante de tiempo, y ejecutarlos como parte de la simulación.

D. Resultados de la Simulación. Datos medidos durante la ejecución que permiten obtener una visión del desempeño del modelo y por ende, sacar conclusiones de la situación simulada.

Tomando un ejemplo clásico, la simulación de autos en una intersección de calles, un parámetro de entrada sería la duración de la luz roja y de la verde; datos o input sería la llegada de vehículos en momentos de la simulación; la ejecución consideraría el tiempo que toma que los autos se vayan acumulando en roja y luego salgan en verde; y resultados posibles se consideran el tiempo de espera, o la probabilidad de que un auto no alcance a cruzar en verde.

IIC 1102 Página: 1

Page 3: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es de mucha utilidad el uso de parámetros, que permitan de manera simple cambiar las características del ambiente o del sistema mismo, de modo que sea posible observar los cambios que se producen en su operación. Definen un escenario específico en el cual se realizará la simulación. Normalmente son valores numéricos, que se mantienen constantes durante la simulación completa.

El hecho de mantener estos valores paramétricos, permite a quien analiza la simulación variarlos y poder probar distintos escenarios de simulación. Por ejemplo, parámetros de una simulación podrían ser la duración de un semáforo en una intersección, la capacidad de carga de un camión o de otro medio de transporte, la capacidad de atención de una caja de banco o de tienda, valores monetarios o tarifas.

2.2 Datos o Input de la Simulación Los datos que alimentan el modelo de simulación pueden ser fijos – que usualmente son más bien considerados como parámetros de la simulación – o bien generarse en forma aleatoria de acuerdo a ciertas condiciones de distribución de estos valores casi siempre numéricos, y finalmente es posible contar con mediciones reales tomadas en terreno, las cuales al quedar almacenadas en archivos, por ejemplo, permiten su recuperación durante el proceso de la simulación, para constituir una fuente realista de la situación modelada.

2.2.1 Generación de Números Aleatorios La generación de valores aleatorios le da un grado de incerteza al comportamiento del modelo. Si bien es posible determinar que ciertos valores que alimentan el modelo se comportan de acuerdo a diferentes tipos de distribuciones estadísticas, en el gran porcentaje de los casos, el uso de la distribución uniforme – en la cual todos los números de un rango tienen la misma posibilidad de salir – es suficiente para soportar diferentes modelos.

Para producir estos datos es necesario contar con herramientas que generen números aleatorios en ciertos intervalos y con cierta distribución especificada en el modelo.

En C# la generación de números aleatorios está resuelta por una clase llamada Random, cuyo principal propósito es generar números aleatorios dentro de un rango especificado. Un programa que utilice Random para la generación de números, depende de dos principales declaraciones: el constructor y el método Next().

2.2.1.1 Constructor de Random

Existen diferentes versiones del constructor, las cuales – por sobrecarga – reciben distintos parámetros.

El constructor simple no recibe parámetros:

Random num = new Random();

El constructor con semilla permite su inicialización estableciendo una semilla de aleatoriedad, de manera que no se repitan las secuencias de números entregados. Para darle un grado de variabilidad a esta generación de números, se recomienda el uso de una semilla que en cada llamado al programa tenga un valor diferente. El usar un número fijo o constante, es equivalente funcionalmente al constructor sin parámetros: la secuencia de números aleatorios será idéntica en cada ejecución desde cero del programa. Para la semilla, hay dos alternativas: utilizar un número entregado por el usuario, que se espere vaya variando en cada ejecución, o utilizar un valor del reloj del computador, el cual se obtiene del uso de DateTime.Now – objeto que se detalla más adelante en este documento. Este objeto tiene un campo llamado Millisecond, el cual indica la parte de milisegundos (de 0 a 999) de la hora actual.

Random num = new Random(DateTime.Now.Millisecond);

IIC 1102 Página: 2

Page 4: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

2.2.1.2 Generación de números con Next

El método Next() tiene varias versiones, las cuales – por sobrecarga de métodos – ofrecen comportamientos levemente diferentes y útiles en situaciones distintas. Las dos versiones principales son las siguientes, y ambas incluyen un valor que representa el límite superior no incluido del rango de valores posibles:

int numero1 = num.Next(11); // numero1 tendrá un valor entre 0 y 10

int numero2 = num.Next(5,11); // numero2 tendrá un valor entre 5 y 10

2.2.1.3 Ejemplo Básico de Random

A continuación, un ejemplo de un programa que genera 10 números aleatorios entre 1 y 10.

using System; class MainApp { static void Main() { Random rn = new Random(DateTime.Now.Millisecond); for(int n=0; n<10 ; n++) Console.WriteLine(“Número: {0}”, rn.Next(1,11)); // Números entre 1 y 10 Console.ReadLine(); } }

En el ejemplo anterior resulta relevante analizar las siguientes líneas:

- La instanciación de un nuevo generador de números aleatorios: Random rn = new Random(...)

- Le generación de un nuevo número: rn.Next(1,11);

La primera línea se refiere a la creación de un nuevo generador de números aleatorios, instanciado como rn. Como argumento al constructor, se entrega la semilla de generación, que en este caso es un número de 0 a 999 (correspondiente a los milisegundos de la hora actual). Este número, que según el instante en que se ejecute la línea, tendrá uno de 1.000 valores posibles, inicializará el punto de partida de la serie de generación de números aleatorios, asegurando que la posibilidad de que se repita una secuencia de números generados, sea una en mil.

La segunda línea relevante de conocer es la que entrega un nuevo número: rn.Next(1,11), indicando que los valores posibles van entre el 1 y el 10 (11-1).

2.2.1.4 Generación de Valores Aleatorios en Otras Escalas

En muchos casos, el uso de valores enteros directamente no es parte del contexto del problema modelado. Por tal razón, existen estrategias de aprovechamiento del comportamiento de Random descrito anteriormente, que permiten generar estos números en otras escalas.

Generación de Verdadero o Falso Aleatoriamente.

La conversión es simple, si se toma la generación de números enteros aleatorios entre 0 y 1 se puede tener una conversión en que 0 corresponde a False (o false en C#) y 1 corresponde a Verdadero (true en C#).

using System; class MainApp { static void Main() { Random rn = new Random(DateTime.Now.Millisecond); for(int n=0; n<10 ; n++) if( rn.Next(2) == 1 ) // Valores entre 0 y 1 Console.WriteLine(“VERDADERO”); else Console.WriteLine(“FALSO”); Console.ReadLine(); } }

IIC 1102 Página: 3

Page 5: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

Generación de Valores Reales Aleatoriamente.

La primera decisión que hay que tomar es cuántos decimales son relevantes para el modelo representado. Si la cantidad de decimales relevantes son 2, entonces, se generan números enteros que se dividen por 100 (10 elevado a 2). using System; class MainApp { static void Main() { Random rn = new Random(DateTime.Now.Millisecond); for(int n=0; n<10 ; n++) // 10 números reales aleatorios entre 0.00 y 99.99 Console.WriteLine(“Número: {0}”, rn.Next(1,10001)/100); Console.ReadLine(); } }

Generación con Diferente Probabilidad

Un modelo particular puede plantear algo como “la cantidad de personas que entran en cada instante de tiempo es de 1 con 20% de probabilidad, 2 con 30% y 3 con 50%”. Esta situación una vez más puede modelarse con la generación de números enteros aleatorios, con la adaptación en función de los porcentajes de probabilidades.

Es decir, si un caso tiene 20% de probabilidades de salir, implica que de 10 números (1 al 10) la probabilidad de que salga un 1 ó un 2 es exactamente de 10%+10% = 20%. Así, el siguiente 30% se da cuando salen el 3, 4 ó 5, y el 50% restante con cualquier número entre 6 y 10. En ese caso, el ejemplo podría plantearse en C#. using System; class MainApp { static void Main() { Random rn = new Random(DateTime.Now.Millisecond); int numero = rn.Next(1,11); if(numero <= 2) Console.WriteLine(“20%”); if(numero>2 && numero<=5) Console.WriteLine(“30%”); if(numero>5) Console.WriteLine(“50%”); Console.ReadLine(); } }

2.2.2 Carga de Datos Reales desde Archivos En muchos casos, más que asumir comportamientos de acuerdo a una distribución estadística, es factible contar con datos reales, en muchos casos medidos en su generación real. Por ejemplo, la cantidad de autos llegados a una intersección por unidad de tiempo, la cantidad de clientes que llegan a la caja en un banco, etc.

En estos casos, conociendo el comportamiento de cierto parámetro en forma real, estos datos alimentan el sistema de simulación, el cual procesa la información entrante según la lógica.

La información se almacena en archivos de datos, cuyo caso más común es simplemente el formato de texto plano, cada línea del archivo representando un dato puntual. El archivo es leído antes de comenzar la simulación y sus datos son almacenados en una representación de cola, o alguna estructura que emule la misma generación de los datos, secuencialmente en el tiempo.

IIC 1102 Página: 4

Page 6: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

2.3 Ejecución de la Simulación Uno de los aspectos más importantes en una simulación es el manejo del tiempo, pues los sistemas normalmente se desenvuelven de acuerdo a una componente temporal. En este punto, la alternativa más simple es emplear una componente de tiempo discreto. Según este enfoque, el funcionamiento del sistema se puede predecir dentro de unidades discretas de tiempo (por ejemplo, segundos o minutos, e incluso días). La elección de esta unidad resulta fundamental, pues introducirá cierto margen de error en la simulación.

Otro aspecto fundamental es la alimentación de la simulación con datos de entrada reales. Las simulaciones usualmente llevan consigo una gran cantidad de trabajo de campo recogiendo valores de entrada. Por ejemplo, para simular los tacos que se forman en una intersección será necesario tomar datos sobre la afluencia de vehículos por cada calle que concurre a la intersección.

Existen bases teóricas que pueden aplicarse a distintos modelos de simulación, tal es el caso de la Teoría de Colas para la simulación de filas en las que usuarios esperan ser atendidos, o Dinámica para la simulación de cuerpos en movimiento. En general, una simulación requerirá de algún sustento teórico que guiará el funcionamiento del sistema, y por consiguiente dependerá de cada caso en particular.

En esta sección se presenta un modelo de simulación, junto con su implementación, que pretende ilustrar esta importante aplicación de los computadores. El modelo planteado no hace uso de resultados teóricos importantes, con el objetivo de hacerlo más fácil de entender. Sin embargo, presenta conceptos de mucha importancia, como el manejo del tiempo discreto, la representación de las entidades que forman el modelo como estructuras de datos del lenguaje de programación empleado, y el manejo de algunos parámetros de configuración.

2.3.1 El Manejo del Tiempo Tal como se indicó, uno de los elementos relevantes de controlar es el tiempo. Ya sea que el contexto de la simulación requiere una unidad discreta basada en segundos, minutos, horas, días, semanas, o incluso meses, siempre es necesario ir registrando el paso del tiempo con un contador. Este registro puede ser tan simple como utilizar un contador entero que se incrementa de uno en uno, hasta determinar el fin de la simulación. En este caso, se usa por convención el concepto de Tics, refiriéndose a que cada Tic es un incremento en el contador de tiempo.

Para esto, dos objetos existentes en el framework de .NET resuelven el manejo del tiempo y lapsos.

2.3.1.1 DateTime

En algunos casos, se requiere un registro del tiempo más preciso que un simple contador, por lo que se usa una estructura que almacena los datos referentes al tiempo. En C# se cuenta con tal tipo de estructura, en la forma de una clase de nombre DateTime.

En particular, existe una propiedad de DateTime, que ofrece todos los datos de la hora actual (al momento de ser consultada), incluyendo hasta los milisegundos: año-mes-día-hora-min-seg-miliseg. Esta es DateTime.Now y se usa como referencia temporal para inicializaciones, o incluso, comparaciones referenciales.

La instanciación de un objeto de tipo DateTime aprovecha las facultades del Constructor. Por ejemplo:

using System; // Nueva instancia DateTime con el 28 del 7 de 1979 a las 10:35:05 PM. DateTime dateTime = new DateTime(1979, // Año 07, // Mes 28, // Día 22, // Hora 35, // Minutos 5, // Segundos 15); // Milisegundo Console.WriteLine("{0:F}", dateTime); // Escribe la fecha

IIC 1102 Página: 5

Page 7: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

2.3.1.2 Propiedades, Métodos y Operadores principales de DateTime

Propiedades

Date Obtiene el componente correspondiente a la fecha de esta instancia. Day Obtiene el día del mes representado por esta instancia. DayOfWeek Obtiene el día de la semana representado por esta instancia. DayOfYear Obtiene el día del año representado por esta instancia.

Hour Obtiene el componente correspondiente a la hora de la fecha representada por esta instancia.

Millisecond Obtiene el componente correspondiente a los milisegundos de la fecha representada por esta instancia.

Minute Obtiene el componente correspondiente a los minutos de la fecha representada por esta instancia.

Month Obtiene el componente correspondiente al mes de la fecha representada por esta instancia.

Now Obtiene un DateTime que constituye la fecha y hora locales actuales de este equipo.

Second Obtiene el componente correspondiente a los segundos de la fecha representada por esta instancia.

Ticks Obtiene el número de pasos que representan la fecha y hora de esta instancia. TimeOfDay Obtiene la hora del día para esta instancia. Today Obtiene la fecha actual.

UtcNow Obtiene un DateTime que representa la fecha y hora locales actuales de este equipo y que se expresa en forma de hora universal coordinada (UTC).

Year Obtiene el componente correspondiente al año de la fecha representada por esta instancia.

Métodos

AddDays Agrega el número de días especificado al valor de esta instancia. AddHours Agrega el número de horas especificado al valor de esta instancia. AddMilliseconds Agrega el número de milisegundos especificado al valor de esta instancia. AddMinutes Agrega el número de minutos especificado al valor de esta instancia. AddMonths Agrega el número de meses especificado al valor de esta instancia. AddSeconds Agrega el número de segundos especificado al valor de esta instancia. AddTicks Agrega el número de pasos especificado al valor de esta instancia. AddYears Agrega el número de años especificado al valor de esta instancia.

Compare Compara dos instancias de DateTime y devuelve una indicación de sus valores relativos.

CompareTo Compara esta instancia con un objeto especificado y devuelve una indicación de los valores relativos.

Operadores

Suma (+) Agrega un intervalo de tiempo especificado a una fecha y hora especificadas, generando una fecha y hora nuevas.

Igualdad (==) Determina si dos instancias especificadas de DateTime son iguales.

Mayor que (> y >=) Determina si un DateTime especificado es mayor que otro DateTime especificado.

Desigualdad (!=) Determina si dos instancias especificadas de DateTime no son iguales.

Menor que (< y <=) Determina si un DateTime especificado es menor que otro DateTime especificado.

Resta (-) Sobrecargado. Resta un DateTime especificado de un DateTime especificado.

IIC 1102 Página: 6

Page 8: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

Ejemplos prácticos del uso de DateTime como parte de los datos de una clase utilizada en una simulación se ven en la siguiente sección de ejemplos.

2.3.1.3 TimeSpan

Por su parte, el manejo de lapsos o intervalos de tiempo se resuelve con TimeSpan. Esencialmente éste representa el objeto resultante de la diferencia entre dos objetos de tipo DateTime, y es el que se usa para representar los Tics o unidades de tiempo relevante.

Existen varias versiones del constructor de TimeSpan, las que varían principalmente en la cantidad de enteros que reciben como parámetro, lo cual determina la cantidad de tiempo que incluye el intervalo de tiempo. Algunas de estas diferentes versiones se demuestran en los siguientes ejemplos.

using System; TimeSpan t1 = new TimeSpan(0, 1, 0); // 0 horas, 1 minuto, 0 segundos TimeSpan t2 = new TimeSpan(1, 0, 0, 0); // 1 día, 0 horas, 0 min, 0 seg TimeSpan t3 = new TimeSpan(0, 0, 0, 0, 1); // 1 dd, 0 hh, 0 mm, 0 s, 1 mseg.

A continuación se muestra un ejemplo práctico del uso de TimeSpan y DateTIme juntos en una simulación. En este caso, el reloj de control de la simulación deberá comenzar a las 13:30. Como referencia de fecha, se utiliza la fecha actual por medio de DateTime.Now que corresponde a un objeto de tipo DateTime asignado a la fecha del computador en el momento en que se invoca.

using System; . . . // Declaración del reloj que llevará la cuenta de tiempo de simulación DateTime reloj = DateTime.Now; // Reloj puesto a la fecha y hora actual // Se ajusta el reloj a la hora de inicio de la simulación reloj.Hour = 13; reloj.Minute = 30; reloj.Second = 0; reloj.Millisecond = 0; // Declaración de la hora de fin -> 30 minutos después del inicio. DateTime fin = reloj + new TimeSpan(0,30,0); // Declaración de la unidad significativa de tiempo -> 1 minuto TimeSpan tick = new TimeSpan(0, 1, 0); // 0 horas, 1 minuto, 0 segundos . . . while(reloj <= fin) { // Mientras el reloj no sea igual a la hora de fin . . . Reloj += tick; // Se incrementa el contador de tiempo en un tick } . . .

2.3.2 Colas en C# El uso de colas en simulación permite representar la llegada de objetos (personas, autos, órdenes de compra, etc.) en el tiempo y que serán atendidos como parte del proceso de simulación. El uso de colas es un concepto tradicionalmente referido en simulación computacional.

En el caso del lenguaje C# y del framework de .NET, reconociendo las colas como una estructura frecuentemente requerida, se ha incluido su definición completa en un objeto denominado Queue, que ofrece el comportamiento tradicional de una cola, en la cual los elementos nuevos ingresan sólo al final y se sacan elementos sólo por adelante. Esta clase está disponible dentro del Namespace System.Collections.

IIC 1102 Página: 7

Page 9: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

Esta clase Queue puede almacenar objetos de cualquier tipo, ya que su elemento base es Object, que es el objeto base del cual derivan absolutamente todos los objetos definidos por los desarrolladores. De esa manera, se pueden crear fácilmente colas para almacenar elementos básicos como números (int, double, etc.) o cualquier otro elemento definido en una clase del programa.

Las operaciones estándar de una cola son: Agregar un Elemento (que lo ubica al final de la cola de elementos ya agregados); Sacar el Primero (sólo se sacan elementos por el inicio de la cola); Ver el Primero (sólo se puede ver el elemento que está en primer lugar sin sacarlo de la cola); y ver el Largo de la lista (para determinar la cantidad de elementos que están en la cola).

Formalmente, los elementos de la clase Queue son los siguientes:

Métodos

void Enqueue(Object) Este método “encola” un elemento derivado de la clase Object.

Object Dequeue()

Saca el primer elemento de la cola, retornándolo para ser utilizado. Este método no verifica si la cola cuenta con elementos, por lo que es conveniente agregar una cláusula condicional verificando que existan elementos antes de retirar el primero, o bien aprovechar un bloque de control de excepciones try-catch.

Object Peek() Funciona equivalentemente a Dequeue(), con la diferencia de que el objeto en primer lugar de la cola no es retirado, sino que permanece.

Propiedades

int Count Propiedad que retorna un número mayor o igual a cero, indicando la cantidad de elementos de la cola.

Count

Enqueue()Dequeue()

Peek()

La siguiente sección incluye diferentes ejemplos que hacen uso exhaustivo de la definición de Queue, de modo de ilustrar el comportamiento de cada uno de estos métodos y propiedad, así como dar una noción de la manera de utilizar esta clase para apoyar el proceso de simulación.

IIC 1102 Página: 8

Page 10: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

3 Ejemplos Entre los ejemplos que ilustran la simulación conceptual, se distinguen diversos tipos de complejidad. A medida que los ejemplos van involucrando más elementos de simulación y de resultados, se van programando y utilizando objetos más complejos.

3.1 Simulación de Cadena de Correo Las cadenas enviadas por correo (originalmente en cartas de papel, hoy por e-mail), son seguidas por muchos y odiadas por otros tantos. En este ejemplo se pretende ver el comportamiento de una nueva cadena por correo, la cual cuenta con ciertas características que definen su funcionamiento. Esta cadena en particular indica que para ser continuada, cada receptor deberá re-enviar a 4 nuevas personas. Para efectos del ejemplo se han tomado ciertas simplificaciones a un caso realista, de modo de concentrar el modelamiento en los conceptos vistos en este documento.

La forma de funcionamiento es la siguiente:

• De las 4 personas a quienes se reenvía, existe un 66% de probabilidad de que la persona receptora no lo tome en cuenta y corte su parte de la cadena.

• El periodo que se toma en leer y reenviar es de 24 horas.

Este programa de simulación analiza el comportamiento de una cadena, en la medida en que se van agregando nuevas personas, por un periodo de 30 días.

Al final de la simulación, se indicarán en pantalla cuántas personas en total recibieron la cadena y cuántas efectivamente la reenviaron.

Solución

Esta solución se implementa en forma directa, sin mayores estructuras especiales. En particular, el manejo del tiempo, al no requerirse en fechas absolutas, se maneja en forma relativa con un simple contador de tipo entero, avanzando por un loop o ciclo de 30 iteraciones (representando los 30 días de simulación).

Código Fuente Solución using System; class MainApp { static void Main() { Random rn = new Random(DateTime.Now.Millisecond); int enviaron = 1, recibieron = 0, recibieronant = 1; // Se parte con 1 sola persona for(int i=0; i<30 ; i++) { // loop para 30 días int rec = 0, env = 0; Console.Write("Día {0}: ", i+1); for(int j=0; j<recibieronant; j++) { // p/todos los receptores día anterior for(int k=0; k<4; k++) { // c/u de los anteriores, envió a 4 rec++; if( rn.Next(0,3) > 1 ) // Posibilidad de que lo reenvíe env++; } } Console.WriteLine(" de:{0} rec:{1} y env:{2}", recibieronant, rec, env); recibieronant = env; recibieron += rec; enviaron += env; } Console.WriteLine("En un periodo de simulación de 30 días:"); Console.WriteLine("Recibieron: {0} personas", recibieron); Console.WriteLine("Enviaron: {0} personas", enviaron); Console.ReadLine(); } }

IIC 1102 Página: 9

Page 11: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

Ejemplo de ejecución y resultados:

Día 1: de:1 rec:4 y env:3 Día 2: de:3 rec:12 y env:3 Día 3: de:3 rec:12 y env:9 Día 4: de:9 rec:36 y env:14 Día 5: de:14 rec:56 y env:22 Día 6: de:22 rec:88 y env:28 Día 7: de:28 rec:112 y env:32 Día 8: de:32 rec:128 y env:41 Día 9: de:41 rec:164 y env:56 Día 10: de:56 rec:224 y env:70 Día 11: de:70 rec:280 y env:85 Día 12: de:85 rec:340 y env:100 Día 13: de:100 rec:400 y env:140 Día 14: de:140 rec:560 y env:192 Día 15: de:192 rec:768 y env:251 Día 16: de:251 rec:1004 y env:332 Día 17: de:332 rec:1328 y env:450 Día 18: de:450 rec:1800 y env:596 Día 19: de:596 rec:2384 y env:805 Día 20: de:805 rec:3220 y env:1027 Día 21: de:1027 rec:4108 y env:1389 Día 22: de:1389 rec:5556 y env:1803 Día 23: de:1803 rec:7212 y env:2430 Día 24: de:2430 rec:9720 y env:3337 Día 25: de:3337 rec:13348 y env:4488 Día 26: de:4488 rec:17952 y env:5960 Día 27: de:5960 rec:23840 y env:7777 Día 28: de:7777 rec:31108 y env:10201 Día 29: de:10201 rec:40804 y env:13572 Día 30: de:13572 rec:54288 y env:18036 En un periodo de simulación de 30 días: Recibieron: 220856 personas Enviaron: 73250 personas

3.2 Llegada de Clientes a Caja en el Banco Este ejemplo muestra el simple proceso de la llegada de clientes a una caja de banco y cómo son atendidos.

En particular se busca mostrar distintas versiones de un mismo ejemplo, agregando ciertos elementos o simplificando algunas condiciones para ilustrar el uso de los diferentes elementos que tanto la teoría, como la librería de clases del Microsoft .NET framework ofrecen para facilitar estas implementaciones.

Se toman las siguientes condiciones:

• El periodo de simulación es de 30 minutos.

• Se conoce el momento de llegada de los clientes a la cola, datos que vienen almacenados en un archivo de datos. Puede llegar más de un cliente por minuto.

En un archivo de entrada, clientes.dat, vendrá como único dato por cada línea, el instante en que llegó el cliente N (con N: línea del archivo). Es posible que más de una línea contenga el mismo número, representando que más de un cliente llegó en el mismo instante de tiempo.

• Se asume que todos los clientes tienen en promedio la misma cantidad de trámites que realizar, por lo que se demorarán lo mismo.

IIC 1102 Página: 10

Page 12: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

• Se sabe que el único cajero atendiendo, procesa 1 cliente por minuto. Por esta razón se utilizará 1 minuto como unidad de tiempo significativa.

Instante 1 Instante 2 Instante 3 Instante 4

Orden de Llegada

Atiende 1 cliente por

minuto

1º 4º

Al finalizar la simulación interesa conocer:

• El total de clientes atendidos por el cajero.

• La espera máxima en la cola en minutos.

3.2.1 Solución 1.0 Esta primera versión del ejemplo se modela y soluciona de la forma más simple, tomando algunas suposiciones de la operación real y utilizando los elementos básicos del lenguaje C#.

Solución

Se implementará una cola de clientes, registrando el instante de llegada de cada uno de ellos, de modo de procesar los momentos de llegada en sincronización con el manejo del tiempo de la simulación, mientras que se utilizan los instantes de llegada para medir el tiempo de espera de cada cliente, al compararlo con el momento en que son atendidos.

El proceso general tomará un reloj de tipo número entero, funcionando como contador (cronómetro de minutos), que irá aumentando en 1, cuando haya clientes en cola, o se adelantará hasta el instante en que llega el siguiente cliente. Es decir, no es necesario una contabilización exhaustiva de cada unidad de tiempo de simulación, sino que se puede simplificar el proceso computacional involucrado al procesar sólo los instantes en que ocurren eventos relevantes dentro del proceso, como es la atención de clientes, mientras que se saltan los instantes en que no hay clientes en la cola.

Código Fuente Solución using System; using System.IO; // ---------------------------------------------------------------- // Clase Cliente // Representa un cliente, con su instante de llegada // ---------------------------------------------------------------- class Cliente { int llegada; public Cliente(int l) { llegada = l; } public int Llegada { get { return(llegada); } } }

IIC 1102 Página: 11

Page 13: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

// ---------------------------------------------------------------- // Clase Cola // Representa la cola que se forma frente a la caja. Almacena todos // los clientes ingresados con su respectivo instante de llegada // ---------------------------------------------------------------- class Cola { const int MAX = 30; Cliente[] clientes; int cantidad = 0; string archivo = "clientes.dat"; public Cola() { clientes = new Cliente[MAX]; // Dimensionamiento StreamReader sr; try { sr = new StreamReader(archivo); } catch (Exception e) { Console.WriteLine("Error al abrir \"{0}\"\n{1}", archivo, e.ToString()); return; } string linea = sr.ReadLine(); while(linea != null) { Agregar(int.Parse(linea)); linea = sr.ReadLine(); } sr.Close(); } // Agregar(): dado un instante de llegada 'l', lo agrega a la cola public void Agregar(int l) { if(cantidad<MAX) clientes[cantidad++] = new Cliente(l); } // Primero(): devuelve el primer cliente en la cola public Cliente Primero() { if(cantidad>0) return(clientes[0]); else { Cliente vacio = new Cliente(0); return(vacio); } } // Atender(): atiende al primer cliente de la cola, sacándolo de ella public void Atender() { if(cantidad>0) { for(int i=1; i<cantidad ; i++) clientes[i-1] = clientes[i]; cantidad--; } } public int Cantidad { get { return(cantidad); } } } // ---------------------------------------------------------------- // Clase Principal // ---------------------------------------------------------------- class Principal { static void Main() { int reloj = 0; // reloj contador de minutos Cola cola = new Cola(); // Instancia la cola de clientes int esperamax = 0; int cantclientes = cola.Cantidad; // Se registra la cantidad total de clientes Console.WriteLine("Procesando..."); // Proceso simulación involucra 30 min o hasta que se acaben los clientes while(reloj<=30 && cola.Cantidad>0) { Cliente c = cola.Primero(); if(reloj<c.Llegada) reloj = c.Llegada; // Se avanza reloj al primero

IIC 1102 Página: 12

Page 14: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

else reloj++; Console.Write(" {0}", reloj); if( reloj-c.Llegada > esperamax ) esperamax = reloj-c.Llegada; cola.Atender(); } // Al final, indica los valores registrados Console.WriteLine("\nPersonas atendidas: {0}", cantclientes); Console.WriteLine("Espera máxima: {0}", esperamax); Console.Write("Presione ENTER..."); Console.ReadLine(); } }

Ejemplo de Ejecución

Archivo “clientes.dat”:

1 1 1 3 6 7 9 11 11 15 16 17 19 19 19 21 22 23 24 26 28

Salida en Pantalla:

Procesando... 1 2 3 4 6 7 9 11 12 15 16 17 19 20 21 22 23 24 25 26 28 Personas atendidas: 21 Espera máxima: 2 Presione ENTER...

3.2.2 Solución 2.0 Evolucionando un poco el ejemplo anterior, esta segunda versión profundiza un poco en el uso de la clase Queue como apoyo al modelamiento de la cola de clientes que llegan al banco, de manera que la implementación de la cola de clientes se muestra más simple en código.

Particularmente, el enfoque de esta solución, implementa la clase Cola, heredando de Queue, complementando algunos métodos especiales para el contexto de este problema, en particular el constructor.

IIC 1102 Página: 13

Page 15: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

Código Fuente using System; using System.IO; using System.Collections; // ---------------------------------------------------------------- // Clase Cliente // Representa un cliente, con su instante de llegada // ---------------------------------------------------------------- class Cliente { int llegada; public Cliente(int l) { llegada = l; } public int Llegada { get { return(llegada); } } } // ---------------------------------------------------------------- // Clase Cola (Hereda de Queue) // Representa la cola que se forma frente a la caja. Almacena todos // los clientes ingresados con su respectivo instante de llegada // ---------------------------------------------------------------- class Cola : Queue { string archivo = "clientes.dat"; public Cola() { StreamReader sr; try { sr = new StreamReader(archivo); } catch (Exception e) { Console.WriteLine("Error al abrir \"{0}\"\n{1}", archivo, e.ToString()); return; } string linea = sr.ReadLine(); while(linea != null) { Enqueue(new Cliente(int.Parse(linea))); linea = sr.ReadLine(); } sr.Close(); } // Primero(): devuelve el primer cliente en la cola public Cliente Primero() { if(Count>0) return( (Cliente) Peek() ); else return(new Cliente(0)); } // Atender(): atiende al primer cliente de la cola, sacándolo de ella public void Atender() { if(Count>0) Dequeue(); } public int Cantidad { get { return(Count); } } } // ---------------------------------------------------------------- // Clase Simulacion // ---------------------------------------------------------------- class Simulacion { int atendidos = 0; int esperamax = 0; int encola = 0; public void Simular(int tiempo) { int reloj = 1; // reloj contador de minutos Cola cola = new Cola(); // Instancia la cola de clientes Console.WriteLine("Procesando..."); encola = cola.Cantidad;

IIC 1102 Página: 14

Page 16: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

// Proceso dura 30 minutos o hasta que se acaben los clientes while(reloj<=tiempo && cola.Cantidad>0) { Cliente c = cola.Primero(); if(reloj<c.Llegada) reloj = c.Llegada; // Se avanza reloj al primero else reloj++; Console.Write(" {0}", reloj); if( reloj-c.Llegada > esperamax ) esperamax = reloj-c.Llegada; cola.Atender(); atendidos++; encola = cola.Cantidad; } } public int Atendidos { get { return(atendidos); } } public int EsperaMax { get { return(esperamax); } } public int EnCola { get { return(encola); } } } // ---------------------------------------------------------------- // Clase Principal // ---------------------------------------------------------------- class Principal { static void Main() { Simulacion s = new Simulacion(); s.Simular(30); // Efectúa el proceso completo de simulación // Al final, indica los valores registrados Console.WriteLine("\nPersonas atendidas: {0}", s.Atendidos); Console.WriteLine("Espera máxima: {0}", s.EsperaMax); Console.WriteLine("Personas en Cola: {0}", s.EnCola); Console.Write("Presione ENTER..."); Console.ReadLine(); } }

3.2.3 Solución 3.0 En esta tercera versión del mismo caso de simulación ofrece algunas diferencias al problema original. En primer lugar, la llegada de los clientes se mide en horas absolutas (hh:mm) y no en una referencia relativa de minutos. Por otro lado, la llegada de los clientes no se conoce y se determina en forma aleatoria. En cada instante de simulación podrán llegar entre 0 y 2 clientes. La tercera diferencia, relacionada con la implementación, es que se simplifica la definición de la cola de clientes (utilizando directamente la clase Queue).

Dado el uso de minutos en la forma hh:mm, se aprovechará la clase DateTime, identificando para cada cliente el instante de llegada. A la vez, el control de la evolución del tiempo de la simulación, también tomará el mismo tipo de objeto para ir contabilizando los minutos en la forma hh:mm. Para representar la unidad relevante de tiempo se utilizará un objeto de tipo TimeSpan, como un tick.

Código Fuente using System; using System.IO; using System.Collections; // ---------------------------------------------------------------- // Clase Cliente // Representa un cliente, con su instante de llegada // ---------------------------------------------------------------- class Cliente { DateTime horallegada; public Cliente(DateTime hl) { horallegada = hl; } public DateTime HoraLlegada { get { return(horallegada); } } }

IIC 1102 Página: 15

Page 17: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

// ---------------------------------------------------------------- // Clase Simulacion // ---------------------------------------------------------------- class Simulacion { int atendidos = 0; int maxespera = 0; public void Procesar() { DateTime reloj = new DateTime(2000,1,1,13,30,0,0); DateTime horafin = new DateTime(2000,1,1,14,00,0,0); TimeSpan tick = new TimeSpan(0,1,0); Random rn = new Random(DateTime.Now.Millisecond); Queue cola = new Queue(); while( reloj <= horafin ) { int clientes = rn.Next(0,3); for(int i=0; i<clientes; i++) cola.Enqueue(new Cliente(reloj)); Console.WriteLine("{0}:{1}, llegaron {2} clientes a una cola con {3}",

reloj.Hour, reloj.Minute, clientes, cola.Count);

if(cola.Count>0) { // Siempre verificar largo de la cola antes de procesar. Cliente sale = (Cliente) cola.Dequeue(); atendidos++; if(maxespera < (reloj.Minute - sale.HoraLlegada.Minute)) maxespera = (reloj.Minute - sale.HoraLlegada.Minute); } reloj += tick; } } public int Atendidos { get { return(atendidos); } } public int MaxEspera { get { return(maxespera); } } } // ---------------------------------------------------------------- // Clase Principal // ---------------------------------------------------------------- class Principal { static void Main() { Simulacion sim = new Simulacion(); sim.Procesar(); Console.WriteLine("Cliente atendidos: {0}", sim.Atendidos); Console.WriteLine("Máxima espera: {0}", sim.MaxEspera); Console.Write("Presione ENTER..."); Console.ReadLine(); } }

IIC 1102 Página: 16

Page 18: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

3.3 Simulación de las Colas en un Supermercado En este ejemplo se muestra una simulación que modela las colas que se forman en las cajas de un supermercado. El desarrollo de este ejemplo es informal, en el sentido de que no se basa en formalismos teóricos para desarrollar el modelo.

3.3.1 Definición del Problema Un supermercado recibe una cantidad regular de clientes diariamente, los cuales traen consigo una lista de los productos que van a comprar. Los clientes buscan sus productos en los estantes y pasan de inmediato a la caja que más les convenga (en la que deban esperar menos en la fila). Una vez que han pagado se retiran del local.

Para determinar cuál es la caja más conveniente, los clientes miran las compras que llevan los clientes en la cola, y eligen aquella caja con menos productos delante de ellos (como es natural).

3.3.2 Características del Modelo El modelo de simulación que se empleará hace ciertas suposiciones sobre el comportamiento del sistema:

• Los clientes llegan al supermercado según una tasa regular todos los días, y siguiendo un comportamiento de compras también regular.

• Un cliente se demora un tiempo constante en ubicar cada uno de los productos que comprará.

• Las cajeras pasan por el lector de barras los productos a un ritmo constante, es decir, una determinada cantidad de productos por minuto.

• Una vez que un cliente elige una caja en la que hará fila, no se moverá a otra.

• Se considera despreciable el tiempo que le toma al cliente pagar por sus compras y recibir su vuelto.

• La unidad de tiempo discreto que se empleará en la simulación es equivalente a un minuto, descartando las tareas que puedan llevarse a cabo en fracciones restantes. Por ejemplo, si a un cajero le toma 10 segundos pasar los artículos de un cliente, el resto de ese minuto lo desperdiciará y no lo empleará atendiendo a otro cliente.

El modelo se centrará en la simulación del tiempo, ejecutando en cada unidad discreta de tiempo las actividades propias del supermercado y los clientes:

• Se verificará cuáles clientes han terminado de buscar sus productos y se les colocará en la fila de la caja.

• Cada cajera atenderá al primer cliente en la fila, y le pasará tantos productos como pueda en una unidad de tiempo.

3.3.3 Mediciones Requeridas Con fines estadísticos, es necesario guardar la visión que tuvo cada cliente al llegar a la caja, es decir, cuántos productos tienen los clientes que están delante de él, y cuántos son estos clientes. Esto se llevará a cabo en forma acumulativa con ayuda de la clase, de manera que sea posible obtener promedios al final de la simulación. Además, resulta valioso almacenar los valores máximos, tanto para el tiempo de espera como para el largo de cola en cada caja.

IIC 1102 Página: 17

Page 19: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

3.3.4 Solución • Los clientes del supermercado se representarán mediante una clase Cola, en donde cada

elemento corresponderá con un cliente. Para cada cliente se almacenará:

o Hora de llegada al supermercado.

o Cantidad de productos que pretende comprar (generado aleatoriamente).

hh:mm 1compras1

Orden de Llegada1º 4º

hh:mm 2compras2

hh:mm 3compras3

hh:mm 4compras4

Las cajas se representarán también como una clase, el cual ofrece en su interfaz funciones de mucha utilidad, como determinar la caja con menos productos para que un cliente se pueda ubicar en ella. El único dato que es necesario almacenar es la cantidad de productos que lleva cada uno de los clientes que hacen fila en las cajas.

compras1 compras2 comprasN

. . .Caja1

Caja2

compras1 compras2 comprasN

. . .

CajaN

compras1 compras2 comprasN

. . .

IIC 1102 Página: 18

Page 20: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

Por otra parte, será necesario llevar constancia del tiempo actual (hora), para saber en qué momento los clientes pasarán a las cajas y cómo irán evolucionando las colas al cumplirse cada unidad de tiempo.

De los resultados arrojados por estas estadísticas dependerán los posibles cambios de configuración que deban llevar a cabo los administradores del negocio. Por ejemplo, el aumento o disminución de cajas disponibles, la reubicación de los productos para que los clientes pasen menos tiempo ubicándolos, la capacitación de las cajeras para que pasen más productos por minuto por el lector de barras, etc.

Entradas del Programa

Los datos de los clientes se leen desde un archivo de entrada, llamado clientes.txt.

El archivo tiene un formato riguroso. En la primera línea se indica el número de clientes que concurrirá al supermercado en el día, seguido de una línea por cada uno de estos clientes.

Cada una de las líneas de clientes está compuesta por dos enteros que indican la hora de llegada al supermercado (hora y minutos).

A modo de ejemplo se incluye aquí un archivo de entrada, que considera 25 clientes.

25 10 01 10 05 10 05 10 05 10 05 10 05 10 05 10 07 10 08 10 08 10 10 10 12 10 15 10 20 10 22 10 22 10 22 10 22 10 22 10 22 10 35 10 45 10 50 10 50 10 55

El número de cajas que se desea emplear se pregunta como primer paso dentro del programa.

Desarrollo de la solución

Para esta solución, los objetos relevantes son:

- Cliente. Representado por una clase cuyos atributos son: la hora de llegada (de tipo DateTime) y la cantidad de compras (int). Estos valores son pasados como parámetros al constructor y adicionalmente se definen las propiedades que dan acceso a los dos atributos privados del objeto Cliente.

- Cajas. Un objeto más complejo, que maneja un arreglo de colas de caja y ofrece una serie de métodos que resuelven las preguntas más requeridas, como ¿cuál es la caja con la cola más corta? ¿cuántos productos hay en la caja N? … además de procesar cada cola en una unidad de tiempo de simulación.

IIC 1102 Página: 19

Page 21: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

- Estadística. Un objeto que guarda los valores numéricos que se van obteniendo por el proceso de atención de las cajas y que finalmente sirve para mostrar en pantalla los resultados estadísticos medidos durante la simulación.

- La cola de llegada de los clientes al supermercado se maneja como un objeto de tipo Queue y se incluye la lógica de inicialización de esta cola al leer los datos que vienen en el archivo de llegadas. El procesamiento de este archivo va creando objetos de tipo cliente, tomando la hora y minutos que indica la línea respectiva del archivo y también generando un número aleatorio de productos a comprar, por medio de la clase Random.

Código Fuente Solución using System; using System.IO; using System.Collections; class Cliente {

private DateTime dt; private int compras; public Cliente(int hora, int minuto) { dt = new DateTime(DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day,

hora,minuto,0,0); compras = 0; } public void Imprimir() { Console.WriteLine("Hora: {0} - compras: {1}",dt,compras); } public DateTime HoraRegistro { get { return dt; } } public bool registro_vacio {

get{ if(compras == 0) return true; else return false; } } public int registro_compra { get { return compras; } set { compras = value; } } } class Cajas { private int [,] cajas; private int num, max_caja; public Cajas(int num_cajas, int max_clientes_caja) { num = num_cajas; max_caja = max_clientes_caja; cajas = new int[num_cajas,max_clientes_caja]; } public void Insertar(int prod) { int i; for(i = 0; i < num && cajas[MejorCaja(),i] != 0; i++); cajas[MejorCaja(),i] = prod; } public int MejorCaja() { int cant_aux = 0, cant = Int32.MaxValue, mejor = 0; for(int i = 0; i < num; i++) { for(int j = 0; j < max_caja; j++) cant_aux += cajas[i,j]; if(cant_aux < cant) { mejor = i; cant = cant_aux;

IIC 1102 Página: 20

Page 22: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

} cant_aux = 0; } return mejor; } public int ProductosEnCaja(int caja) { int num_prod = 0; for(int i = 0; i < max_caja; i++) num_prod += cajas[caja,i]; return num_prod; } public int ColaCaja(int caja) { int num_clientes = 0; for(int i = 0; i < max_caja; i++) if(cajas[caja,i] != 0) num_clientes++; return num_clientes; } public int ProdsPrimerCliente(int caja) { return cajas[caja,0]; } public void Cobrar(int caja, int prod) { cajas[caja,0] -= prod; } public void SacarCaja(int caja) { for(int i = 1; i < max_caja; i++) cajas[caja,i-1] = cajas[caja,i]; } public bool QuedanClientes() { for(int i = 0; i < num; i++) for(int j = 0; j < max_caja; j++) if(cajas[i,j] > 0) return true; return false; } public void Imprimir() { for(int i = 0; i < num; i++) { Console.Write("\n\t Caja nº {0}: ",i); for(int j = 0; j < max_caja; j++) if(cajas[i,j] != 0) Console.WriteLine(" {0}",cajas[i,j]); } Console.WriteLine(""); } public void Atender() { int caja, cobrados; for( caja = 0; caja < num; caja++) { if(ProductosEnCaja(caja) > 0) { if(ProdsPrimerCliente(caja) < 3) cobrados = ProdsPrimerCliente(caja); else cobrados = 3; Cobrar(caja,cobrados); if(ProdsPrimerCliente(caja) == 0) SacarCaja(caja); } } } } class Estadistica { private int LargoTotal; private int LargoMax; public Estadistica() { LargoTotal = 0; LargoMax = 0; }

IIC 1102 Página: 21

Page 23: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

public int LargoT { get { return LargoTotal; } set { LargoTotal = value; } } public int LargoM { get { return LargoMax; } set { LargoMax = value; } } } class CMain { public static void Main() { DateTime dt = new DateTime(DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day,

9,0,0,0); int NumClientes = 0, EsperaTotal = 0, EsperaMax = 0; int cajas = 0; Console.WriteLine("SIMULACION DE SUPERMERCADO"); Console.Write("Indique la cantidad de cajas atendiendo: "); cajas = int.Parse(Console.ReadLine()); Queue Clientes = new Queue(); Cajas Cajas = new Cajas(cajas,10); Estadistica [] estadistica = new Estadistica[cajas]; for(int i = 0; i < Estadistica.Length; i++) estadistica[i] = new Estadistica(); try { StreamReader sr = new StreamReader("clientes.txt"); Console.WriteLine("Leyendo datos de entrada"); NumClientes = int.Parse(sr.ReadLine()); string str; System.Random rn = new System.Random(System.DateTime.Now.Millisecond); for(int i = 0; (str = sr.ReadLine()) != null; i++) { string[] hh_mm = str.Split(' '); Cliente cr = new Cliente (int.Parse(hh_mm[0]),

int.Parse(hh_mm[1])); cr.registro_compra = rn.Next(0,99); Clientes.Enqueue(cr); } sr.Close(); } catch(Exception e) { Console.WriteLine("No se abre archivo clientes.txt: {0}",e.Message); return; } while(Clientes.Count > 0 || Cajas.QuedanClientes()) { if(Clientes.Count == 0) break; CRegistro cli = (CRegistro)Clientes.Peek(); while(cli.HoraRegistro == dt) { int prodsCajas = Cajas.ProductosEnCaja(Cajas.MejorCaja()); int colaCaja = Cajas.ColaCaja(Cajas.MejorCaja()); EsperaTotal += prodsCajas; if(prodsCajas > EsperaMax) EsperaMax = prodsCajas; Estadistica[Cajas.MejorCaja()].LargoT += colaCaja; if(colaCaja > Estadistica[Cajas.MejorCaja()].LargoM) Estadistica[Cajas.MejorCaja()].LargoM = colaCaja; if(Clientes.Count == 0) break; cli = (CRegistro)Clientes.Dequeue(); Cajas.Insertar(cli.registro_compra); } Cajas.Atender();

IIC 1102 Página: 22

Page 24: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

DateTime d = dt.AddMinutes(1); dt = d; } Console.WriteLine("\n\n\t\t-=Estadistica=-\n\n"); int valor = (EsperaTotal / 3) / NumClientes; int min = valor; int seg = ((valor-min)*60); Console.WriteLine("\tTiempo de espera Promedio (mm:ss) -> {0}:{1}",min,seg); valor = (EsperaMax / 3); min = (int)valor; seg = (int) ((valor-min)*60); Console.WriteLine("\tTiempo de Espera Maximo (mm:ss) -> {0}:{1}",min,seg); Console.WriteLine("\tLargo de la Cola en las Cajas (Promedio/Maximo):"); for(int i=0 ; i<cajas ; i++) Console.WriteLine("\t\tCaja nº{0}: {1} / {2}",i,

Estadistica[i].LargoT,Estadistica[i].LargoM); Console.Write("Presione ENTER ..."); Console.ReadLine(); } }

Ejemplos de ejecución (varias configuraciones)

Con 1 caja: -=Estadistica=-

Tiempo de espera Promedio (mm:ss) -> 29:0 Tiempo de Espera Maximo (mm:ss) -> 52:0 Largo de la Cola en las Cajas (Promedio/Maximo): Caja nº0: 44 / 2

Con 2 cajas:

-=Estadistica=- Tiempo de espera Promedio (mm:ss) -> 29:0 Tiempo de Espera Maximo (mm:ss) -> 57:0 Largo de la Cola en las Cajas (Promedio/Maximo): Caja nº0: 6 / 2 Caja nº1: 50 / 3

Con 4 cajas:

-=Estadistica=- Tiempo de espera Promedio (mm:ss) -> 26:0 Tiempo de Espera Maximo (mm:ss) -> 46:0 Largo de la Cola en las Cajas (Promedio/Maximo): Caja nº0: 12 / 4 Caja nº1: 12 / 3 Caja nº2: 12 / 4 Caja nº3: 15 / 4

Modificaciones propuestas

IIC 1102 Página: 23

Page 25: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

Como se puede ver en los ejemplos de ejecución, la simulación arroja algunos valores estadísticos que pueden ser de utilidad para el administrador del supermercado: tiempos de espera de los clientes y largos de cola en las cajas. Sin embargo, la experimentación es aún algo engorrosa, pues cada vez que se quieren ver los resultados para una determinada configuración, es necesario ejecutar de nuevo el programa y registrar los resultados.

Una posible modificación al programa planteado es hacer que por sí mismo busque la mejor configuración, de acuerdo a parámetros dados por el usuario. Por ejemplo, ¿Cuántas cajas son necesarias para que los clientes no deban esperar más de 1 minuto?. Para lograr esto, el cuerpo de la simulación se debe convertir en un método o función que reciba como argumento el número de cajas y retorne el tiempo de espera promedio (actualmente se envía por la consola). El algoritmo principal (Main) hará llamados sucesivos a esta nueva función (mediante un ciclo), pasándole como argumento distintos valores para el número de cajas en forma incremental (primero 2, luego 3, etc.), hasta que se llegue al tiempo de espera propuesto por el usuario (1 minuto).

Otra característica que podría resultar muy útil es permitir la simulación por períodos distintos al día completo. Por ejemplo, es bien sabido que las horas de mayor saturación en el supermercado se dan al final de la tarde. Sería útil que el administrador del supermercado pudiera determinar cuántas cajas requiere para cada período del día en forma independiente. Actualmente los datos de las horas de muy alta y muy baja afluencia están alterando los promedios arrojados. Para lograr esto el programa debería pedir un rango de horas y ejecutar la simulación únicamente con los datos de entrada que correspondan con el rango especificado. Además, dependiendo de la hora del día el número de productos que llevan los clientes podría variar. Para lograr esto bastaría con cambiar la generación aleatoria de la cantidad de productos para que dependiera de la hora en la que se está comprando.

Finalmente, podría ser interesante lograr que la hora de llegada de los clientes se genere en forma aleatoria, de modo que podamos suprimir el archivo de entrada y lo único que deba dar el usuario es el número de clientes y la cantidad de cajas que deberán emplearse para la simulación.

La planificación y la implementación de estas modificaciones se dejan como ejercicio al estudiante.

3.4 Simulación de una Plaza de Peaje Este ejemplo en particular se presentó como trabajo personal dentro de un curso. Cada alumno, contando sólo con ejemplos como los anteriores y la explicación que se indica a continuación.

Este ejemplo se centra en implementar una plaza de peaje de la carretera, donde se tienen distintas casetas abiertas para atención y en el tiempo van llegando autos a ser atendidos.

Una plaza de peaje está compuesta de distintas casetas que atienden a los autos que llegan por cada lado de la carretera. Los autos deben pagar una tarifa que depende de la hora, y según esa tarifa, la tasa de atención de la caseta puede aumentar o disminuir.

El propósito del programa es determinar la cantidad óptima de casetas abiertas y atendiendo para dar un servicio adecuado a los vehículos al menor costo.

Esta particularidad le impone un factor especial al ejemplo, ya que más que sólo ejecutar una simulación del funcionamiento de la plaza de peaje, se toman los datos obtenidos de una simulación completa y se usan para cambiar los parámetros que determinan el escenario de la siguiente simulación (en particular la cantidad de casetas abiertas). De tal manera, se evalúan diferentes escenarios y se determina cuál de ellos ofrece la mejor relación costo/ingreso. Este proceso informal de optimización se refleja en el algoritmo principal (Main).

3.4.1 Definición del Problema En detalle el funcionamiento de la simulación considera lo siguiente:

IIC 1102 Página: 24

Page 26: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

3.4.1.1 El Tiempo de Simulación

• El periodo a simular consta de dos horas, desde las 17:00 a las 19:00 de un día viernes. • Cada unidad de tiempo de simulación es de 1 minuto. • A las 18:00 - la mitad del tiempo de simulación - se cambia la tarifa de peaje, con lo cual también

cambia la tasa de atención. Estos dos valores se explican más adelante.

3.4.1.2 Las Casetas

• Hay un total de 20 casetas construidas, de las cuales en una simulación dada, el total de ellas o sólo una parte estarán atendiendo (al menos dos casetas siempre, una para cada dirección).

• De las abiertas, la mitad está atendiendo a los autos que llegan por el sur y las otras a los que llegan por el norte. La cantidad de casetas que atienden a cada lado también es fijo para cada simulación, pero es el parámetro a ir ajustando para determinar la cantidad óptima.

• El costo fijo de atención por caseta es de $50.000 por cada periodo de simulación, lo que permite calcular los costos.

• En cada caseta siempre habrá una cola que tiene 0 ó más autos. • Cada auto que llegue a la plaza de peaje, por cualquier dirección, seleccionará la caseta cuya

cola sea la más corta, o bien la primera si todas son iguales. • Tarifa de peaje: en la primera hora la tarifa es de $1.200 por vehículo, y en la segunda hora es de

$2.000. • La tasa de atención en la caseta es de:

o 2 autos por minuto cuando la tarifa es baja (ya que se cuenta el tiempo para dar vuelto en monedas).

o 4 autos por minuto cuando la tarifa es alta (ya que no se requiere dar vuelto en monedas).

o En cualquiera de los dos casos se atenderá a la cantidad de autos correspondiente a la tasa del horario actual, y si quedan menos autos, sólo se atenderá a los que haya.

3.4.1.3 Los Vehículos

• Existe un registro de los autos que llegan por el sur y por el norte respectivamente, identificando la hora (en hh y mm) y la cantidad de autos que llegan en ese minuto.

• Los del norte vienen en el archivo norte.txt y los del sur en sur.txt. Estos archivos asumen conocidos y para este ejemplo se pueden inventar datos.

• En cada archivo se registra una línea por minuto de datos, la cual tiene en orden: hh mm cantidadautos.

• Si en un minuto dado no se registraron autos (cantidadautos=0), esa línea no viene en el archivo. • En la corrección de la tarea se pueden utilizar otros archivos, por lo que no asuma que esos

serán siempre los archivos.

3.4.1.4 El Proceso de Optimización

El proceso de optimización no se enfoca en las técnicas formales de optimización matemática, ya que ese enfoque no forma parte de este documento. Sin embargo, se busca lograr un punto denominad óptimo por medio de la evaluación de los resultados tomando distintos escenarios de simulación. Al comparar progresivamente los escenarios en torno a los costos e ingresos, se puede llegar a una combinación ideal de casetas abiertas que logren un nivel aceptable de tasa de atención por vehículo.

Para ello, el procedimiento (algoritmo) es el siguiente:

• Se comienza con el mínimo: 1 caseta abierta para los vehículos del norte y 1 para los del sur. • Se efectúa la simulación completa y se miden los siguientes datos que deben mostrarse en

pantalla.

IIC 1102 Página: 25

Page 27: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

o Cantidad de cajas abiertas por cada lado. o Cantidad de autos atendidos por cada lado. o $ ingreso (cobro de peaje). o $ costos (casetas x costo fijo). o Máxima espera en minutos.

• Se aumenta en uno la cantidad de casetas abiertas por cada lado y se vuelve a simular. • Las condiciones de término del proceso de optimización (que a su vez ejecuta varias

simulaciones) son: o El Tiempo Máximo de espera por atención debe ser menor que un valor en minutos dado

por el usuario al comienzo de todo el proceso. o Se analiza si la utilidad (ingresos-costos) disminuye o aumenta. Dentro de la restricción

de Tiempo de Espera Máxima, se busca el menor costo posible (el mínimo de casetas abiertas).

o El máximo de casetas es el de la cantidad construida: 20 en total (10 para cada lado).

3.4.2 Solución Código Fuente using System; using System.IO; using System.Collections; //------------------------------------------------------------------------------------ // Clase: Auto // Representa un auto cuyos datos relevantes son únicamente los de la hora de llegada //------------------------------------------------------------------------------------ class Auto { DateTime horallegada; // Atributo relevante: la hora de llegada. public Auto(int hh, int mm) { // Transforma la hora y minutos de llegada en un tipo DateTime horallegada = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, hh, mm, 0, 0); } public DateTime HoraLlegada { get { return(horallegada); } } public int Hora { get { return(horallegada.Hour); } } public int Minutos { get { return(horallegada.Minute); } } // Al imprimir una instancia de Auto, se imprime la hora de llegada public override string ToString() { return(horallegada.ToString()); } } //------------------------------------------------------------------------------------ // Clase: Caseta // Hereda de Queue, por lo cual la misma caseta representa una cola de vehículos que // se atienden en dicha caseta. Además, registra el tiempo máximo de espera durante // toda la operación de la caseta, contabiliza los autos atendidos, y va sumando // el cobro de peajes según tarifa por auto atendido. //------------------------------------------------------------------------------------ class Caseta : Queue { int maxespera = 0; int procesados = 0; int ingresos = 0; // AtenderPrimero(): toma al primero de la cola, y si está en la hora adecuada // lo atiende, registrando su tiempo de espera y contabilizándolo public int AtenderPrimero(DateTime lahora, int valorpeaje) { if(Count<=0) return(-1); // Si no hay autos en cola, no se atiende a nadie. Auto a = (Auto) Peek(); // Se mira el primero de la cola

IIC 1102 Página: 26

Page 28: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

if( a.HoraLlegada<=lahora ) {// Si llegó antes de la hora actual TimeSpan ts = lahora - a.HoraLlegada; // Tiempo de espera Dequeue(); // Se saca de la cola procesados++; // Se contabiliza ingresos += valorpeaje; // Suma el pago por el peaje al total acum. return(ts.Hours*60 + ts.Minutes); // Retorna el valor total de minutos } return(-1); // Si no se atendió ninguno, retorna <0 para no contabilizar. } // Dos versiones para Agregar Auto a la cola (Queue) de la caseta. public void AgregarAuto(int hh, int mm) { Enqueue((Object) new Auto(hh,mm)); } public void AgregarAuto(Auto a) { Enqueue((Object) a); } // Propiedades de Caseta public int CantidadAutos { get { return(Count); } } public int AutosProcesados { get { return(procesados); } } public int Ingresos { get { return(ingresos); } } public int MaxEspera { get { return(maxespera); } set { if(value>maxespera) maxespera = value; } } // PrimerAuto: revisa el primer auto sin sacarlo de la cola public Auto PrimerAuto { get { return( (Auto) Peek()); } } } //------------------------------------------------------------------------------------ // Clase: Plaza // Representa una colección de casetas o plaza de peaje, atendiendo DIR colas de // autos que llegan. Si bien el ejemplo habla de dos extremos por los que llegan // autos, se maneja un átributo DIR que representa la cantidad de extremos en forma // genérica, permitiendo al ejemplo el potencial de ser extendido. // El valor de casetasenuso se maneja referenciando una única dirección. Si se abren // dos casetas por cada dirección, entonces ese valor es 2, totalizando 4 casetas abiertas. //------------------------------------------------------------------------------------ class Plaza { const int DIR = 2; // Dos direcciones: Norte y Sur Caseta[,] casetas; // Matriz de casetas. N casetas por M direcciones (2 dir: N y S). int casetasenuso; // Constructor, prepara la plaza indicando cuántas casetas se utilizarán. // No requiere validar un máximo de casetas en uso, ya que es indiferente a este nivel public Plaza(int enuso) { casetas = new Caseta[enuso,DIR]; // Dimensiona la matriz de casetas for(int dir=0; dir<DIR; dir++) for(int i=0; i<casetas.GetLength(0); i++) casetas[i,dir] = new Caseta(); // Instancia c/celda de la matriz. casetasenuso = enuso; } // MejorCaseta(): según la dirección dada (0: norte; 1: sur) // : indica cuál es la caseta con la fila más corta public Caseta MejorCaseta(int direccion) { int mincola = casetas[0,direccion].CantidadAutos; int mincaseta = 0; for(int i=0; i<casetasenuso; i++) if( mincola > casetas[i,direccion].CantidadAutos ) { mincola = casetas[i,direccion].CantidadAutos; mincaseta = i; } return( casetas[mincaseta,direccion] ); // Retorna la caseta elegida. } public int CasetasEnuso { get { return(casetasenuso); } set { if( value >= 1 ) casetasenuso = value; } // Mínimo de 1 caseta } // ProcesarMinuto(): atiende autos en las casetas que alcanzan en el minuto actual,

IIC 1102 Página: 27

Page 29: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

// : de acuerdo a tasa dada, tomando valor del peaje en ese minuto. public void ProcesarMinuto(DateTime lahora, int tasa, int valorpeaje) { for(int dir=0; dir<DIR; dir++) // Para ambas direcciones (norte y sur). for(int i=0; i<casetasenuso; i++) // Para todas las casetas abiertas. for(int j=0; j<tasa; j++) // Los autos que alcanzan en un min. if(casetas[i,dir].CantidadAutos>0) { // Calcula espera del atendido. Si no hay nadie en la cola // no se atiende a nadie, la espera es -1,

// que no es asignada a MaxEspera. // Validaciones están en AtenderPrimero() y de MaxEspera. int espera = casetas[i,dir].AtenderPrimero(lahora, valorpeaje); casetas[i,dir].MaxEspera = espera; } } // EsperaMax: Calcula la Máxima espera registrada en las cajas. public int EsperaMax { get { int max=0; for(int dir=0; dir<DIR; dir++) for(int i=0; i<casetasenuso; i++) if(max<casetas[i,dir].MaxEspera) max = casetas[i,dir].MaxEspera; return(max); } } public int TotalIngresos { get { int total = 0; for(int dir=0; dir<DIR; dir++) for(int i=0; i<casetasenuso; i++) total += casetas[i,dir].Ingresos; return(total); } } public int TotalAutos { get { int total = 0; for(int dir=0; dir<DIR; dir++) for(int i=0; i<casetasenuso; i++) total += casetas[i,dir].AutosProcesados; return(total); } } public int AutosEnCola { get { int total = 0; for(int dir=0; dir<DIR; dir++) for(int i=0; i<casetasenuso; i++) total += casetas[i,dir].CantidadAutos; return(total); } } public void Encabezado() { for(int dir=0; dir<DIR; dir++) for(int i=0; i<casetasenuso; i++) Console.Write("{0}.{1} ", dir+1, i+1); Console.WriteLine(); } public void MostrarResumen() { for(int dir=0; dir<DIR; dir++) for(int i=0; i<casetasenuso; i++) Console.Write("{0,3} ", casetas[i,dir].CantidadAutos); Console.WriteLine(); } }

IIC 1102 Página: 28

Page 30: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

//------------------------------------------------------------------------------------ // Clase: ColaLlegada // Representa la cola de autos de llegada por una dirección específica. //------------------------------------------------------------------------------------ class ColaLlegada : Queue { StreamReader sr; // Constructor: Abre archivo. Lee todos registrándolos en una cola de autos de llegada public ColaLlegada(string filename) { try { sr = new StreamReader(filename); } catch(Exception e) {

Console.WriteLine("Error al abrir {0}\n{1}", filename, e.ToString()); return; }

string linea = sr.ReadLine(); int contador = 0; while(linea!=null) { // Procesa el archivo completo contador++; string[] datos = linea.Split(); if(datos.Length != 3) { // Si no vienen 3 datos, avisa y termina el proceso Console.WriteLine("Error en formato del archivo de entrada:”

+ “línea Nº {0} no tiene 3 datos", contador); sr.Close(); return; } int cant = int.Parse(datos[2]); // Lee cantidad de autos en min. en proceso for(int i=0; i<cant; i++) // Registra 1 elem. x c/auto en el min. en proc. Enqueue( (Object) new Auto(int.Parse(datos[0]),

int.Parse(datos[1]))); linea = sr.ReadLine(); } sr.Close(); // Se cierra el archivo con datos. } // Propiedades básicas de la Cola de Llegada --> Se basan en los métodos de Queue public Auto PrimerAuto { get { return( (Auto) Peek()); } } public int CantidadAutos { get { return(Count); } } // Métodos públicos de la Cola de Llegada public void SacarPrimerAuto() { if(Count>0) Dequeue(); } } //------------------------------------------------------------------------------------ // Clase: SimuladorPlaza // Se encarga de hacer una simulación completa en un escenario dado por // las colas de los autos en llegada y de una cantidad determinada de casetas abiertas //------------------------------------------------------------------------------------ class SimuladorPlaza { Plaza p; ColaLlegada c1; ColaLlegada c2; const int TARIFA1 = 1200; const int TARIFA2 = 2000; const int TASA1 = 2; const int TASA2 = 4; const int COSTO = 50000; public SimuladorPlaza(string file1, string file2, int casetas) { p = new Plaza(casetas); c1 = new ColaLlegada(file1); c2 = new ColaLlegada(file2); } // Procesar(): Método principal de la clase, que realiza (ejecuta) la simulación public void Procesar() { // Se procesa el loop de simulación principal DateTime HoraActual = new DateTime(DateTime.Now.Year, DateTime.Now.Month,

IIC 1102 Página: 29

Page 31: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

DateTime.Now.Day, 17, 0, 0, 0); DateTime HoraCambio = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 18, 0, 0, 0); DateTime HoraFinal = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 19, 0, 0, 0); TimeSpan UnTick = new TimeSpan(0,1,0); // Para ver en pantalla avance del proceso: Console.Write("Llegan "); p.Encabezado(); while( HoraActual<=HoraFinal ) { // Console.WriteLine(HoraActual); // Procesa los autos de la hora de llegada actual -> Norte int llegaron1 = 0; int llegaron2 = 0; while( (c1.CantidadAutos>0) && (c1.PrimerAuto.HoraLlegada<=HoraActual) ) { Caseta cas = p.MejorCaseta(0); cas.AgregarAuto(c1.PrimerAuto); c1.SacarPrimerAuto(); llegaron1++; } // Procesa los autos de la hora de llegada actual -> Sur while( (c2.CantidadAutos>0) && (c2.PrimerAuto.HoraLlegada<=HoraActual) ) { Caseta cas = p.MejorCaseta(1); cas.AgregarAuto(c2.PrimerAuto); c2.SacarPrimerAuto(); llegaron2++; } // Ahora procesa las colas int tasa = TASA2; int tarifa = TARIFA2; if( HoraActual < HoraCambio ) { tasa = TASA1; tarifa = TARIFA1; } // Console.Write("{0,2} {1,2} ", llegaron1, llegaron2); // p.MostrarResumen(); // OJO: En simulación larga esto muestra demasiada info p.ProcesarMinuto(HoraActual, tasa, tarifa); // Console.Write(" ", llegaron1, llegaron2); // p.MostrarResumen(); // OJO: En simulación larga esto muestra demasiada info HoraActual += UnTick; // Aumenta en un instante de simulación } } public int Costos { get { return(COSTO*p.CasetasEnuso*2); } } public int Ingresos { get { return(p.TotalIngresos); } } public int Resultado { get { return(Ingresos - Costos); } } public int MaxEspera { get { return(p.EsperaMax); } } public int AutosAtendidos { get { return(p.TotalAutos); } } } class CMain { public static void Main() { int casetasenuso = 0; int resultado = 0; Console.Write("Ingrese tiempo de espera máximo razonable en minutos: "); int esperamax = int.Parse(Console.ReadLine()); int espera = 0; int minespera = 100; int optimocasetas = 2; int maxresultado = 0; // Loop principal: realiza simulaciones y tiene la lógica de optimización. // En cada iteración aumenta la cantidad de casetas en uso.

// Ojo que se maneja un número de casetas por lado. // Los datos resultantes de cada simulación de los pregunta al SimuladorPlaza. do { casetasenuso++; // Cantidad de casetas abiertas por lado SimuladorPlaza sp =

new SimuladorPlaza("norte.txt","sur.txt", casetasenuso); Console.WriteLine("\n==============================”);

IIC 1102 Página: 30

Page 32: Simulación Computacional con C# - R: · PDF fileSimulación Computacional con C# Rodrigo Sandoval U. 2 Modelo de Simulación 2.1 Parámetros de la Simulación En estos modelos es

Simulación Computacional con C# Rodrigo Sandoval U.

Console.WriteLine("Nueva Simulación\n=============================="); sp.Procesar(); resultado = sp.Resultado; espera = sp.MaxEspera; // Se imprimen en pantalla los datos pedidos: Console.WriteLine("\nResultados de la Simulación”);

Console.WriteLine("=============================="); Console.WriteLine("Casetas : {0}\nAutos Atendidos: {1}\nMáx. Espera: {2}",

casetasenuso*2, sp.AutosAtendidos, espera); Console.WriteLine("Ingresos: {0:C}\nCostos: -{1:C}\nResultado: {2:C}", sp.Ingresos, sp.Costos, resultado); // Registra el punto con espera menor que el mínimo dado. // Dado que siempre será el de menor cantidad de casetas abiertas // este punto también es el de mayores ingresos. if( espera<=esperamax ) { minespera = espera; optimocasetas = casetasenuso; maxresultado = resultado; break; } } while(casetasenuso<10); Console.WriteLine("\nEl punto Optimo”);

Console.WriteLine(“==========================\n”); Console.WriteLine(“Casetas: {0} - Resultado: {1:C}", optimocasetas*2, resultado);

Console.Write("Presione ENTER ..."); Console.ReadLine(); } }

IIC 1102 Página: 31