SlideShare una empresa de Scribd logo
1 de 32
Descargar para leer sin conexión
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, (rsandova@ing.puc.cl)
basado en los apuntes de clase del curso IIC1102, año 2003, de M. Nussbaum, Marcos Sepúlveda, et.al.
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 1
compras1
Orden de Llegada1º 4º
hh:mm 2
compras2
hh:mm 3
compras3
hh:mm 4
compras4
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
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
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
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("nt 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
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
Simulación Computacional con C# Rodrigo Sandoval U.
DateTime d = dt.AddMinutes(1);
dt = d;
}
Console.WriteLine("nntt-=Estadistica=-nn");
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("ttCaja 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
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
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
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
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
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
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
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
Simulación Computacional con C# Rodrigo Sandoval U.
Console.WriteLine("Nueva Simulaciónn==============================");
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

Más contenido relacionado

Destacado

Cuba.Disidentes 2
Cuba.Disidentes 2Cuba.Disidentes 2
Cuba.Disidentes 2posei2
 
Benefits of implementing_the_primary_care_pcmh
Benefits of implementing_the_primary_care_pcmhBenefits of implementing_the_primary_care_pcmh
Benefits of implementing_the_primary_care_pcmhVicki Harter
 
Partes del computador
Partes  del computadorPartes  del computador
Partes del computadorJakelin Yanez
 
Harley Sheffield Professional Persona Project
Harley Sheffield Professional Persona ProjectHarley Sheffield Professional Persona Project
Harley Sheffield Professional Persona ProjectHarley Sheffield
 
Cambios y Preocupaciones
Cambios y PreocupacionesCambios y Preocupaciones
Cambios y Preocupacionesezecal
 
Future of Communications & Collaboration for Businesses
Future of Communications & Collaboration for BusinessesFuture of Communications & Collaboration for Businesses
Future of Communications & Collaboration for BusinessesFreedom Communications
 
o uso das novas tecnologias da informação no ensino a distância
o uso das novas tecnologias da informação no ensino a distânciao uso das novas tecnologias da informação no ensino a distância
o uso das novas tecnologias da informação no ensino a distânciaCristóvão Silva
 
Augmented Reality - Blair MacIntyre
Augmented Reality - Blair MacIntyreAugmented Reality - Blair MacIntyre
Augmented Reality - Blair MacIntyreWorld Economic Forum
 
Realization of high order iir digital bandstop filter using domain transfer a...
Realization of high order iir digital bandstop filter using domain transfer a...Realization of high order iir digital bandstop filter using domain transfer a...
Realization of high order iir digital bandstop filter using domain transfer a...Subhadeep Chakraborty
 
Folleto ohsa 3173
Folleto ohsa 3173Folleto ohsa 3173
Folleto ohsa 3173Mafe Mafer
 
Developing A Technology Plan For Higher Education
Developing A Technology Plan For Higher EducationDeveloping A Technology Plan For Higher Education
Developing A Technology Plan For Higher Educationrandywald
 
Undergraduate downloads...A guide to neurological examination
Undergraduate downloads...A guide to neurological examinationUndergraduate downloads...A guide to neurological examination
Undergraduate downloads...A guide to neurological examinationProfessor Yasser Metwally
 
Five critical strategies to succeed in your product management career
Five critical strategies to succeed in your product management careerFive critical strategies to succeed in your product management career
Five critical strategies to succeed in your product management careerAIPMM Administration
 
Facebook presentation final
Facebook presentation finalFacebook presentation final
Facebook presentation finalJosh Kim
 
Professor Paul Resnick at Vircomm14 – 'Motivating Contribution: 5 theories an...
Professor Paul Resnick at Vircomm14 – 'Motivating Contribution: 5 theories an...Professor Paul Resnick at Vircomm14 – 'Motivating Contribution: 5 theories an...
Professor Paul Resnick at Vircomm14 – 'Motivating Contribution: 5 theories an...FeverBee Limited
 
Unit 4: Economics Essay
Unit 4: Economics EssayUnit 4: Economics Essay
Unit 4: Economics Essaymattbentley34
 

Destacado (20)

Cuba.Disidentes 2
Cuba.Disidentes 2Cuba.Disidentes 2
Cuba.Disidentes 2
 
Benefits of implementing_the_primary_care_pcmh
Benefits of implementing_the_primary_care_pcmhBenefits of implementing_the_primary_care_pcmh
Benefits of implementing_the_primary_care_pcmh
 
Partes del computador
Partes  del computadorPartes  del computador
Partes del computador
 
Harley Sheffield Professional Persona Project
Harley Sheffield Professional Persona ProjectHarley Sheffield Professional Persona Project
Harley Sheffield Professional Persona Project
 
Cambios y Preocupaciones
Cambios y PreocupacionesCambios y Preocupaciones
Cambios y Preocupaciones
 
110731 the big ten 03 the right image
110731 the big ten 03 the right image110731 the big ten 03 the right image
110731 the big ten 03 the right image
 
Future of Communications & Collaboration for Businesses
Future of Communications & Collaboration for BusinessesFuture of Communications & Collaboration for Businesses
Future of Communications & Collaboration for Businesses
 
Ea em 1970
Ea em 1970Ea em 1970
Ea em 1970
 
o uso das novas tecnologias da informação no ensino a distância
o uso das novas tecnologias da informação no ensino a distânciao uso das novas tecnologias da informação no ensino a distância
o uso das novas tecnologias da informação no ensino a distância
 
Augmented Reality - Blair MacIntyre
Augmented Reality - Blair MacIntyreAugmented Reality - Blair MacIntyre
Augmented Reality - Blair MacIntyre
 
Realization of high order iir digital bandstop filter using domain transfer a...
Realization of high order iir digital bandstop filter using domain transfer a...Realization of high order iir digital bandstop filter using domain transfer a...
Realization of high order iir digital bandstop filter using domain transfer a...
 
Folleto ohsa 3173
Folleto ohsa 3173Folleto ohsa 3173
Folleto ohsa 3173
 
Developing A Technology Plan For Higher Education
Developing A Technology Plan For Higher EducationDeveloping A Technology Plan For Higher Education
Developing A Technology Plan For Higher Education
 
Historia y partes
Historia y partesHistoria y partes
Historia y partes
 
Undergraduate downloads...A guide to neurological examination
Undergraduate downloads...A guide to neurological examinationUndergraduate downloads...A guide to neurological examination
Undergraduate downloads...A guide to neurological examination
 
Property Division
Property DivisionProperty Division
Property Division
 
Five critical strategies to succeed in your product management career
Five critical strategies to succeed in your product management careerFive critical strategies to succeed in your product management career
Five critical strategies to succeed in your product management career
 
Facebook presentation final
Facebook presentation finalFacebook presentation final
Facebook presentation final
 
Professor Paul Resnick at Vircomm14 – 'Motivating Contribution: 5 theories an...
Professor Paul Resnick at Vircomm14 – 'Motivating Contribution: 5 theories an...Professor Paul Resnick at Vircomm14 – 'Motivating Contribution: 5 theories an...
Professor Paul Resnick at Vircomm14 – 'Motivating Contribution: 5 theories an...
 
Unit 4: Economics Essay
Unit 4: Economics EssayUnit 4: Economics Essay
Unit 4: Economics Essay
 

Similar a Simulacioncsharp

Taller # 3 Modelos de Colas y Simulación”.pdf
Taller # 3 Modelos de Colas y Simulación”.pdfTaller # 3 Modelos de Colas y Simulación”.pdf
Taller # 3 Modelos de Colas y Simulación”.pdfJuanPabloPea19
 
Lenguajes de simulacion
Lenguajes de simulacionLenguajes de simulacion
Lenguajes de simulacionAnel Sosa
 
Unidad i simulacion
Unidad i simulacionUnidad i simulacion
Unidad i simulacionneferh22
 
Introducción a la Simulación2.pptx
Introducción a la Simulación2.pptxIntroducción a la Simulación2.pptx
Introducción a la Simulación2.pptxJearvaviVzquez
 
Dialnet aplicacion delasimulacionmontecarloenelcalculodelri-4835801
Dialnet aplicacion delasimulacionmontecarloenelcalculodelri-4835801Dialnet aplicacion delasimulacionmontecarloenelcalculodelri-4835801
Dialnet aplicacion delasimulacionmontecarloenelcalculodelri-4835801luis Farro
 
Dialnet aplicacion delasimulacionmontecarloenelcalculodelri-4835801
Dialnet aplicacion delasimulacionmontecarloenelcalculodelri-4835801Dialnet aplicacion delasimulacionmontecarloenelcalculodelri-4835801
Dialnet aplicacion delasimulacionmontecarloenelcalculodelri-4835801luis Farro
 
Simulación de sistemas
Simulación de sistemasSimulación de sistemas
Simulación de sistemasjack_corvil
 
1. Fundamentación General de la simulación de sistemas.pdf
1. Fundamentación General de la simulación de sistemas.pdf1. Fundamentación General de la simulación de sistemas.pdf
1. Fundamentación General de la simulación de sistemas.pdfhectorrosales52
 
1.2 definiciòn de simulaciòn exposicion
1.2 definiciòn de simulaciòn   exposicion1.2 definiciòn de simulaciòn   exposicion
1.2 definiciòn de simulaciòn exposicionJose Hernandez Landa
 
1.2 Definición de simulación
1.2 Definición de simulación   1.2 Definición de simulación
1.2 Definición de simulación avengers92
 
Concepto básico de programación (1)
Concepto básico de programación  (1)Concepto básico de programación  (1)
Concepto básico de programación (1)LauraSofia53
 
Martha navarrete metodos deterministicos
Martha navarrete metodos deterministicos Martha navarrete metodos deterministicos
Martha navarrete metodos deterministicos MarthaISABEL18
 
Sistemas de simulacion
Sistemas de simulacionSistemas de simulacion
Sistemas de simulacionCamilo Muñoz
 

Similar a Simulacioncsharp (20)

Taller # 3 Modelos de Colas y Simulación”.pdf
Taller # 3 Modelos de Colas y Simulación”.pdfTaller # 3 Modelos de Colas y Simulación”.pdf
Taller # 3 Modelos de Colas y Simulación”.pdf
 
paso4.docx
paso4.docxpaso4.docx
paso4.docx
 
Lenguajes de simulacion
Lenguajes de simulacionLenguajes de simulacion
Lenguajes de simulacion
 
Unidad i simulacion
Unidad i simulacionUnidad i simulacion
Unidad i simulacion
 
Simulación de procesos
Simulación de procesosSimulación de procesos
Simulación de procesos
 
simulacion-compartido.pdf
simulacion-compartido.pdfsimulacion-compartido.pdf
simulacion-compartido.pdf
 
Introducción a la Simulación2.pptx
Introducción a la Simulación2.pptxIntroducción a la Simulación2.pptx
Introducción a la Simulación2.pptx
 
Dialnet aplicacion delasimulacionmontecarloenelcalculodelri-4835801
Dialnet aplicacion delasimulacionmontecarloenelcalculodelri-4835801Dialnet aplicacion delasimulacionmontecarloenelcalculodelri-4835801
Dialnet aplicacion delasimulacionmontecarloenelcalculodelri-4835801
 
Dialnet aplicacion delasimulacionmontecarloenelcalculodelri-4835801
Dialnet aplicacion delasimulacionmontecarloenelcalculodelri-4835801Dialnet aplicacion delasimulacionmontecarloenelcalculodelri-4835801
Dialnet aplicacion delasimulacionmontecarloenelcalculodelri-4835801
 
SIMUago-dic23.pptx
SIMUago-dic23.pptxSIMUago-dic23.pptx
SIMUago-dic23.pptx
 
Simulación de sistemas
Simulación de sistemasSimulación de sistemas
Simulación de sistemas
 
taller 3 parte 1.docx
taller 3 parte 1.docxtaller 3 parte 1.docx
taller 3 parte 1.docx
 
1. Fundamentación General de la simulación de sistemas.pdf
1. Fundamentación General de la simulación de sistemas.pdf1. Fundamentación General de la simulación de sistemas.pdf
1. Fundamentación General de la simulación de sistemas.pdf
 
1.2 definiciòn de simulaciòn exposicion
1.2 definiciòn de simulaciòn   exposicion1.2 definiciòn de simulaciòn   exposicion
1.2 definiciòn de simulaciòn exposicion
 
1.2 Definición de simulación
1.2 Definición de simulación   1.2 Definición de simulación
1.2 Definición de simulación
 
Capítulo viii simulacion montecarlo
Capítulo viii simulacion montecarloCapítulo viii simulacion montecarlo
Capítulo viii simulacion montecarlo
 
Concepto básico de programación (1)
Concepto básico de programación  (1)Concepto básico de programación  (1)
Concepto básico de programación (1)
 
Martha navarrete metodos deterministicos
Martha navarrete metodos deterministicos Martha navarrete metodos deterministicos
Martha navarrete metodos deterministicos
 
337 lectura6.3.1
337 lectura6.3.1337 lectura6.3.1
337 lectura6.3.1
 
Sistemas de simulacion
Sistemas de simulacionSistemas de simulacion
Sistemas de simulacion
 

Más de Simar Leaño Prieto

Más de Simar Leaño Prieto (9)

Despido por causas legales
Despido por causas legalesDespido por causas legales
Despido por causas legales
 
Produccion y utilizacion de insumos
Produccion y utilizacion de insumosProduccion y utilizacion de insumos
Produccion y utilizacion de insumos
 
168315310 plan-de-negocios-minimarket
168315310 plan-de-negocios-minimarket168315310 plan-de-negocios-minimarket
168315310 plan-de-negocios-minimarket
 
59563233 algoritmo-bresenham
59563233 algoritmo-bresenham59563233 algoritmo-bresenham
59563233 algoritmo-bresenham
 
Apunte clase
Apunte claseApunte clase
Apunte clase
 
Proceso de-desarrollo-software
Proceso de-desarrollo-softwareProceso de-desarrollo-software
Proceso de-desarrollo-software
 
Cocomo2 apuntes
Cocomo2 apuntesCocomo2 apuntes
Cocomo2 apuntes
 
Tesis con rup
Tesis con rupTesis con rup
Tesis con rup
 
Ejercicios prolog
Ejercicios prologEjercicios prolog
Ejercicios prolog
 

Último

ORIENTACIONES DE INFORMÁTICA-2024.pdf-guia
ORIENTACIONES DE INFORMÁTICA-2024.pdf-guiaORIENTACIONES DE INFORMÁTICA-2024.pdf-guia
ORIENTACIONES DE INFORMÁTICA-2024.pdf-guiaYeimys Ch
 
BLOG, EXCEL AVANZADO, MÉTODOS ESTADÍSTICOS..docx
BLOG, EXCEL AVANZADO, MÉTODOS ESTADÍSTICOS..docxBLOG, EXCEL AVANZADO, MÉTODOS ESTADÍSTICOS..docx
BLOG, EXCEL AVANZADO, MÉTODOS ESTADÍSTICOS..docxhellendiaz12
 
Cold Dyeing BROWN Shade, room temperature dyeing
Cold Dyeing BROWN Shade, room temperature dyeingCold Dyeing BROWN Shade, room temperature dyeing
Cold Dyeing BROWN Shade, room temperature dyeingCHEMPRO
 
carta combinada para tecnología de sara Garzón
carta combinada para tecnología de sara Garzóncarta combinada para tecnología de sara Garzón
carta combinada para tecnología de sara GarzónSaraGarzon13
 
#Tare10ProgramacionWeb2024aaaaaaaaaaaa.pptx
#Tare10ProgramacionWeb2024aaaaaaaaaaaa.pptx#Tare10ProgramacionWeb2024aaaaaaaaaaaa.pptx
#Tare10ProgramacionWeb2024aaaaaaaaaaaa.pptxHugoGutierrez99
 
tecnologia11-6 Juan Sebastián Gonzalez liceo
tecnologia11-6 Juan Sebastián Gonzalez liceotecnologia11-6 Juan Sebastián Gonzalez liceo
tecnologia11-6 Juan Sebastián Gonzalez liceoSebastinOrdez4
 
tecnologia116.docx TRABAJO COLABORTIVO PRIMNER
tecnologia116.docx TRABAJO COLABORTIVO PRIMNERtecnologia116.docx TRABAJO COLABORTIVO PRIMNER
tecnologia116.docx TRABAJO COLABORTIVO PRIMNERedepmariaordonez
 
LA ELECTRICIDAD Y LA ELECTRÓNICA TRABAJO EN GRUPO
LA ELECTRICIDAD Y LA ELECTRÓNICA TRABAJO EN GRUPOLA ELECTRICIDAD Y LA ELECTRÓNICA TRABAJO EN GRUPO
LA ELECTRICIDAD Y LA ELECTRÓNICA TRABAJO EN GRUPOv16959670
 
Trabajo de Tecnología .pdfywhwhejsjsjsjsjsk
Trabajo de Tecnología .pdfywhwhejsjsjsjsjskTrabajo de Tecnología .pdfywhwhejsjsjsjsjsk
Trabajo de Tecnología .pdfywhwhejsjsjsjsjskbydaniela5
 
Taller de tecnología año 2024 11-2 sofia nava
Taller de tecnología año 2024  11-2 sofia navaTaller de tecnología año 2024  11-2 sofia nava
Taller de tecnología año 2024 11-2 sofia navaSofaNava1
 
Trabajo de tecnología 10-8 Primer periodo
Trabajo de tecnología 10-8 Primer periodoTrabajo de tecnología 10-8 Primer periodo
Trabajo de tecnología 10-8 Primer periodoAnaRiascos5
 
TALLER DE TECNOLOGIA, PRIMER PERIODO 11-2..docx
TALLER DE TECNOLOGIA, PRIMER PERIODO 11-2..docxTALLER DE TECNOLOGIA, PRIMER PERIODO 11-2..docx
TALLER DE TECNOLOGIA, PRIMER PERIODO 11-2..docxSantiagocortes55
 
Green-Tech.pdf (Tecnologia Verde) Tendencias Tecnologicas
Green-Tech.pdf (Tecnologia Verde) Tendencias TecnologicasGreen-Tech.pdf (Tecnologia Verde) Tendencias Tecnologicas
Green-Tech.pdf (Tecnologia Verde) Tendencias TecnologicasDahianaParedes2
 
La electricidad y la electronica.10-7.pdf
La electricidad y la electronica.10-7.pdfLa electricidad y la electronica.10-7.pdf
La electricidad y la electronica.10-7.pdfcristianrb0324
 
tecnologia trabajo sobre excel avanzado método estadístico
tecnologia trabajo sobre excel avanzado método estadísticotecnologia trabajo sobre excel avanzado método estadístico
tecnologia trabajo sobre excel avanzado método estadísticojuliana280780
 
Análisis de Artefactos Tecnologicos .docx
Análisis de Artefactos Tecnologicos .docxAnálisis de Artefactos Tecnologicos .docx
Análisis de Artefactos Tecnologicos .docxmajovaru19
 
TECNOLOGIA 11-4.8888888888888888888888888
TECNOLOGIA 11-4.8888888888888888888888888TECNOLOGIA 11-4.8888888888888888888888888
TECNOLOGIA 11-4.8888888888888888888888888ElianaValencia28
 
LISTA taller tecnología Sofia nava 11-2 año 2024
LISTA taller tecnología Sofia nava 11-2 año 2024LISTA taller tecnología Sofia nava 11-2 año 2024
LISTA taller tecnología Sofia nava 11-2 año 2024SofaNava1
 
TRABAJO TECNOLOGÍA E INFORMATICA TABLAAA
TRABAJO TECNOLOGÍA E INFORMATICA TABLAAATRABAJO TECNOLOGÍA E INFORMATICA TABLAAA
TRABAJO TECNOLOGÍA E INFORMATICA TABLAAASebastinOrdez4
 
tecnologiaactividad11-240323205859-a9b9b9bc.pdf
tecnologiaactividad11-240323205859-a9b9b9bc.pdftecnologiaactividad11-240323205859-a9b9b9bc.pdf
tecnologiaactividad11-240323205859-a9b9b9bc.pdflauralizcano0319
 

Último (20)

ORIENTACIONES DE INFORMÁTICA-2024.pdf-guia
ORIENTACIONES DE INFORMÁTICA-2024.pdf-guiaORIENTACIONES DE INFORMÁTICA-2024.pdf-guia
ORIENTACIONES DE INFORMÁTICA-2024.pdf-guia
 
BLOG, EXCEL AVANZADO, MÉTODOS ESTADÍSTICOS..docx
BLOG, EXCEL AVANZADO, MÉTODOS ESTADÍSTICOS..docxBLOG, EXCEL AVANZADO, MÉTODOS ESTADÍSTICOS..docx
BLOG, EXCEL AVANZADO, MÉTODOS ESTADÍSTICOS..docx
 
Cold Dyeing BROWN Shade, room temperature dyeing
Cold Dyeing BROWN Shade, room temperature dyeingCold Dyeing BROWN Shade, room temperature dyeing
Cold Dyeing BROWN Shade, room temperature dyeing
 
carta combinada para tecnología de sara Garzón
carta combinada para tecnología de sara Garzóncarta combinada para tecnología de sara Garzón
carta combinada para tecnología de sara Garzón
 
#Tare10ProgramacionWeb2024aaaaaaaaaaaa.pptx
#Tare10ProgramacionWeb2024aaaaaaaaaaaa.pptx#Tare10ProgramacionWeb2024aaaaaaaaaaaa.pptx
#Tare10ProgramacionWeb2024aaaaaaaaaaaa.pptx
 
tecnologia11-6 Juan Sebastián Gonzalez liceo
tecnologia11-6 Juan Sebastián Gonzalez liceotecnologia11-6 Juan Sebastián Gonzalez liceo
tecnologia11-6 Juan Sebastián Gonzalez liceo
 
tecnologia116.docx TRABAJO COLABORTIVO PRIMNER
tecnologia116.docx TRABAJO COLABORTIVO PRIMNERtecnologia116.docx TRABAJO COLABORTIVO PRIMNER
tecnologia116.docx TRABAJO COLABORTIVO PRIMNER
 
LA ELECTRICIDAD Y LA ELECTRÓNICA TRABAJO EN GRUPO
LA ELECTRICIDAD Y LA ELECTRÓNICA TRABAJO EN GRUPOLA ELECTRICIDAD Y LA ELECTRÓNICA TRABAJO EN GRUPO
LA ELECTRICIDAD Y LA ELECTRÓNICA TRABAJO EN GRUPO
 
Trabajo de Tecnología .pdfywhwhejsjsjsjsjsk
Trabajo de Tecnología .pdfywhwhejsjsjsjsjskTrabajo de Tecnología .pdfywhwhejsjsjsjsjsk
Trabajo de Tecnología .pdfywhwhejsjsjsjsjsk
 
Taller de tecnología año 2024 11-2 sofia nava
Taller de tecnología año 2024  11-2 sofia navaTaller de tecnología año 2024  11-2 sofia nava
Taller de tecnología año 2024 11-2 sofia nava
 
Trabajo de tecnología 10-8 Primer periodo
Trabajo de tecnología 10-8 Primer periodoTrabajo de tecnología 10-8 Primer periodo
Trabajo de tecnología 10-8 Primer periodo
 
TALLER DE TECNOLOGIA, PRIMER PERIODO 11-2..docx
TALLER DE TECNOLOGIA, PRIMER PERIODO 11-2..docxTALLER DE TECNOLOGIA, PRIMER PERIODO 11-2..docx
TALLER DE TECNOLOGIA, PRIMER PERIODO 11-2..docx
 
Green-Tech.pdf (Tecnologia Verde) Tendencias Tecnologicas
Green-Tech.pdf (Tecnologia Verde) Tendencias TecnologicasGreen-Tech.pdf (Tecnologia Verde) Tendencias Tecnologicas
Green-Tech.pdf (Tecnologia Verde) Tendencias Tecnologicas
 
La electricidad y la electronica.10-7.pdf
La electricidad y la electronica.10-7.pdfLa electricidad y la electronica.10-7.pdf
La electricidad y la electronica.10-7.pdf
 
tecnologia trabajo sobre excel avanzado método estadístico
tecnologia trabajo sobre excel avanzado método estadísticotecnologia trabajo sobre excel avanzado método estadístico
tecnologia trabajo sobre excel avanzado método estadístico
 
Análisis de Artefactos Tecnologicos .docx
Análisis de Artefactos Tecnologicos .docxAnálisis de Artefactos Tecnologicos .docx
Análisis de Artefactos Tecnologicos .docx
 
TECNOLOGIA 11-4.8888888888888888888888888
TECNOLOGIA 11-4.8888888888888888888888888TECNOLOGIA 11-4.8888888888888888888888888
TECNOLOGIA 11-4.8888888888888888888888888
 
LISTA taller tecnología Sofia nava 11-2 año 2024
LISTA taller tecnología Sofia nava 11-2 año 2024LISTA taller tecnología Sofia nava 11-2 año 2024
LISTA taller tecnología Sofia nava 11-2 año 2024
 
TRABAJO TECNOLOGÍA E INFORMATICA TABLAAA
TRABAJO TECNOLOGÍA E INFORMATICA TABLAAATRABAJO TECNOLOGÍA E INFORMATICA TABLAAA
TRABAJO TECNOLOGÍA E INFORMATICA TABLAAA
 
tecnologiaactividad11-240323205859-a9b9b9bc.pdf
tecnologiaactividad11-240323205859-a9b9b9bc.pdftecnologiaactividad11-240323205859-a9b9b9bc.pdf
tecnologiaactividad11-240323205859-a9b9b9bc.pdf
 

Simulacioncsharp

  • 1. 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, (rsandova@ing.puc.cl) basado en los apuntes de clase del curso IIC1102, año 2003, de M. Nussbaum, Marcos Sepúlveda, et.al.
  • 2. 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
  • 3. 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
  • 4. 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
  • 5. 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
  • 6. 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
  • 7. 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
  • 8. 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
  • 9. 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
  • 10. 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
  • 11. 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
  • 12. 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
  • 13. 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
  • 14. 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
  • 15. 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
  • 16. 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
  • 17. 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
  • 18. 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
  • 19. 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 1 compras1 Orden de Llegada1º 4º hh:mm 2 compras2 hh:mm 3 compras3 hh:mm 4 compras4 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
  • 20. 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
  • 21. 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
  • 22. 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("nt 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
  • 23. 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
  • 24. Simulación Computacional con C# Rodrigo Sandoval U. DateTime d = dt.AddMinutes(1); dt = d; } Console.WriteLine("nntt-=Estadistica=-nn"); 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("ttCaja 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
  • 25. 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
  • 26. 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
  • 27. 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
  • 28. 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
  • 29. 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
  • 30. 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
  • 31. 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
  • 32. Simulación Computacional con C# Rodrigo Sandoval U. Console.WriteLine("Nueva Simulaciónn=============================="); 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