Sunteți pe pagina 1din 85

lica de Chile Pontificia Universidad Cato Escuela de Ingenier a n Departamento de Ciencia de la Computacio IIC1103 Introducci on a la Programaci on

Cap tulo 10: Simulaci on Resumen te orico


El poder simular complejos sistemas es una de las grandes posibilidades que nos brinda la computaci on. Con ella podemos crear un modelo simplicado de la realidad que se comporte similar a un sistema en particular. Utilizando simulaci on podemos predecir el comportamiento de un sistema sin tener que observarlo en la realidad, lo que nos da diversas ventajas, entre ellas un menor costo (tanto dinero como tiempo), an alisis de sensibilidad (como reacciona el sistema ante cambios peque nos en ciertas variables) o simplemente la posibilidad de observar sistemas que generalmente se resisten al estudio (sistemas sociales por ejemplo). Un problema de simulaci on se puede dividir en dos partes:

Modelo
El modelo, que es el conjunto de clases que intenta representar el problema, considerando que los sistemas reales son demasiado complejos, por lo que debemos hacer una simplicaci on que se comporte de manera similar para nuestro problema particular. La funci on principal del modelo es almacenar la informaci on y realizar las operaciones entre los agentes que conforman el sistema. Por esto, es com un el uso de estructuras de datos, como son arreglos, matrices, colas, pilas, etc. Estas almacenar an los agentes unitarios que interactuar an en la simulaci on. Por ejemplo, un supermercado tiene una, o varias, colas de personas, a medida que van atendiendo a los clientes, estos salen de las colas para dar lugar a nuevos clientes.

Simulaci on
La simulaci on determina el ujo de los eventos en el modelo, por lo tanto lo contiene. Esta clase com unmente posee un constructor que ja los par ametros de la simulaci on, adem as de un m etodo niciar.o simular, que realizar a la simulaci on completa. Dado que es necesario dar ujo a la simulaci on hay varios m etodos, de los cuales nombraremos dos: En problemas donde hay un n umero de pasos, donde cada uno dura un lapso de tiempo, generalmente se pueden realizar iteraciones que representan cada paso. En cada uno ocurrir an determinados eventos, usualmente aleatorios, el modelo interactuar a, se har an validaciones, o se imprimir a el estado actual de la simulaci on. Siguiendo con el ejemplo de la cola del supermercado, en cada iteraci on podr amos decir que se pasa un producto del cliente atendido (los clientes tendr an cierto n umero de productos), y en cuanto se le acaben los productos, el cliente dejar a la cola para que el siguiente sea atendido. Adem as podr amos agregar una probabilidad en cada iteraci on de que lleguen nuevos clientes. Por u ltimo, podemos imprimir en consola un mensaje cada vez que un cliente entre o salga de la cola. Tambi en existen problemas donde no es optimo dividir la simulaci on en iteraciones, si no en eventos concatenados. En estas, cada evento lleva a otro, con la posibilidad de tomar distintos caminos. Ejemplo de esto podr a ser el proceso productivo de una f abrica, con varios productos que usan determinadas m aquinas en forma iterativa. Puede pasar el producto 1 a la m aquina 1, luego el producto 1 pasa a la m aquina 2 y el IIC1103 Cap tulo 10: Simulaci on 1

producto 2 entra en la m aquina 1, y as sucesivamente, con lo que podr amos realizar varias simulaciones a manera de ver que orden de entrada en las m aquinas permite la producci on de X productos en el menor tiempo. Adem as la simulaci on es la encargada de mantener las estad sticas que nos entregar a nalmente el programa, guardando los datos pertinentes a posteriores an alisis. Es com un que se realicen varias simulaciones y se considere un promedio, debido a la inuencia de las probabilidades en el resultado nal.

Temas nales
Simulaci on es una poderosa herramienta, pero depende en gran medida de los supuestos que hagamos para simplicar el problema original. Puede ocurrir que un dato considerado despreciable en principio tenga efectos inesperados en los resultados. Por ello es importante hacer un profundo an alisis del problema a tratar, y determinar los elementos pertinentes, siempre considerando que nuestro modelo ser a una simplicaci on del problema, pero que intentar a representar, con cierto porcentaje de error, al problema inicial.

IIC1103 Cap tulo 10: Simulaci on

Ejemplos
Problema 1: Fotocopias
Enunciado El due no de una de las fotocopiadoras de la universidad le ha encargado que haga un programa en Java que le permita calcular la cantidad de fotocopias solicitadas por los alumnos diariamente para dimensionar la cantidad de m aquinas e insumos que debe comprar el siguiente semestre. Modele el problema considerando la clase Evento. La clase Evento representa el evento llegada alumnos a la fotocopiadora, posee los m etodos tiempoSiguienteEvento horas() y tiempoSiguienteEvento segundos() que dado el tiempo actual calcula el tiempo en el que llegar a el siguiente alumno a solicitar fotocopias expresado en horas o segundos, respectivamente, respecto del inicio de la simulaci on. Elija uno de los dos m etodos para realizar la simulaci on. El constructor de la clase no recibe par ametros. public int tiempoSiguienteEvento_segundos(int T) {...} public double tiempoSiguienteEvento_horas(double T) {...} Se sabe que la cantidad de fotocopias que solicita un alumno es una variable aleatoria con distribuci on uniforme entre 1 y X fotocopias, en que X depende de la cantidad de cursos del alumno y, a su vez, corresponde a una variable aleatoria con distribuci on uniforme entre 30 y 60 fotocopias. La fotocopiadora atiende en horario continuado entre las 9:00 y las 18:00 hrs. Implemente el m etodo estimarFotocopias() de la clase Simulador. Este m etodo estima la cantidad de alumnos atendidos y la cantidad de fotocopias solicitadas diariamente. Simule un per odo de atenci on de 1 a no (365 d as) para que obtenga un buen estimador. public static void estimarFotocopias(){...} Su programa debe ir mostrando en consola la cantidad de alumnos y fotocopias solicitadas cada d a y al nal de la simulaci on la cantidad promedio de alumnos atendidos y la cantidad promedio de fotocopias solicitadas. Ejemplo: Simulaci on no 1. Cantidad de alumnos 176. Cantidad de fotocopias 4235 Simulaci on no 2. Cantidad de alumnos 185. Cantidad de fotocopias 4437 ... Simulaci on no 365. Cantidad de alumnos 175. Cantidad de fotocopias 4271 Fin de la simulaci on: Cantidad promedio de alumnos 180.05479452054794. Cantidad promedio de fotocopias 4147.282191780822 Criterios de soluci on En este caso la simulaci on es por eventos, en otras palabras, preguntamos cu ando es el siguiente evento y de acuerdo a eso cambiamos la cantidad de tiempo transcurrido. Tenemos dos participantes importantes dentro de esta, las fotocopias y los alumnos, sin embargo el u nico cambio que sufren es la cantidad de cada uno por lo que pueden ser representados como enteros. Luego en cada iteraci on hay que: Inicializar las fotocopias y alumnos en cero. Calcular cuando es el siguiente evento y cambiar la hora. Ver si cambia la cantidad de alumnos. IIC1103 Cap tulo 10: Simulaci on 3

Ver por cuanto cambia la cantidad de fotocopias. Y esto se repite por 365 iteraciones, simulando un a no. Al nal de estas se calcula el promedio de alumnos y fotocopias.

Posible soluci on
import i i c 1 1 0 3 P a c k a g e .*; public class S i m u l a d o r { /* * * e s t i m a r F o t o c o p i a s _ p r o x i m o e v e n t o Simula la llegada de alumnos al sistema * por 9 horas durante 1 anio . Estima la cantidad de alumnos a t e n d i d o s y * f o t o c o p i a s s o l i c i t a d a s en ese periodo de tiempo . Maneja el tiempo en * horas . */ public void e s t i m a r F o t o c o p i a s _ p r o x i m o e v e n t o() { // Reloj de s i m u l a c i o n double t_horas ; // Cantidad de alumnos por s i m u l a c i o n int nAlumnos ; // Cantidad de f o t o c o p i a s por s i m u l a c i o n int n F o t o c o p i a s; // Total de alumnos a c u m u l a d o double t o t a l A l u m n o s = 0.0; // Total de f o t o c o p i a s a c u m u l a d o double t o t a l F o t o c o p i a s = 0.0; // Evento llegada de un alumno Evento e = new Evento (); // Repito la s i m u l a c i o n for ( int i = 1; i <= 365; i ++) { // I n i c i a l i z o las v a r i a b l e s t_horas = 0.0; nAlumnos = 0; n F o t o c o p i a s = 0; // S I M U L A C I O N: // Genero el primer evento t_horas = e . t i e m p o S i g u i e n t e E v e n t o _ h o r a s( t_horas ); while ( t_horas <= 9.0) { // I n c r e m e n t o la cantidad de alumnos nAlumnos ++; n F o t o c o p i a s += A l e a t o r i o. entero (1 , A l e a t o r i o. entero (30 , 60)); // A c t u a l i z o el tiempo t_horas = e . t i e m p o S i g u i e n t e E v e n t o _ h o r a s( t_horas ); } // Acumulo la cantidad de alumnos t o t a l A l u m n o s += nAlumnos ; t o t a l F o t o c o p i a s += n F o t o c o p i a s; Usuario . m e n s a j e C o n s o l a( " S i m u l a c i o n n " + i + " . Cantidad de alumnos " + nAlumnos + " . Cantidad de f o t o c o p i a s " + n F o t o c o p i a s); } // Saco el promedio de las n S i m u l a c i o n e s t o t a l A l u m n o s = t o t a l A l u m n o s / 365; t o t a l F o t o c o p i a s = t o t a l F o t o c o p i a s / 365; Usuario . m e n s a j e C o n s o l a( " Fin de la s i m u l a c i o n: " ); Usuario . m e n s a j e C o n s o l a( " Cantidad promedio de alumnos " + t o t a l A l u m n o s); Usuario . m e n s a j e C o n s o l a( " Cantidad promedio de f o t o c o p i a s" + t o t a l F o t o c o p i a s); } }

IIC1103 Cap tulo 10: Simulaci on

Problema 2: Cobrando Peajes


Enunciado A ra z de los continuos reclamos de los automovilistas, quienes se quejan de lo lento que es el desplazamiento en las carreteras producto de la lentitud del cobro de peajes, se le ha pedido construir un programa computacional en Java que ayude a las empresas concesionarias a estimar el n umero m nimo de cajas que tienen que tener abiertas, de manera de asegurar una cierta calidad de servicios. Dicha calidad de servicio se puede expresar a trav es del tiempo m aximo que es aceptable que esperen los automovilistas desde que llegan al peaje hasta que se inicia su atenci on. Se puede suponer que el tiempo de llegada entre dos autom oviles es aleatorio y uniforme, entre 0 y un tiempo m aximo que var a para distintos intervalos horarios (ver tabla). Inicio 18:00:00 18:30:01 19:00:01 19:30:01 20:00:01 20:30:01 21:00:01 21:30:01 Otro horario Fin 18:30:00 19:00:00 19:30:00 20:00:00 20:30:00 21:00:00 21:30:00 22:00:00 Tiempo M aximo 10 seg 7 seg 3 seg 2 seg 1 seg 1 seg 3 seg 7 seg 20 seg

Para crear el programa en Java, puede utilizar las siguientes clases. Debe considerar que la unidad de tiempo que manejan dichas clases es el segundo. Caja: describe el funcionamiento de una caja del peaje, a la cual pueden llegar un n umero indeterminado de autos; para cada uno de ellos almacena cu anto tiempo de atenci on a un requieren.
// Crea una nueva caja ; la cola se puede c o n s i d e r a r tan grande como // sea n e c e s a r i o public Caja () { ... } // Agrega un auto , con un cierto tiempo r e q u e r i d o de atencion t public void a g r e g a r A u t o( int t ) { ... } // Atiende 1 segundo al auto que esta mas adelante en la cola public void a t e n d e r P r i m e r A u t o () { ... } // Retorna el tiempo restante de atencion r e q u e r i d o por el auto que esta // mas adelante en la cola public int t i e m p o R e s t a n t e P r i m e r A u t o () { ... } // Elimina de la cola al primer auto public void s a c a r P r i m e r A u t o() { ... } // Calcula el tiempo de atencion r e q u e r i d o por todos los autos en la cola public int t i e m p o T o t a l E s p e r a () { ... } // Retorna el numero de autos en espera public int g e t L a r g o C o l a() { ... }

PlazaPeaje: almacena un conjunto de cajas de peaje.


// C o n s t r u y e una plaza de peaje c o m p u e s t a de un grupo de cajas ; // i n i c i a l m e n t e no hay cajas abiertas public P l a z a P e a j e() { ... } // Agrega una nueva caja a la plaza de peaje

IIC1103 Cap tulo 10: Simulaci on

public void a g r e g a r C a j a() { ... } // Retorna cual el indice de la mejor caja ; aquella que s e l e c c i o n a r i a // un auto cuando llega al peaje ( aquella en que esperara menos // tiempo ) public int m e j o r C a j a() { ... } // Retorna la caja i - esima public Caja getCaja ( int i ) { ... } // Retorna el numero de cajas abiertas public int g e t N u m e r o C a j a s() { ... }

Se pide que implemente la clase Simulacion, la cual consta de los siguientes 3 m etodos:
// C o n s t r u y e un objeto de la clase S i m u l a c i o n public S i m u l a c i o n() { ... } // Retorna el tiempo maximo para t , donde t es el tiempo e x p r e s a d o en // segundos a partir del inicio de la s i m u l a c i o n (18:00 hrs .) public int g e t T i e m p o M a x i m o( int t ) { ... } // Efectua una s i m u l a c i o n completa desde las 18:00 hrs . a las 24:00 hrs . // Retorna el numero de cajas u t i l i z a d a s public int e f e c t u a r S i m u l a c i o n () { ... }

A modo de referencia, este es el m etodo main de la clase Principal del programa:


import i i c 1 1 0 3 P a c k a g e .*; public class P r i n c i p a l { public static void main ( String [] args ) { int n C a j a s T o t a l e s = 0; S i m u l a c i o n sim = new S i m u l a c i o n(); for ( int i = 0; i < 100; i ++) { int nCajas = sim . e f e c t u a r S i m u l a c i o n (); Usuario . m e n s a j e C o n s o l a( " S i m u l a c i o n " + i + " - numero de cajas : " + nCajas ); n C a j a s T o t a l e s += nCajas ; } Usuario . m e n s a j e C o n s o l a( " numero promedio cajas : " + ( double ) n C a j a s T o t a l e s / 100); } }

Algunos datos que requerir a para implementar la simulaci on: Deber a simular 6 horas a partir de las 18:00 horas. El tiempo requerido para atender a un cliente es de 15 segundos. El peaje deber a iniciar su funcionamiento con una caja. Por contrato se establece que cuando un auto llega el peaje, si el tiempo que deber a esperar es mayor que un cierto tiempo m aximo aceptable de 60 segundos, la concesionaria debe abrir una nueva caja. Una vez que se crea una nueva caja, esta no se cierra hasta el n de la simulaci on. Se pide: a)Implementaci on del constructor y del m etodo getTiempoMaximo de la clase Simulacion. b)Implementaci on del m etodo efectuarSimulacion de la clase Simulacion.

IIC1103 Cap tulo 10: Simulaci on

Criterios de soluci on a)El constructor de una simulaci on puede estar vac o y este es un ejemplo, aunque es posible pasarle ciertos par ametros como, cuando empieza, la cantidad de personas iniciales, etc. Esto no es necesario y en algunos casos es aconsejable no hacerlo. Para getTiempoMaximo basta hacer varios ifs que retornen los tiempos que aparecen en la tabla. b)Aqu tenemos que lo u nico importante es c omo cambia cada caja durante la simulaci on. Cu antos autos est an esperando en ella, si est a activa o no y cu anto le falta para atender el pr oximo auto. Adem as, de acuerdo con las instrucciones del enunciado debe, paso por paso: Ver cu ando es el pr oximo evento. Ver si en la mejor caja el tiempo es mayor que 60, en caso armativo se debe crear otra caja, si no, ocupa la mejor. Se agrega el auto a la caja correspondiente. Ver cuando llega el pr oximo auto. Hacer que cada caja atienda al auto que le corresponde Repetir. . . . Soluci on
import i i c 1 1 0 3 P a c k a g e .*; public class S i m u l a c i o n { public S i m u l a c i o n() { } public int g e t T i e m p o M a x i m o( int t ) { if ( t >= 0 && t return 10; } else if ( t >= return 7; } else if ( t >= return 3; } else if ( t >= return 2; } else if ( t >= return 1; } else if ( t >= return 1; } else if ( t >= return 3; } else if ( t >= return 7; } else { return 20; } } public int e f e c t u a r S i m u l a c i o n _ p o r T i e m p o() { Caja c ; // una caja auxiliar P l a z a P e a j e peaje = new P l a z a P e a j e(); // aqui esta toda la info de las cajas peaje . a g r e g a r C a j a (); // nuestra caja inicial int tActual = 0; // cuando llega el primer auto int tSig = A l e a t o r i o. entero (0 , g e t T i e m p o M a x i m o( tActual )); // el while del tiempo de s i m u l a c i o n while ( tActual <= 60 * 60 * 6) { <= 30 * 60 * 1) { 30 * 60 * 1 + 1 && t <= 30 * 60 * 2) { 30 * 60 * 2 + 1 && t <= 30 * 60 * 3) { 30 * 60 * 3 + 1 && t <= 30 * 60 * 4) { 30 * 60 * 4 + 1 && t <= 30 * 60 * 5) { 30 * 60 * 5 + 1 && t <= 30 * 60 * 6) { 30 * 60 * 6 + 1 && t <= 30 * 60 * 7) { 30 * 60 * 7 + 1 && t <= 30 * 60 * 8) {

IIC1103 Cap tulo 10: Simulaci on

// vemos si en el tiempo Actual c o r r e s p o n d e recibir un auto while ( tActual == tSig ) { // o b t e n e m o s la mejor caja int m = peaje . m e j o r C a j a(); c = peaje . getCaja ( m ); // si el tiempo de espera es mayor a 60 hacemos una caja nueva if ( c . t i e m p o T o t a l E s p e r a() > 60) { peaje . a g r e g a r C a j a (); m = peaje . m e j o r C a j a(); c = peaje . getCaja ( m ); } // a g r e g a m o s el auto c . a g r e g a r A u t o (15); tSig = tSig + A l e a t o r i o. entero (0 , g e t T i e m p o M a x i m o( tActual )); } // en este for a t e n d e m o s a los autos caja por caja for ( int i = 0; i < peaje . g e t N u m e r o C a j a s (); i ++) { c = peaje . getCaja ( i ); if ( c . g e t L a r g o C o l a() > 0) { c . a t e n d e r P r i m e r A u t o (); if ( c . t i e m p o R e s t a n t e P r i m e r A u t o() == 0) { c . s a c a r P r i m e r A u t o (); } } } tActual ++; } return peaje . g e t N u m e r o C a j a s(); } }

IIC1103 Cap tulo 10: Simulaci on

Problema 3: Metro de Santiago


Enunciado La empresa Metro se ha visto en la necesidad de estudiar los tiempos de espera promedio de sus pasajeros para as ver cu al es la mejor combinaci on de tama no y rapidez de sus trenes. Para ello le han pedido a usted que haga una simulaci on que logre determinar el tiempo de espera promedio de cada uno de los pasajeros que llegan a una estaci on. Un estudio muestra que la probabilidad de que llegue un pasajero en cada segundo es de un 25 %. Adem as el estudio muestra que los pasajeros saben donde est an las entradas a los carros, por lo que al llegar a la estaci on se ponen en una de las las para entrar a alg un carro. La elecci on de la la la hacen seg un cual sea m as corta. Los carros no vienen vac os, sino que llegan con un cierto n umero de pasajeros. Cuando un tren llega a la estaci on las personas en las las comienzan a subir al carro al cual pertenece su la hasta que el carro se llene o hasta que no queden m as personas en la la. Si el carro se llena esperan el pr oximo tren (no suben a otro carro). Tambi en se sabe que si un pasajero encuentra que todas las las de espera son de tama no igual o superior a 20 personas, se retira de la estaci on y se va en micro. Usted debe implementar el m etodo public double Simular(int tiempoMax, int[] datos) de la clase Estacion el cual recibe como par ametros el tiempo m aximo de la simulaci on en segundos, y un arreglo cuyo primer elemento es el tiempo m nimo que hay entre cada tren, el segundo elemento es el tiempo m aximo que hay entre las llegadas de cada tren, y el tercer elemento es la capacidad de cada uno de los carros del tren. Su m etodo debe retornar el tiempo promedio de espera de todos los pasajeros que llegan durante la simulaci on. Para realizar esto cuenta con las siguientes clases (no puede agregar m as m etodos ni atributos).
public class Estacion { // Arreglo de filas para subir a los carros del tren private Cola [] filas ; // C o n s t r u c t o r de la clase , i n i c i a l i z a el arreglo de filas public Estacion ( int p u e r t a s C a r r o ){...} // Metodo que usted debe i m p l e m e n t a r public double Simular ( int tiempoMax , int [] datos ){...} // Metodo que agrega un pasajero a la fila mas corta // Retorna false en caso de estar todas las filas llenas public boolean A g r e g a r P a s a j e r o( int t i e m p o L l e g a d a ){...} } public class Cola { // Constructor , recibe el tamanio maximo de la cola public Cola ( int max ) {...} // Agrega una persona a la cola public boolean Agregar ( Persona nuevo ) {...} // Retorna la primera persona en la cola , s a c a n d o l a de esta public Persona Proximo (){...} // Retorna el largo de la Cola public int Largo (){...} } public class Persona { // Constructor , recibe el tiempo de llegada de la persona public Persona ( int llegada ){...} // Retorna el tiempo de llegada de la persona public int g e t T i e m p o L l e g a d a() {...} // Indica que la persona se sube a un carro , recibe el tiempo en // que esto ocurre y retorna el tiempo que estuvo e s p e r a n d o public int Subirse ( int tiempo ) {...} } public class Metro { // Constructor , recibe el numero de carros del metro // y la c a p a c i d a d de cada uno . Calculo de forma a l e a t o r i a el // numero de personas que viene en cada Carro public Metro ( int numCarros , int m a x P a s a j e r o s ){...}

IIC1103 Cap tulo 10: Simulaci on

// Retorna el numero de p a s a j e r o s en el carro numCarro public int P a s a j e r o s C a r r o( int numCarro ){...} // Sube un pasajero al carro numCarro public void S u b i r P a s a j e r o( int numCarro ){...} }

Criterios de soluci on En este caso lo importante es ver cu anto tiempo se demora el metro y cu antos pasajeros se suben. Para hacer esto hay que: Ver si se llega un pasajero a la estaci on. Ver si viene un metro. Si viene un metro, por cada carro subir pasajeros mientras haya espacio. Repetir Soluci on
public double Simular ( int tiempoMax , int [] d ) { int p r o x M e t r o = A l e a t o r i o. entero ( d [0] , d [1]); double t i e m p o s E s p e r a = 0; int p a s a j e r o s A r r i b a = 0; for ( int tActual = 0; tActual < t i e m p o M a x; tActual ++) { if ( A l e a t o r i o. entero (1 , 100) <= 25) { A g r e g a r P a s a j e r o( tActual ); } if ( p r o x M e t r o == tActual ) { Metro tren = new Metro ( filas . length , d [2]); for ( int i = 0; i < filas . length ; i ++) { int pAct = tren . P a s a j e r o s C a r r o( i ); while ( filas [ i ]. Largo () > 0 && pAct < d [2]) { tren . S u b i r P a s a j e r o( i ); Persona proximo = filas [ i ]. Proximo (); if ( proximo != null ){ t i e m p o s E s p e r a += proximo . Subirse ( tActual ); } p a s a j e r o s A r r i b a ++; pAct ++; } } p r o x M e t r o = tActual + A l e a t o r i o. entero ( d [0] , d [1]); } } return t i e m p o s E s p e r a / p a s a j e r o s A r r i b a; }

IIC1103 Cap tulo 10: Simulaci on

10

Problema 4: Pelea
Enunciado Realice un programa en Java que represente la simulaci on de un juego de pelea de Arcade 1 . Para esto, debe tener en cuenta la siguiente informaci on: Peleador: clase que representa cada peleador. Estos poseen los siguientes datos ingresado por el usuario al principio de la simulaci on: 1. vida: puntos de vida. 2. maxPower: cantidad m axima de puntos de vida que puede llegar a quitar un peleador. 3. probabilidadGolpe: es posible que acierte un golpe, o que falle. La probabilidad de esto queda determinado por este valor. 4. tiempoBatalla: cantidad de segundos que puede llegar a durar la pelea. Hints: se sugiere fuertemente que adem as cree las siguientes clases. Pelea: clase que realice la simulaci on en s , y adem as se encargue de mostrar los resultados. Principal: como siempre, clase que pide los datos iniciales. Adem as, instancia los objetos de las clases correspondientes. Por simplicidad, puede suponer que solamente un peleador (partiendo por el primero) golpea cada segundo. As , su programa debe, en cada segundo, indicar la acci on que ocurre, esto es, qu e jugador intenta golpear, si lo logra o no, y en caso armativo, cu anto quita de vida, y al nal, qui en es el ganador 2 . Bonus: muestre un mensaje personalizado cuando un peleador golpee con m as de la mitad de su maxPower. Criterios de soluci on Dado lo generoso en informaci on del enunciado, debemos implementar cada una de las clases que se nos pide y sugiere. Lo m as cr tico es realizar de manera correcta el m etodo Simulaci on de la clase Pelea: se debe tener en cuenta que si un peleador ha muerto (sus puntos de vida son menores o iguales que 0), no puede golpear, por lo que debe nalizar la simulaci on. Soluci on
import i i c 1 1 0 3 P a c k a g e .*; public class Peleador { // [ A T R I B U T O S] private String nombre ; private int p u n t o s D e V i d a; private int p r o b a b i l i d a d G o l p e; private int maxPower ; // [ METODOS ] // C o n s t r u c t o r public Peleador ( String nombre , int puntosDeVida , int p r o b a b i l i d a dGo lp e , int maxPower ) { this . nombre = nombre ; this . p u n t o s D e V i d a = p u n t o s D e V i d a; this . p r o b a b i l i d a d G o l p e = p r o b a b i l i d a d G o l p e; this . maxPower = maxPower ;
1 por 2 si

ejemplo, Street Fighter al terminar el tiempo de la pelea, ambos peleadores siguen con vida, ganar a el que tenga m as puntos de vida

IIC1103 Cap tulo 10: Simulaci on

11

} // getters && setters public int g e t M a x P o w e r() { return maxPower ; } public String g e t N o m b r e() { return nombre ; } public int g e t P r o b a b i l i d a d G o l p e() { return p r o b a b i l i d a d G o l p e; } public int g e t P u n t o s D e V i d a () { return p u n t o s D e V i d a; } // otros metodos propios del problema public boolean P o d r a P e g a r() { int suerte = A l e a t o r i o. entero (0 , 100); return ( suerte >= this . p r o b a b i l i d a d G o l p e); } public int Golpear () { int potencia = 0; if ( this . P o d r a P e g a r ()) { potencia = A l e a t o r i o. entero (1 , maxPower ); // si pega con mas de la mitad del max poder , sera un golpe especial if ( potencia >= this . maxPower / 2) { potencia += 5; System . out . println ( this . nombre + " golpeara con Kamehame ( quita " + potencia + " ) " ); } else { System . out . println ( this . nombre + " golpeara normal con " + potencia ); } } else { System . out . println ( " El " + this . nombre + " feil " ); } return potencia ; } public void R e c i b i r G o l p e( int dano ) { this . p u n t o s D e V i d a -= dano ; } } import i i c 1 1 0 3 P a c k a g e .*; public class Pelea { private private private private Peleador p1 ; Peleador p2 ; int t i e m p o T r a n s c u r r i d o = 0; int t i e m p o T o t a l;

// [ METODOS ] // C o n s t r u c t o r public Pelea ( Peleador p1 , Peleador p2 , int t i e m p o T o t a l) { this . p1 = p1 ; this . p2 = p2 ; this . t i e m p o T o t a l = t i e m p o T o t a l; } public void Simular () { for (; this . t i e m p o T r a n s c u r r i d o < this . t i e m p o T o t a l; t i e m p o T r a n s c u r r i d o++) { if ( this . p1 . g e t P u n t o s D e V i d a() > 0) { p2 . R e c i b i r G o l p e( p1 . Golpear ()); } else { break ; }

IIC1103 Cap tulo 10: Simulaci on

12

if ( this . p2 . g e t P u n t o s D e V i d a() > 0) { p1 . R e c i b i r G o l p e( p2 . Golpear ()); } else { break ; } } } public void M o s t r a r G a n a d o r () { if ( p1 . g e t P u n t o s D e V i d a() < p2 . g e t P u n t o s D e V i d a ()) { Usuario . mensaje ( " Gano " + this . p2 . g e t N o m b r e()); } else if ( p2 . g e t P u n t o s D e V i d a() < p1 . g e t P u n t o s D e V i d a()) { Usuario . mensaje ( " Gano " + this . p2 . g e t N o m b r e()); } else { Usuario . mensaje ( " Empate " ); } } } public class P r i n c i p a l { /* * S i m u l a c i o n de una Pelea */ public static void main ( String [] args ) { // datos i n i c i a l e s int vida1 = 100 , vida2 = 100; int m a x P o w e r 1 = 5 , m a x P o w e r 2 = 3; int p r o b a b i l i d a d G o l p e 1 = 15 , p r o b a b i l i d a d G o l p e 2 = 20; int t i e m p o B a t a l l a = 30; String nombre1 = " L a n z a I n t e r n a c i o n a l" , nombre2 = " C h i p a M o g l i" ; // i n i a l i z a r v a r i a b l e s Peleador p1 = new Peleador ( nombre1 , vida1 , p r o b a b i l i d a dGo lp e1 , m a x P o w e r 1); Peleador p2 = new Peleador ( nombre2 , vida2 , p r o b a b i l i d a dGo lp e2 , m a x P o w e r 2); Pelea ring = new Pelea ( p1 , p2 , t i e m p o B a t a l l a); // llamado a la s i m u l a c i o n ring . Simular (); // muestra la i n f o r m a c i o n arrojada por la s i m u l a c i o n ring . M o s t r a r G a n a d o r (); } }

IIC1103 Cap tulo 10: Simulaci on

13

Problema 5: C octel
Enunciado La organizaci on sin nes de lucro Datos, Copuchas y Chismes (DCC) est a planicando un c octel al nalizar su pr oximo seminario, donde la idea es que los participantes se conozcan entre s . El objetivo de DCC es que, en promedio, cada persona haya conversado con al menos un cuarto de los dem as participantes en la duraci on de este c octel. Su misi on es realizar una simulaci on que determine la cantidad m nima de minutos que debiera durar el c octel para cumplir con el objetivo propuesto, considerando que: Cada persona puede establecer una conversaci on con, a lo m as, una persona a la vez. Una persona A estar a conversando con una persona B si y solo si B tambi en est a conversando con A (es una relaci on rec proca) En cada minuto, si una persona no est a conversando, intentar a establecer una conversaci on con alguna persona que tampoco est e conversando. Luego de cada minuto de conversaci on, una persona abandonar a la misma con un 40 % de probabilidad. Ud. solo debe escribir las clases Simulacion y Persona, pero considerando que ser an utilizadas de la siguiente forma en el m etodo main del programa:
L i s t a D e P e r s o n a s personas = new L i s t a D e P e r s o n a s (); for ( int i = 0; i < 100; i ++) { personas . agrega ( new Persona ()); } S i m u l a c i o n s i m u l a c i o n = new S i m u l a c i o n( personas ); s i m u l a c i o n. correr ();

Adem as, otro programador le ofrece usar la siguiente clase para aligerar su trabajo:
public class L i s t a D e P e r s o n a s { /* * * Agrega una persona a la lista * @param persona a agregar */ public void agrega ( Persona persona ) {...} /* * * Entrega alguna persona con la cual entablar una c o n v e r s a c i o n. Este * metodo g a r a n t i z a que la persona r e t o r n a d a no es la misma que la * e n t r e g a d a como parametro , que no esta con alguna c o n v e r s a c i o n actual * y ademas que no han tenido una anterior c o n v e r s a c i o n. Si no hay * ninguna persona que cumpla con todos los criterios , este metodo * r e t o r n a r a null . * @param persona para la cual se quiere d e t e r m i n a r su proxima c o n v e r s a c i o n * @return La persona con la cual debe c o n v e r s a r o null si no es posible e n c o n t r a r alguna */ public Persona p e r s o n a A C o n t a c t a r( Persona persona ) {...} /* * * Entrega la persona que esta en el indice indicado * @param indice de la persona pedida * @return la persona en el indice pedido */ public Persona obtiene ( int indice ) {...} /* * * Largo de la lista ( cantidad de personas ) * @return cantidad de personas en la lista */ public int getLargo () {...} }

IIC1103 Cap tulo 10: Simulaci on

14

Adem as, recuerde que cuenta con la clase Aleatorio de la librer a del curso, que tiene el m etodo Aleatorio.real(double desde, double hasta) que entrega un n umero real aleatorio entre desde y hasta. As , la expresi on Aleatorio.real(0, 1) <= 0.7 evaluar a a true con una probabilidad de un 70 %.

Criterios de soluci on Posible soluci on


import i i c 1 1 0 3 P a c k a g e .*; public class Persona { private Persona c o n v e r s a c i o n A c t u a l; private int c a n t i d a d C o n v e r s a c i o n e s; public void c o n v e r s a r U n M i n u t o() { if ( c o n v e r s a c i o n A c t u a l != null && A l e a t o r i o. real (0 , 1) < 0.4) { c o n v e r s a c i o n A c t u a l. c o n v e r s a c i o n A c t u a l = null ; c o n v e r s a c i o n A c t u a l = null ; } } public boolean e s t a C o n v e r s a n d o() { return c o n v e r s a c i o n A c t u a l != null ; } public void c o n v e r s a r C o n( Persona persona ) { c o n v e r s a c i o n A c t u a l = persona ; c a n t i d a d C o n v e r s a c i o n e s ++; } public int g e t C a n t i d a d D e C o n t a c t a d o s() { return c a n t i d a d C o n v e r s a c i o n e s; } } public class S i m u l a c i o n { private L i s t a D e P e r s o n a s personas ; public S i m u l a c i o n( L i s t a D e P e r s o n a s personas ) { this . personas = personas ; } public void correr () { double p r o m e d i o D e C o n t a c t a d o s = 0; int minutos = 0; while ( p r o m e d i o D e C o n t a c t a d o s < ( personas . getLargo () - 1) / 4.0) { for ( int i = 0; i < personas . getLargo (); i ++) { Persona p e r s o n a A c t u a l = personas . obtiene ( i ); if (! p e r s o n a A c t u a l. e s t a C o n v e r s a n d o ()) { Persona a C o n t a c t a r = personas . p e r s o n a A C o n t a c t a r( p e r s o n a A c t u a l); if ( a C o n t a c t a r != null ) { p e r s o n a A c t u a l. c o n v e r s a r C o n( a C o n t a c t a r); a C o n t a c t a r. c o n v e r s a r C o n( p e r s o n a A c t u a l); } } } for ( int i = 0; i < personas . getLargo (); i ++) { personas . obtiene ( i ). c o n v e r s a r U n M i n u t o (); } minutos ++; p r o m e d i o D e C o n t a c t a d o s = c a l c u l a r P r o m e d i o C o n t a c t a d o s (); } System . out . println ( " El promedio de c o n t a c t o s hechos en un coctel de " + personas . getLargo () + " personas es de " + p r o m e d i o D e C o n t a c t a d o s + " en " + minutos + " minutos " ); } private double c a l c u l a r P r o m e d i o C o n t a c t a d o s() { double total = 0; for ( int i = 0; i < personas . getLargo (); i ++) {

IIC1103 Cap tulo 10: Simulaci on

15

total += personas . obtiene ( i ). g e t C a n t i d a d D e C o n t a c t a d o s (); } return total / personas . getLargo (); } }

IIC1103 Cap tulo 10: Simulaci on

16

Problema 6: Sala de Espera


Enunciado Considere la clase Cliente, que representa a las personas que esperan para ser atendidos en un banco.
public class Cliente { private String rut ; private int p r i o r i d a d; public Cliente ( String id , int p ) { rut = id ; prioridad = p; } public int g e t P r i o r i d a d() { return p r i o r i d a d; } }

El atributo rut permite identicar a un cliente; el atributo prioridad indica la prioridad del cliente para ser atendido, seg un su importancia para el banco. Escriba la clase SalaEspera que representa a la sala de espera del banco. Esta clase debe tener al menos los siguientes dos m etodos (usted puede denir los atributos y constructor de la clase): boolean agregarCliente(String rut, int prioridad) crea un nuevo cliente y lo agrega a la lista de clientes esperando. Debe agregarlo en el orden de prioridad correspondiente dentro de la lista. Retorna false en caso de que no sea posible agregar el cliente a la lista. Cliente atenderCliente() retorna el pr oximo cliente que debe ser atendido, seg un el que tenga m axima prioridad. Si dos o m as tienen la misma prioridad se debe atender al que lleva m as tiempo en la sala de espera. HINT: Verique las condiciones de borde en ambos m etodos. Criterios de soluci on Posible soluci on
public class S a l a E s p e r a { private Cliente [] lista ; private int n u m C l i e n t e s; public S a l a E s p e r a( int max ) { lista = new Cliente [ max ]; n u m C l i e n t e s = 0; } public boolean a g r e g a r C l i e n t e( String rut , int p r i o r i d a d) { if ( n u m C l i e n t e s == lista . length ) { return false ; } Cliente c = new Cliente ( rut , p r i o r i d a d); int pos = 0; for ( pos = 0; pos < n u m C l i e n t e s; pos ++) { if ( c . g e t P r i o r i d a d() > lista [ pos ]. g e t P r i o r i d a d()) { break ; } } for ( int i = n u m C l i e n t e s - 1; i >= pos ; i - -) { lista [ i + 1] = lista [ i ]; } lista [ pos ] = c ; n u m C l i e n t e s++; return true ; }

IIC1103 Cap tulo 10: Simulaci on

17

public Cliente a t e n d e r C l i e n t e() { if ( n u m C l i e n t e s == 0) { return null ; } Cliente c = lista [0]; for ( int i = 0; i < n u m C l i e n t e s - 1; i ++) { lista [ i ] = lista [ i + 1]; } numClientes - -; return c ; } }

IIC1103 Cap tulo 10: Simulaci on

18

Problema 7: Formas Parejas


Enunciado A una esta llegan hombres y mujeres solteros. A medida que van llegando van formando parejas con la primera persona del sexo opuesto que encuentran, y que aun no est e en pareja. Escriba un programa completo en JAVA, que obtenga el tiempo promedio que demora la formaci on de k parejas, preguntando el valor de k al usuario, y muestre este resultado en la consola. Para obtener el valor promedio debe realizar una serie de simulaciones. La cantidad de simulaciones tambi en debe ser pedida al usuario. Para simular la llegada de personas usted cuenta con la clase Evento. Esta clase genera los tiempos de ocurrencia de un cierto evento. El constructor recibe como par ametro la tasa (en n umero de eventos por minuto) y el m etodo tiempoProximoEvento permite obtener el tiempo (en minutos) del pr oximo evento, recibiendo como par ametro el tiempo actual (puede asumir que el retorno siempre ser a mayor a 0). Dentro de la simulaci on es posible que alguna de las personas que llega tenga que retirarse, con lo cual, de estar emparejado, la persona que era su pareja pasa a quedar libre y busca r apidamente la primera persona del sexo opuesto que encuentre para volver a emparejarse. Para su simulaci on usted sabe que en promedio llegan 18 hombres y 20 mujeres por hora. Los tiempos de llegada de hombres y mujeres son independientes. Inicialmente el lugar de la esta se encuentra vac o. La tasa de personas que se retiran es 3 por hora, teniendo la misma posibilidad hombres que mujeres, y teniendo la misma posibilidad una persona emparejada que uno no emparejado.
public class Evento { public Evento ( double tasa ){...} public int t i e m p o P r o x i m o E v e n t o( int t i e m p o A c t u a l ){...} }

Criterios de soluci on Posible soluci on


import i i c 1 1 0 3 P a c k a g e .*; public class Fiesta { private int h o m b r e s S o l o s; private int m u j e r e s S o l a s; private int parejas ; public int simular ( int m a x P a r e j a s) { h o m b r e s S o l o s = 0; m u j e r e s S o l a s = 0; parejas = 0; Evento l l e g a d a H o m b r e s = new Evento (18 / 60.0); Evento l l e g a d a M u j e r e s = new Evento (20 / 60.0); Evento a b a n d o n o s = new Evento (3 / 60.0); int tiempo = 0; for ( tiempo = 0; parejas < m a x P a r e j a s; tiempo ++) { // Llegada de hombres y mujeres if ( l l e g a d a H o m b r e s. t i e m p o P r o x i m o E v e n t o( tiempo ) == tiempo ) h o m b r e s S o l o s ++; if ( l l e g a d a M u j e r e s. t i e m p o P r o x i m o E v e n t o( tiempo ) == tiempo ) m u j e r e s S o l a s ++; // Formamos parejas , la cantidad sera el minimo entre los hombres y // mujeres solas que hayan . parejas += Math . min ( hombresSolos , m u j e r e s S o l a s);

IIC1103 Cap tulo 10: Simulaci on

19

h o m b r e s S o l o s -= Math . min ( hombresSolos , m u j e r e s S o l a s); m u j e r e s S o l a s -= Math . min ( hombresSolos , m u j e r e s S o l a s); // Vemos si hay a b a n d o n o s if ( a b a n d o n o s. t i e m p o P r o x i m o E v e n t o( tiempo ) == tiempo ) { // C a l c u l a m o s un random sobre el total de personas int n = A l e a t o r i o. entero (1 , h o m b r e s S o l o s + m u j e r e s S o l a s + 2 * parejas ); // R e v i s a m o s quien se fue if ( n <= h o m b r e s S o l o s) { // Se fue un hombre solo hombresSolos - -; } else if ( n <= h o m b r e s S o l o s + m u j e r e s S o l a s) { // Se fue una mujer sola mujeresSolas - -; } else if ( n <= h o m b r e s S o l o s + m u j e r e s S o l a s + parejas ) { // Se fue un hombre en pareja parejas - -; m u j e r e s S o l a s ++; } else { // Se fue una mujer en pareja parejas - -; h o m b r e s S o l o s ++; } } } return tiempo ; } } import i i c 1 1 0 3 P a c k a g e .*; public class P r i n c i p a l { public static void main ( String [] args ) { int k = Usuario . entero ( " Cuantas parejas ? " ); int n = Usuario . entero ( " Cuantas s i m u l a c i o n e s? " ); double promedio = 0; for ( int i = 0; i < n ; i ++) { Fiesta f = new Fiesta (); promedio += f . simular ( k ); } promedio = promedio / n ; Usuario . m e n s a j e C o n s o l a( " Tiempo promedio : " + promedio ); } }

IIC1103 Cap tulo 10: Simulaci on

20

Problema 8: Concierto
Enunciado Una productora de eventos est a organizando un espectacular concierto de n de a no, conscientes de la alta demanda para la compra de entradas y anteriores experiencias vendiendo las entradas en su sitio web ha decidido cambiar sus servidores. Para dimensionar la cantidad de transacciones promedio que necesita atender por segundo y la cantidad m axima por hora lo ha contratado para que realice una simulaci on siguiendo los siguientes supuestos: En el concierto anterior las primeras cuatro horas el tiempo entre transacciones alcanz o su m aximo, durante la noche decay o y al d a siguiente volvi o a incrementarse hasta que se agotaron las entradas 24 hrs. despu es de iniciada la venta. Modele el problema considerando que los tiempos entre eventos es una variable aleatoria con distribuci on uniforme entre A y B milisegundos, donde A y B dependen de la hora. La primeras cuatro horas A : 1 - B : 4. Las siguientes seis horas A : 20 - B : 45. Las restantes catorce horas A : 3 - B : 7. El siguiente d a pese a que las entradas se agotaron A : 100 - B : 500. Recuerde que debe repetir su simulaci on para obtener buenos estimadores. Para cada simulaci on su programa debe imprimir en la consola la cantidad total de transacciones durante el periodo de simulaci on, el promedio de transacciones por segundo y la cantidad de transacciones en cada hora. Ejemplo: Simulacion 1. Cantidad de transacciones 16795291 Promedio de transacciones por segundo 97.18597800925926 Hora: 0 numero de transacciones 1439080 ... Hora: 3 numero de transacciones 1440117 Hora: 4 numero de transacciones 110769 ... Hora: 9 numero de transacciones 110693 Hora: 10 numero de transacciones 719679 ... Hora: 23 numero de transacciones 719762 Hora: 24 numero de transacciones 11983 ... Hora: 47 numero de transacciones 11993 Para nalizar su programa debe entregar la cantidad promedio de transacciones por simulaci on, la cantidad m axima de transacciones por hora y el promedio de transacciones por segundo. Ejemplo: Cantidad promedio de clientes por simulacion: 16792783.666666668 Cantidad promedio de transacciones por segundo: 97.18046103395062 Cantidad maxima de transacciones por hora: 1439719 No aproxime los valores nales de los estimadores. IIC1103 Cap tulo 10: Simulaci on 21

Criterios de soluci on Posible soluci on


import i i c 1 1 0 3 P a c k a g e .*; public class P r i n c i p a l { public static void main ( String [] args ) { // Reloj de s i m u l a c i o n int t ; // Cantidad de clientes por s i m u l a c i o n int n C l i e n t e s; // Solicito la cantidad de r e p e t i c i o n e s de la s i m u l a c i o n int n S i m u l a c i o n e s = Usuario . entero ( " Ingrese la cantidad de r e p e t i c i o n e s" ); // I n i c i a l i z o las v a r i a b l e s double t o t a l C l i e n t e s = 0; double t o t a l P r o m e d i o = 0; int m a x _ s i m u l a c i o n = 0; int max = 0; // Repito la s i m u l a c i o n for ( int i = 1; i <= n S i m u l a c i o n e s; i ++) { // I n i c i a l i z o las v a r i a b l e s por s i m u l a c i o n t = 0; n C l i e n t e s = 0; // Lo declaro adentro o lo i n i c i a l i z o completo en 0 en cada s i m u l a c i o n int [] c l i e n t e _ x _ h o r a = new int [48]; // S I M U L A C I O N: // Mientras el tiempo sea menor que 48 h simulo llegada de clientes // 1 h = 3600 s = 3600000 ms // Genero el primer evento t = A l e a t o r i o. entero (1 , 4); while ( t < 48 * 3600000) { // I n c r e m e n t o la cantidad de clientes de la s i m u l a c i o n n C l i e n t e s++; // I n c r e m e n t o la cantidad de clientes de la hora r e s p e c t i v a c l i e n t e _ x _ h o r a[( int ) t / 3 6 0 0 0 0 0 ] + + ; // A c t u a l i z o el tiempo y genero el proximo evento // Las primeras cuatro horas if ( t < 4 * 3600000) { t = t + A l e a t o r i o. entero (1 , 4); } // Las s i g u i e n t e s seis horas if ( t >= 4 * 3600000 && t < 10 * 3600000) { t = t + A l e a t o r i o. entero (20 , 45); } // Las r e s t a n t e s catorce horas if ( t >= 10 * 3600000 && t < 24 * 3600000) { t = t + A l e a t o r i o. entero (3 , 7); } // El s i g u i e n t e dia if ( t >= 24 * 3600000 && t < 48 * 3600000) { t = t + A l e a t o r i o. entero (100 , 500); } } // Acumulo la cantidad de clientes t o t a l C l i e n t e s += n C l i e n t e s; // Acumulo el promedio de t r a n s a c c i o n e s t o t a l P r o m e d i o += ( double ) n C l i e n t e s / (3600 * 48); // Imprimo r e s u l t a d o s Usuario . m e n s a j e C o n s o l a( " S i m u l a c i o n numero " + i + " .\ n C a n t i d a d de t r a n s a c c i o n e s " + n C l i e n t e s); Usuario . m e n s a j e C o n s o l a( " Promedio de t r a n s a c c i o n e s por segundo " + ( double ) n C l i e n t e s / (3600 * 48)); // Imprimo y busco maximo por hora m a x _ s i m u l a c i o n = c l i e n t e _ x _ h o r a [0]; for ( int j = 0; j < c l i e n t e _ x _ h o r a. length ; j ++) { Usuario . m e n s a j e C o n s o l a( " Hora : " + j + " numero de t r a n s a c c i o n e s "

IIC1103 Cap tulo 10: Simulaci on

22

+ c l i e n t e _ x _ h o r a[ j ]); if ( m a x _ s i m u l a c i o n < c l i e n t e _ x _ h o r a[ j ]) { m a x _ s i m u l a c i o n = c l i e n t e _ x _ h o r a[ j ]; } } // Maximo de todas las horas if ( max < m a x _ s i m u l a c i o n) { max = m a x _ s i m u l a c i o n; } } // Imprimo los p r o m e d i o s de las n S i m u l a c i o n e s Usuario . m e n s a j e C o n s o l a( " Cantidad promedio de clientes por s i m u l a c i o n: " + t o t a l C l i e n t e s / n S i m u l a c i o n e s); Usuario . m e n s a j e C o n s o l a( " Cantidad promedio de t r a n s a c c i o n e s por segundo : " + t o t a l P r o m e d i o / n S i m u l a c i o n e s); Usuario . m e n s a j e C o n s o l a( " Cantidad maxima de t r a n s a c c i o n e s por hora : " + max ); } }

IIC1103 Cap tulo 10: Simulaci on

23

Problema 9: Luces de Navidad


Enunciado Una de las formas m as espectaculares de decorar para navidad consiste en adornar con arreglos de luces, que van desde lo m as sencillo a lo m as complejo. Para sorprender a los vecinos, un amigo decidi o comprar un set de luces realmente complejo. En la tienda venden los siguientes componentes: Luces de color verde(G), rojo(R), blanco(W), azul(B) y amarillo(Y). Cada luz puede ser programada mediante una perilla de 10 regulaciones, que determina la frecuencia con que parpadea esta. Las regulaciones son: 0 (siempre prendida) o un valor de 1 a 9 (en segundos). Por ejemplo, un 2 implica que la ampolleta est a 2 segundos prendida, luego 2 segundos apagada. Cables con nodos de conexi on. Cada uno corresponde a 1 metro de cable con 4 zoquetes para ampolletas, seguido de un peque no enchufe al que pueden conectarse otros cables del mismo tipo. Cada cable puede ser programado con una perilla que puede ponerse en un n umero del 1 al 10. Un cable, al recibir una se nal, la transmite a todos los cables que est en conectados a el. Luego compara su propio n umero con el n umero enviado y s olo de ser iguales da corriente a sus ampolletas, indic andoles con un impulso que ha pasado un segundo, para que estas se prendan o se apaguen de acuerdo a sus propias perillas. Indeciso de que comprar, su amigo le pide que desarrolle en Java un programa que le permita simular la operaci on de diversas combinaciones de luces. M as espec camente debe implementar todas las clases necesarias de modo que sea posible construir las combinaciones de cables y luces (toda la informaci on debe ser recibida como par ametro por sus clases, NO debe ser pedida al usuario). Por u ltimo, tambi en debe implementar el m etodo simularLuces que recibe una conguraci on de cables y luces y un arreglo de enteros con las se nales que se dar an a los cables en cada segundo. Este m etodo debe simular todas las se nales recibidas, mostrando en consola el resultado de cada se nal. Para ello utilice tabulaciones y saltos de l nea para que se entienda qu e luces pertenecen a cada cable y como est an estos conectados. Use un punto para indicar una ampolleta inexistente o apagada. Por ejemplo: B B W . R . R . B W Y G W W W W . . G B B Y B Y Esto representar a un cable inicial (0) con 3 de 4 luces conectadas, al cual est an conectados otros dos cables (1 y 2) con s olo 2 de 4 ampolletas. Al cable 1 est an conectados otros dos cables (3 y 4) y al cable 2 s olo uno (5). Los cables 3, 4 y 5 no tienen otros cables conectados a ellos. Puede utilizar tantas clases como estime conveniente para solucionar el problema. Utilice y comente los supuestos sobre los que basa su soluci on. Criterios de soluci on Posible soluci on
// Clase que r e p r e s e n t a una a m p o l l e t a public class Luz { private int f r e c u e n c i a;

IIC1103 Cap tulo 10: Simulaci on

24

private char color ; private int actual ; /* * C o n s t r u c t o r de la a m p o l l e t a. * @param color Color de la luz . * @param f r e c u e n c i a F r e c u e n c i a de parpadeo . */ public Luz ( char color , int f r e c u e n c i a) { this . color = color ; this . f r e c u e n c i a = f r e c u e n c i a; this . actual = -1; } public String a v a n z a r T i e m p o() { actual ++; if ( f r e c u e n c i a == 0 || f r e c u e n c i a >= actual ) { if ( actual == 2 * f r e c u e n c i a - 1) { actual = 0; } return color + " " ; } else { return " . " ; } } } import i i c 1 1 0 3 P a c k a g e .*; // Clase que r e p r e s e n t a al cable public class Cable { private Luz luces []; private Cable cables []; private int serie ; public Cable ( int serie , String colores , String frecuencias , Cable [] cables ) { // Veo a que serie c o r r e s p o n d e. this . serie = serie ; // Agrego las luces . luces = new Luz [4]; for ( int i =0 ; i < luces . length ; i ++) { if ( f r e c u e n c i a s. charAt ( i ) != . ) { luces [ i ] = new Luz ( colores . charAt ( i ) , Integer . parseInt ( " " + f r e c u e n c i a s. charAt ( i ))); } } this . cables = cables ; } public void a v a n z a r T i e m p o( int secuencia , int p r o f u n d i d a d) { // Imprimo los tabs para el orden . String texto = " " ; for ( int i =0 ; i < p r o f u n d i d a d ; i ++) { texto += " \ t " ; } // Veo si me toca i l u m i n a r m e. for ( int i =0 ; i < luces . length ; i ++) { if ( luces [ i ] != null && serie == s e c u e n c i a) { texto += luces [ i ]. a v a n z a r T i e m p o (); } else { texto += " . " ; } } // Muestro mi senial Usuario . m e n s a j e C o n s o l a( texto ); // Traspazo la senial a los que estan c o n e c t a d o s a mi . for ( int i =0 ; i < cables . length ; i ++) { cables [ i ]. a v a n z a r T i e m p o( secuencia , p r o f u n d i d a d + 1); } } }

public class P r i n c i p a l {

IIC1103 Cap tulo 10: Simulaci on

25

// Metodo que controla las luces public static void s i m u l a r L u c e s( Cable cable , int [] senales ) { for ( int i = 0; i < senales . length ; i ++) cable . a v a n z a r T i e m p o( senales [ i ] , 0); } }

IIC1103 Cap tulo 10: Simulaci on

26

Problema 10: Aeropuerto


Enunciado En el aeropuerto de Santiago se est an produciendo problemas en la salida de vuelos debido a retrasos de los pasajeros en la zona de Inmigraci on, especialmente a las horas de mayor congesti on. Esto ha producido retrasos en los vuelos y que algunos pasajeros no logren llegar a tomar sus vuelos. Investigaciones ha decidido experimentar con un nuevo sistema, en el cual las personas ingresan a una cola com un (al estilo de los bancos) pero priorizada. Esto signica que cuando llega un pasajero a la zona de Inmigraci on, se le da un lugar en la cola seg un la hora de salida programada de su vuelo (en la pr actica quedar an ordenados por la hora de salida de los respectivos vuelos). Para validar si el sistema ser a m as eciente, se desea hacer algunas simulaciones, para lo cual ya se ha implementado la clase Pasajero. Se le pide que implemente completamente la clase ColaPriorizadaAeropuerto, que debe proveer las siguientes funcionalidades: Crear una cola priorizada que pueda almacenar un m aximo de N (par ametro) elementos Agregar un pasajero a la cola priorizada Retornar el primer elemento de la cola priorizada Eliminar el primer elemento de la cola priorizada Preguntar si la cola priorizada est a vac a Mostrar la cola priorizada en la consola La implementaci on deber a considerar las excepciones y casos de borde. Si no es posible realizar una acci on, deber a desplegar un mensaje en la consola. La clase Pasajero almacena la informaci on relacionada a un pasajero: nombre, apellido, vuelo, asiento y hora del vuelo. Sus m etodos son los siguientes: public Pasajero(String nombre, String apellido, String vuelo, String asiento, int horaVuelo) : Constructor de la clase. La hora se ingresa como un entero en el formato hhmm (por ejemplo, 830 para las 8:30 horas o 1930 para las 19:30 horas) public String getNombre() : Retorna el nombre del pasajero. public String getApellido() : Retorna el apellido del pasajero. public String getVuelo() : Retorna el vuelo del pasajero. public String getAsiento() : Retorna el asiento asignado al pasajero. public int getHoraVuelo() : Retorna la hora del vuelo del pasajero. public void Mostrar() : Muestra los datos del pasajero en una l nea de la consola. Criterios de soluci on Posible soluci on

IIC1103 Cap tulo 10: Simulaci on

27

import i i c 1 1 0 3 P a c k a g e .*; public class C o l a P r i o r i z a d a A e r o p u e r t o { private Pasajero [] arreglo ; // Arreglo para a l m a c e n a r los p a s a j e r o s private int ultimo ; // S i g u i e n t e elemento d i s p o n i b l e en el arreglo public C o l a P r i o r i z a d a A e r o p u e r t o( int l a r g o M a x i m o) { arreglo = new Pasajero [ l a r g o M a x i m o]; ultimo = 0; } public void Agregar ( Pasajero nuevo ) { // Si todavia es posible insertar un pasajero if ( ultimo != arreglo . length ) { // Buscar donde insertar int pos = ultimo ; for ( int i = 0; i < ultimo && pos == ultimo ; i ++) { if ( arreglo [ i ]. g e t H o r a V u e l o() > nuevo . g e t H o r a V u e l o()) { pos = i ; } } // D e s p l a z a r e l e m e n t o s for ( int i = ultimo ; i > pos ; i - -) { arreglo [ i ] = arreglo [ i - 1]; } // Insertar en la posicion c o r r e s p o n d i e n t e arreglo [ pos ] = nuevo ; ultimo ++; } else { Usuario . mensaje ( " Cola esta llena " ); } } public Pasajero Primero () { if (! Vacia ()) { return arreglo [0]; } else { Usuario . mensaje ( " Cola esta vacia " ); return null ; } } public void Eliminar () { if (! Vacia ()) { for ( int i = 0; i < ultimo - 1; i ++) { arreglo [ i ] = arreglo [ i + 1]; } } else { Usuario . mensaje ( " Cola esta vacia " ); } } public boolean Vacia () { return ultimo == 0; } public void Mostrar () { Usuario . m e n s a j e C o n s o l a( " Listado de p a s a j e r o s" ); for ( int i = 0; i < ultimo ; i ++) { arreglo [ i ]. Mostrar (); } } }

IIC1103 Cap tulo 10: Simulaci on

28

Problema 11: Abastecimiento Diesel


Enunciado Una importante empresa generadora de electricidad le ha encargado que haga un estudio sobre el abastecimiento de diesel para la operaci on de una de sus centrales termoel ectricas. Existen 2 camiones encargados de transportar diesel desde una central de abastecimiento hasta la unidad de descarga de la central. El tiempo que toma descargar un cami on es una variable aleatoria con distribuci on uniforme entre 18 y 30 minutos. Un cami on deja la unidad de descarga cuando ha entregado la totalidad de su combustible y vuelve con una nueva carga despu es de un tiempo con distribuci on uniforme entre 30 y 48 minutos. Si un cami on llega mientras la unidad de descarga se encuentra ocupada debe esperar hasta que esta se desocupe para descargar. Desarrolle un programa que permita simular 2000 horas de operaci on ininterrumpida de la central. Su programa debe imprimir en la consola la cantidad de descargas que se realizaron en la central al nal de la simulaci on. Ejemplo: Cantidad de descargas: 3727 Supuestos: Todos los camiones que solicitan descarga dentro del tiempo de la simulaci on, hasta las 2000 horas inclusive, son atendidos. Para generar una variable aleatoria con distribuci on uniforme entre A y B puede utilizar Aleatorio.entero(A,B). Se debe atender los camiones en orden de llegada (orden FIFO, rst in rst out). Criterios de soluci on Posible soluci on
import i i c 1 1 0 3 P a c k a g e .*; public class S i m u l a d o r { public static void main ( String [] args ) { // Este arreglo c o n t e n d r a el tiempo en que llegara cada camion al // sitio de descarga int [] t l l C a m i o n e s = { A l e a t o r i o. entero (30 , 48) , A l e a t o r i o. entero (30 , 48) }; // Esta variable indica el indice del camion que esta siendo d e s c a r g a d o int c a m i o n D e s c a r g a n d o = -1; // Esta variable indica el tiempo en que de d e s o c u p a r a la descarga int t i e m p o D e s o c u p a D e s c a r g a = 0; // Contador para el numero de d e s c a r g a s int n u m e r o D e s c a r g a s = 0; // El ciclo termina a los 2000*60 minutos for ( int tiempo = 0; tiempo <= 2000 * 60; tiempo ++) { // R e v i s a m o s si se termino de realizar una descarga . Para ello el // tiempo final de la descarga debe ser igual al tiempo actual y ademas // el indice del camion debe ser distinto de -1 if ( t i e m p o D e s o c u p a D e s c a r g a == tiempo && c a m i o n D e s c a r g a n d o != -1) { // Si hay que d e s o c u p a r c a l c u l a m o s el tiempo en que el // camion que quedo // d e s o c u p a d o volvera al sitio de descarga t l l C a m i o n e s[ c a m i o n D e s c a r g a n d o] = tiempo + A l e a t o r i o. entero (30 , 48); // D e s o c u p a m o s la descarga i n d i c a n d o que no hay camiones d e s c a r g a n d o s e c a m i o n D e s c a r g a n d o = -1; } // R e v i s a m o s si la descarga esta vacia , es decir , no hay camiones // d e s c a r g a n d o s e

IIC1103 Cap tulo 10: Simulaci on

29

if ( c a m i o n D e s c a r g a n d o == -1) { // Buscamos el camion con tiempo de llegada menor , ya que a // ese le c o r r e s p o n d e comenzar a ser d e s c a r g a d o int min = 0; for ( int i = 1; i < t l l C a m i o n e s. length ; i ++) { if ( t l l C a m i o n e s[ i ] < t l l C a m i o n e s[ min ]) { min = i ; } } // R e v i s a m o s si el camion con el tiempo menor de llegada ya // hizo su arribo , en caso de que aun no haya llegado la // descarga seguira d e s o c u p a d a if ( t l l C a m i o n e s[ min ] <= tiempo ) { // Si el camion ya llego , entonces d e f i n i m o s que este // sera el camion que se estara d e s c a r g a n d o y // c a l c u l a m o s el tiempo en que la descarga se d e s o c u p a r a c a m i o n D e s c a r g a n d o = min ; t i e m p o D e s o c u p a D e s c a r g a = tiempo + A l e a t o r i o. entero (18 , 30); // A u m e n t a m o s el numero de d e s c a r g a s totales n u m e r o D e s c a r g a s ++; } } } // R e v i s a m o s si quedo algun camion sin ser atendido , en caso de // haberlo a u m e n t a m o s el numero de d e s c a r g a s. for ( int i = 0; i < t l l C a m i o n e s. length ; i ++) { if ( t l l C a m i o n e s[ i ] <= 2000) { n u m e r o D e s c a r g a s ++; } } Usuario . m e n s a j e C o n s o l a( " Cantidad de D e s c a r g a s: " + n u m e r o D e s c a r g a s); } }

IIC1103 Cap tulo 10: Simulaci on

30

Problema 12: Votaci on Elecci on


Enunciado En este ejercicio completaremos la problem atica de lo que es una votaci on en alguna elecci on, ya sea a nivel nacional o bien en el contexto universitario. En esta ocasi on, simularemos la llegada de votantes a las mesas, con ciertas particularidades. Es muy com un la modelaci on de problemas de este tipo por medio de un lenguaje de programaci on, y de los cuales Ud. ya ha tenido la oportunidad de conocer ejemplos en clases, con una alta probabilidad. El programa lo dividiremos en 3 subconjuntos incrementales. Le recomendamos no comenzar con el siguiente subconjunto hasta terminar y probar el funcionamiento correcto del subconjunto actual. Incremento 1 Ud. debe cargar la lista de votantes desde el archivo votantes.txt, donde cada l nea representa el id del votante y el sexo del mismo (con 1: femenino, 0: masculino), separados por una tabulaci on3 . La l nea en el archivo representa el orden en que vota (i.e. la primera l nea representa la informaci on del primer votante). La informaci on de sexo se utilizar a en el segundo incremento. Luego, Ud. debe solicitar al usuario lo siguiente: N umero total de votantes representa el total de votantes que se usar a en la elecci on. En caso de ser menor al n umero de votantes cargados a partir del archivo, se deben usar los primeros votantes del archivo. En caso de ser mayor, se debe solicitar al usuario nuevamente el n umero de votantes hasta que sea correcto. N umero total de horas en el funcionamiento representa el total de horas del funcionamiento de la mesa. Por simplicidad, el funcionamiento es continuado. N umero total de mesas representa el total de mesas disponibles para la elecci on. Luego de esto, su programa debe simular la llegada de votantes, por minuto4 , al set de mesas. Es una sola la de personas, y se debe vericar en cada minuto si hay alg un votante esperando en ella para emitir su sufragio. Si lo hay, se debe seleccionar aleatoriamente5 una mesa, que no haya sido asignada a otro votante. Se debe escoger un tiempo aleatorio entre 1 y 3 minutos (ambos inclusive) correspondiente al tiempo que le toma al votante emitir su sufragio. El tiempo asignado a la persona para votar incluye el minuto en que fue designada la mesa (i.e. minuto actual). Mientras exista una persona votando en una mesa, ella no est a disponible para m as votantes. Recuerde ir actualizando los tiempos. Si no hay una mesa disponible, debe informar en consola tal hecho. Un mensaje de ejemplo es el siguiente: Minuto: 18 - El votante id: 12 no encontr o mesas disponibles El conteo de las mesas, votantes y minutos parte en cero. El id de votante corresponde al id cargado inicialmente a partir del archivo votantes.txt. Para este incremento, se atiende a un solo votante a la vez, por minuto, para asignarle una mesa para sufragar. Muy importante es considerar el supuesto de que cada persona se comporta de manera aut onoma, es decir
\t, invisible al abrir el archivo con alg un editor de texto, pero detectable a la hora de recorrerlo. que una hora tiene 60 minutos. 5 Recuerde que dispone del m etodo Aleatorio.entero(int a,int b) presente en el paquete del Curso para generar un n umero aleatorio que se encuentre entre los enteros a y b (ambos inclusive).
4 Note 3 Caracter

IIC1103 Cap tulo 10: Simulaci on

31

cada cual decide si llega a votar o se retira de la la. Por simplicidad, puede considerar que al momento de votar, existe una probabilidad de un 50 % de querer sufragar o retirarse del lugar por parte del votante. Una vez nalizada la simulaci on, se deben entregar resultados por mesa, y totales. Un ejemplo, con 100 posibles votantes, 2 mesas y 2 horas de funcionamiento es el siguiente: ================================================== RESULTADOS MESA 0 Total votantes: 22 ================================================== ================================================== RESULTADOS MESA 1 Total votantes: 18 ================================================== ================================================== RESULTADOS TOTALES Total personas que sufragaron: : 40 Personas que no votaron: 60 ================================================== Incremento 2 En este incremento, Ud. debe hacer que su programa simule tambi en la llegada aleatoria de personas de distinto sexo a las mesas de votaci on (i.e. femenino y masculino), a partir de la informaci on cargada en el primer incremento. Debe mostrar estad sticas de resultados para cada mesa, y un resumen nal que contenga la misma informaci on mostrada en el incremento anterior, con detalles para cada sexo. Un ejemplo de estad stica (para el caso de una mesa) es el siguiente: ================================================== RESULTADOS MESA 0 Votantes mujeres: 9 Votantes hombres: 13 Total votantes: 22 ================================================== Incremento 3 En este incremento Ud. deber a mejorar la modelaci on del problema, permitiendo asignar m as de una mesa por minuto, mientras existan votantes en la la (y naturalmente mesas disponibles) para ese minuto. Se deben mostrar en consola mensajes para cada minuto en que hubo personas que quisieran votar en la la, similares a los siguientes: Si hubo votantes a los cuales se les asign o mesa

Minuto: 1 - Se le asign o mesa de votaci on a 2 persona(s)

Si qued o un votante esperando Minuto: 2 - El votante id: 2 no encontr o mesas disponibles Por simplicidad, asuma que s olo se queda esperando para el minuto siguiente la primera persona de la la (por tanto la informaci on que muestra es la de ese votante). Los votantes que est an atr as de la persona que est a a la cabeza de la la, o bien se van, o aumentan para el siguiente minuto, todo de forma aleatoria. No deben quedarse esperando todos en la la necesariamente. Recuerde que cada individuo se comporta

IIC1103 Cap tulo 10: Simulaci on

32

de forma aut onoma (i.e. cada cual decide si llega a votar o bien se retira, no toman decisiones en grupo consensuadas). Criterios de soluci on Posible soluci on
public class Votante { public int sexo ; // 1: mujer , 0: hombre ; public int id ; public Votante () { } public int getSexo () { return sexo ; } public void setSexo ( int sexo ) { this . sexo = sexo ; } public int getId () { return id ; } public void setId ( int id ) { this . id = id ; } } import i i c 1 1 0 3 P a c k a g e .*; public class Mesa { private int t i e m p o A c t u a l V o t a c i o n; private int c u e n t a M u j e r e s; private int c u e n t a H o m b r e s; public int g e t C u e n t a H o m b r e s () { return c u e n t a H o m b r e s; } public void s e t C u e n t a H o m b r e s( int c u e n t a H o m b r e s) { this . c u e n t a H o m b r e s = c u e n t a H o m b r e s; } public int g e t C u e n t a M u j e r e s () { return c u e n t a M u j e r e s; } public void s e t C u e n t a M u j e r e s( int c u e n t a M u j e r e s) { this . c u e n t a M u j e r e s = c u e n t a M u j e r e s; } public int g e t T i e m p o A c t u a l V o t a c i o n() { return t i e m p o A c t u a l V o t a c i o n; } public void s e t T i e m p o A c t u a l V o t a c i o n( int t i e m p o A c t u a l V o t a c i o n) { this . t i e m p o A c t u a l V o t a c i o n = t i e m p o A c t u a l V o t a c i o n; } public void a c t u a l i z a V o t a c i o n( Votante votante ) { switch ( votante . getSexo ()) { case 0: // hombre c u e n t a H o m b r e s ++; break ; case 1: // mujer c u e n t a M u j e r e s ++; break ;

IIC1103 Cap tulo 10: Simulaci on

33

} t i e m p o A c t u a l V o t a c i o n = A l e a t o r i o. entero (1 , 3); } public void d i s m i n u i r T i e m p o V o t a c i o n() { if ( t i e m p o A c t u a l V o t a c i o n > 0) { t i e m p o A c t u a l Vo ta ci on - -; } } public void i m p r i m i r E s t a d i s t i c a() { Usuario . m e n s a j e C o n s o l a( " Votantes mujeres : " + c u e n t a M u j e r e s); Usuario . m e n s a j e C o n s o l a( " Votantes hombres : " + c u e n t a H o m b r e s); Usuario . m e n s a j e C o n s o l a( " Total votantes : " + ( c u e n t a M u j e r e s + c u e n t a H o m b r e s )); } } import java . io .*; import java . util . Scanner ; import i i c 1 1 0 3 P a c k a g e .*; public class P r i n c i p a l { static Mesa [] mesas ; static Votante [] votantes ; public static void main ( String [] args ) throws I O E x c e p t i o n { int c o u n t V o t a n t e s O k = 0; int t o t a l V o t a n t e s = Usuario . entero ( " Ingrese el numero total int m a x V o t a n t e s = n r o M a x V o t a n t e s( " votantes . txt " ); while ( t o t a l V o t a n t e s > m a x V o t a n t e s) { t o t a l V o t a n t e s = Usuario . entero ( " El total de votantes debe + maxVotantes + " .\ nIngrese el numero total de votantes " ); } int t o t a l H o r a s = Usuario . entero ( " Ingrese el numero de horas + " las mesas " ); int t o t a l M e s a s = Usuario . entero ( " Ingrese el numero total de mesas = new Mesa [ t o t a l M e s a s]; for ( int i = 0; i < mesas . length ; i ++) { mesas [ i ] = new Mesa (); } votantes = new Votante [ t o t a l V o t a n t e s]; for ( int i = 0; i < votantes . length ; i ++) { votantes [ i ] = new Votante (); } c a r g a r V o t a n t e s( " votantes . txt " , t o t a l V o t a n t e s); boolean v o t a n t e E n E s p e r a = false ; for ( int i = 0; i < t o t a l H o r a s * 60; i ++) { d i s m i n u i r T i e m p o s V o t a c i o n (); int h a y V o t a n t e = 1; int c u e n t a V o t a n t e s M i n u t o = 0; if (! v o t a n t e E n E s p e r a) { h a y V o t a n t e = A l e a t o r i o. entero (0 , 1); } while ( h a y V o t a n t e == 1) { if ( c o u n t V o t a n t e s O k == votantes . length ) { break ; } // buscar mesa d i s p o n i b l e Mesa m e s a A c t u a l = g e t M e s a D i s p o n i b l e (); if ( m e s a A c t u a l != null ) { m e s a A c t u a l. a c t u a l i z a V o t a c i o n( votantes [ c o u n t V o t a n t e s O k ]); c o u n t V o t a n t e s O k ++; c u e n t a V o t a n t e s M i n u t o ++; } else { Usuario . m e n s a j e C o n s o l a( " Minuto : " + i + " - El votante id : " de votantes " );

ser menor a "

de f u n c i o n a m i e n t o de " mesas " );

IIC1103 Cap tulo 10: Simulaci on

34

+ votantes [ c o u n t V o t a n t e s O k]. getId () + " no encontro mesas d i s p o n i b l e s" ); v o t a n t e E n E s p e r a = true ; } if (! v o t a n t e E n E s p e r a) { h a y V o t a n t e = A l e a t o r i o. entero (0 , 1); } else { h a y V o t a n t e = 0; } } if ( c u e n t a V o t a n t e s M i n u t o > 0) { Usuario . m e n s a j e C o n s o l a( " Minuto : " + i + " - Se le asigno mesa de votacion a " + c u e n t a V o t a n t e s M i n u t o + " persona ( s ) " ); } if ( c o u n t V o t a n t e s O k == votantes . length ) { break ; } } i m p r i m i r E s t a d i s t i c a (); } private static Mesa g e t M e s a D i s p o n i b l e() { int c u e n t a I n t e n t o s = 0; while ( c u e n t a I n t e n t o s < mesas . length ) { int nroMesa = A l e a t o r i o. entero (0 , mesas . length - 1); if ( mesas [ nroMesa ]. g e t T i e m p o A c t u a l V o t a c i o n() == 0) { return mesas [ nroMesa ]; } c u e n t a I n t e n t o s ++; } return null ; } private static void d i s m i n u i r T i e m p o s V o t a c i o n() { for ( int i = 0; i < mesas . length ; i ++) { mesas [ i ]. d i s m i n u i r T i e m p o V o t a c i o n (); } } private static void i m p r i m i r E s t a d i s t i c a() { int c u e n t a M u j e r e s = 0; int c u e n t a H o m b r e s = 0; for ( int i = 0; i < mesas . length ; i ++) { Usuario . m e n s a j e C o n s o l a( " = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = " ); Usuario . m e n s a j e C o n s o l a( " R E S U L T A D O S MESA " + i ); mesas [ i ]. i m p r i m i r E s t a d i s t i c a(); Usuario . m e n s a j e C o n s o l a( " = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = " ); c u e n t a M u j e r e s += mesas [ i ]. g e t C u e n t a M u j e r e s (); c u e n t a H o m b r e s += mesas [ i ]. g e t C u e n t a H o m b r e s (); } Usuario . m e n s a j e C o n s o l a( " = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = " ); Usuario . m e n s a j e C o n s o l a( " R E S U L T A D O S TOTALES " ); Usuario . m e n s a j e C o n s o l a( " Votantes mujeres : " + c u e n t a M u j e r e s); Usuario . m e n s a j e C o n s o l a( " Votantes hombres : " + c u e n t a H o m b r e s); Usuario . m e n s a j e C o n s o l a( " Total personas que s u f r a g a r o n: " + ( c u e n t a M u j e r e s + c u e n t a H o m b r e s )); Usuario . m e n s a j e C o n s o l a( " Personas que no votaron : " + ( votantes . length - ( c u e n t a M u j e r e s + c u e n t a H o m b r e s ))); Usuario . m e n s a j e C o n s o l a( " = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = " ); } private static int n r o M a x V o t a n t e s( String n o m b r e A r c h i v o) throws I O E x c e p t i o n { File archivo = new File ( n o m b r e A r c h i v o); if ( archivo . exists ()) { // Abrimos lectores Scanner bLector = new Scanner ( archivo ); int count = 0; String linea ; while ( bLector . h a s N e x t L i n e()) { linea = bLector . nextLine ();

IIC1103 Cap tulo 10: Simulaci on

35

count ++; } // Cerramos archivos bLector . close (); return count ; } else { return -1; } } private static boolean c a r g a r V o t a n t e s( String nombreArchivo , int t o t a l V o t a n t e s) throws I O E x c e p t i o n { File archivo = new File ( n o m b r e A r c h i v o); if ( archivo . exists ()) { // Abrimos lectores Scanner bLector = new Scanner ( archivo ); String line ; for ( int i = 0; i < t o t a l V o t a n t e s; i ++) { line = bLector . nextLine (); String [] s p l i t L i n e = line . split ( " \ t " ); votantes [ i ]. setId ( Integer . parseInt ( s p l i t L i n e [0])); votantes [ i ]. setSexo ( Integer . parseInt ( s p l i t L i n e [1])); } // Cerramos archivos bLector . close (); return true ; } else { return false ; } } }

IIC1103 Cap tulo 10: Simulaci on

36

Problema 13: Clientes Hotel


Enunciado Usted deber a implementar una simulaci on del comportamiento de los clientes que llegan a un hotel. En particular, deber a implementar lo necesario para controlar la utilizaci on de las piezas del hotel. El programa lo dividiremos en 3 subconjuntos incrementales. Le recomendamos no comenzar con el siguiente subconjunto hasta terminar y probar el funcionamiento correcto del subconjunto actual. Incremento 1 Su programa debe cargar del archivo habitaciones.txt el total de habitaciones del hotel. Cada l nea del archivo representa la informaci on correspondiente a una habitaci on, donde van separados por una tabulaci on6 el n umero de la habitaci on y su capacidad m axima (que var a entre 1 y 4 personas). Luego, su programa debe pedir al usuario la cantidad de habitaciones se usar an del hotel para realizar la simulaci on y la cantidad de d as que durar a la misma. Se deben usar las k primeras habitaciones del hotel, seg un el orden aparecido en el archivo. Por ejemplo, si el usuario ingresa como 20 las habitaciones que se usar an en la simulaci on, debe usar las 20 primeras habitaciones cargadas a partir del archivo de habitaciones. En caso de ingresar un n umero mayor a las habitaciones disponibles, se le debe solicitar al usuario nuevamente el valor correcto. Debe simular el paso de los d as. En cada uno de ellos pueden llegar entre 0 y 3 grupos de personas (para el primer incremento asuma que todos los grupos de persona son individuales, i.e. tienen una sola persona).7 . Seg un la cantidad de grupos que lleguen por d a debe intentar asignarles una pieza en el hotel, si no hay piezas disponibles el grupo no se aloja en el hotel. Cada vez que llega un grupo (aunque no sea asignado) se debe mostrar un mensaje en la consola, indicando el d a actual y la cantidad de personas en el grupo (en este caso siempre ser a 1). Dado que para este incremento todos los grupos son de una persona, a cada grupo puede asignarle cualquier pieza que se encuentre desocupada. Incremento 2 Cambie su programa para que soporte distintos tama nos de grupos, desde 1 a 4 personas (al crear un grupo se debe asignar al azar la cantidad de personas). Con estos cambios, para asignar una habitaci on debe seleccionar la habitaci on desocupada que permita agregar el grupo perdiendo la menor cantidad de espacios posibles. Por ejemplo, si el grupo es de 3 personas, se debe dar preferencia a las habitaciones de 3 por sobre las de 4 (por supuesto que la habitaci on debe tener capacidad igual o mayor al n umero de personas del grupo). Adem as agregue a los grupos un tiempo de estad a, el cual debe estar entre 1 y 10 d as. Luego al comenzar cada d a debe sacar de las habitaciones aquellos grupos que hayan cumplido su tiempo de estad a (esto se debe hacer antes de ver cuantos grupos llegan ese d a). Incremento 3 Ahora su simulaci on debe mostrar en consola un mensaje cuando un grupo no puede ser agregado. En ese mensaje se debe indicar el d a, la cantidad de personas en el grupo, adem as del estado del hotel. Este estado est a representado por la cantidad de habitaciones, y por la capacidad y estado de cada habitaci on. El estado de una habitaci on est a representado por su capacidad y por la cantidad de personas que la est an habitando.
6 Caracter 7 Utilice

\t, invisible al abrir el archivo con alg un editor de texto, pero detectable a la hora de recorrerlo. el m etodo Aleatorio.entero(int, int) para obtener un valor aleatorio con distribuci on uniforme.

IIC1103 Cap tulo 10: Simulaci on

37

El siguiente es un ejemplo del mensaje: Dia 4->No se pudo agregar un grupo: 4 Cantidad de piezas: 5: Pieza 1(1): 1 Pieza 2(1): Desocupada Pieza 3(4): 3 Pieza 4(3): 2 Pieza 5(4): 1 Adem as al nal de la simulaci on debe mostrar la cantidad de personas que se no pudieron tomar una habitaci on en el hotel, debido a que el grupo en que llegaron no pudo ser asignado. Su mensaje debe ser como el siguiente: Clientes Sin Disponibilidad: 18 Criterios de soluci on Posible soluci on
public class Grupo { private int n u m P e r s o n a s; private int d i a S a l i d a; public Grupo ( int num , int salida ) { n u m P e r s o n a s = num ; d i a S a l i d a = salida ; } public int g e t N u m P e r s o n a s() { return n u m P e r s o n a s; } public int g e t S a l i d a() { return d i a S a l i d a; } } public class Hotel { private Pieza [] l i s t a P i e z a s; public Pieza [] g e t L i s t a P i e z a s() { return l i s t a P i e z a s; } public Hotel ( int n u m P i e z a s) { // Creamos el arreglo de piezas l i s t a P i e z a s = new Pieza [ n u m P i e z a s]; } public boolean A g r e g a r G r u p o( Grupo grupo ) { // Buscamos una pieza donde el grupo quepa . // Partimos buscando por el tamano del grupo , // sino e n c o n t r a m o s buscamos alguna mas grande . for ( int cap = grupo . g e t N u m P e r s o n a s (); cap <= 4; cap ++) { for ( int i = 0; i < l i s t a P i e z a s. length ; i ++) { if (! l i s t a P i e z a s[ i ]. E s t a O c u p a d a() && l i s t a P i e z a s[ i ]. g e t C a p a c i d a d() == cap ) { // Ocupamos la pieza l i s t a P i e z a s[ i ]. Ocupar ( grupo ); return true ; } } } return false ; } public void D e s o c u p a r H a b i t a c i o n e s( int d i a A c t u a l) {

IIC1103 Cap tulo 10: Simulaci on

38

// R e v i s a m o s todas las h a b i t a c i o n e s ocupadas viendo si ya se cumplio el // tiempo de o c u p a c i o n for ( int i = 0; i < l i s t a P i e z a s. length ; i ++) { if ( l i s t a P i e z a s[ i ]. E s t a O c u p a d a() && l i s t a P i e z a s[ i ]. g e t G r u p o A l o j a d o (). g e t S a l i d a() == d i a A c t u a l) { // D e s o c u p a m o s la pieza l i s t a P i e z a s[ i ]. D e s o c u p a r(); } } } public String G e n e r a r E s t a d o() { String estado = " Cantidad de piezas : " + l i s t a P i e z a s. length + " :\ n " ; // A G r e g a m o s el estado de cada una de las h a b i t a c i o n e s for ( int i = 0; i < l i s t a P i e z a s. length ; i ++) { estado += " Pieza " + ( i + 1) + " ( " + l i s t a P i e z a s[ i ]. g e t C a p a c i d a d() + " ): " ; if (! l i s t a P i e z a s[ i ]. E s t a O c u p a d a()) { estado += " D e s o c u p a d a\ n " ; } else { estado += l i s t a P i e z a s[ i ]. g e t G r u p o A l o j a d o (). g e t N u m P e r s o n a s() + "\n"; } } return estado ; } } public class Pieza { private boolean ocupada ; private int c a p a c i d a d; private Grupo g r u p o A l o j a d o; private int n r o H a b i t a c i o n; public Pieza ( int cap ) { c a p a c i d a d = cap ; ocupada = false ; } public int g e t N r o H a b i t a c i o n () { return n r o H a b i t a c i o n; } public void s e t N r o H a b i t a c i o n( int n r o H a b i t a c i o n) { this . n r o H a b i t a c i o n = n r o H a b i t a c i o n; } public void s e t C a p a c i d a d( int c a p a c i d a d) { this . c a p a c i d a d = c a p a c i d a d; } public boolean E s t a O c u p a d a() { return ocupada ; } public int g e t C a p a c i d a d() { return c a p a c i d a d; } public Grupo g e t G r u p o A l o j a d o() { return g r u p o A l o j a d o; } public boolean Ocupar ( Grupo grupo ) { if (! E s t a O c u p a d a ()) { g r u p o A l o j a d o = grupo ; ocupada = true ; return true ; } return false ; } public void D e s o c u p a r() { ocupada = false ; }

IIC1103 Cap tulo 10: Simulaci on

39

} import java . io .*; import java . util . Scanner ; import i i c 1 1 0 3 P a c k a g e .*; public class P r i n c i p a l { public static void main ( String [] args ) throws I O E x c e p t i o n { // Pedimos la i n f o r m a c i o n del numero de piezas y el numero de dias de la // s i m u l a c i o n int n u m P i e z a s = Usuario . entero ( " Ingrese el numero de piezas del hotel a utilizar . " ); int t o t a l P i e z a s = n r o M a x P i e z a s( " h a b i t a c i o n e s. txt " ); while ( n u m P i e z a s > t o t a l P i e z a s) { n u m P i e z a s = Usuario . entero ( " El nro de piezas a usar debe ser menor a " + totalPiezas + " .\ nIngrese el numero de piezas a utilizar " ); } int diasSim = Usuario . entero ( " Ingrese el maximo de dias de la s i m u l a c i o n. " ); Hotel hotel = new Hotel ( n u m P i e z a s); c a r g a r P i e z a s( " h a b i t a c i o n e s. txt " , hotel , n u m P i e z a s); int p e r s o n a s P e r d i d a s = 0; for ( int d i a A c t u a l = 0; d i a A c t u a l < diasSim ; d i a A c t u a l++) { // D e s o c u p a m o s las h a b i t a c i o n e s que deban d e s o c u p a r s e este dia hotel . D e s o c u p a r H a b i t a c i o n e s( d i a A c t u a l); // R e v i s a m o s cuantos grupos llegan en el dia int n u m G r u p o s = A l e a t o r i o. entero (0 , 3); // Creamos y a g r e g a m o s todos los grupos que hayan llegado for ( int i = 0; i < n u m G r u p o s; i ++) { Grupo g = new Grupo ( A l e a t o r i o. entero (1 , 4) , d i a A c t u a l + A l e a t o r i o. entero (2 , 10)); Usuario . m e n s a j e C o n s o l a( " Dia " + d i a A c t u a l + " -> llego un nuevo grupo : " + g . g e t N u m P e r s o n a s ()); // I n t e n t a m o s agregar el grupo if (! hotel . A g r e g a r G r u p o( g )) { Usuario . m e n s a j e C o n s o l a( " Dia : " + d i a A c t u a l + " -> No se pudo agregar un grupo : " + g . g e t N u m P e r s o n a s ()); // M o s t r a m o s el estado del hotel en ese momento Usuario . m e n s a j e C o n s o l a( hotel . G e n e r a r E s t a d o ()); p e r s o n a s P e r d i d a s += g . g e t N u m P e r s o n a s (); } } } // M o s t r a m o s la cantidad de personas que no p u e d i e r o n ingresar // por falta de h a b i t a c i o n e s Usuario . m e n s a j e C o n s o l a( " Clientes Sin D i s p o n i b i l i d a d: " + p e r s o n a s P e r d i d a s); } private static int n r o M a x P i e z a s( String n o m b r e A r c h i v o) throws I O E x c e p t i o n { File archivo = new File ( n o m b r e A r c h i v o); if ( archivo . exists ()) { // Abrimos lectores Scanner bLector = new Scanner ( archivo ); int count = 0; String linea ; while ( bLector . h a s N e x t L i n e()) { linea = bLector . nextLine (); count ++; } // Cerramos archivos bLector . close (); return count ; } else { return -1; } } private static boolean c a r g a r P i e z a s( String nombreArchivo , Hotel hotel , int n r o P i e z a s) throws I O E x c e p t i o n { File archivo = new File ( n o m b r e A r c h i v o);

IIC1103 Cap tulo 10: Simulaci on

40

if ( archivo . exists ()) { // Abrimos lectores Scanner bLector = new Scanner ( archivo ); String line ; for ( int i = 0; i < n r o P i e z a s; i ++) { line = bLector . nextLine (); String [] s p l i t L i n e = line . split ( " \ t " ); hotel . g e t L i s t a P i e z a s ()[ i ] = new Pieza ( Integer . parseInt ( s p l i t L i n e [1])); hotel . g e t L i s t a P i e z a s ()[ i ]. s e t N r o H a b i t a c i o n( Integer . parseInt ( s p l i t L i n e [0])); } // Cerramos archivos bLector . close (); return true ; } else { return false ; } } }

IIC1103 Cap tulo 10: Simulaci on

41

Problema 14: Recorrido Transantiago


Enunciado Una empresa concesionaria del Transantiago quiere evaluar la posibilidad de implementar un nuevo recorrido en la zona que le ha sido asignada. El inter es est a particularmente puesto en conocer el n umero de m aquinas que deber an destinar para cumplir con un determinado nivel de satisfacci on, y conf an plenamente en las capacidades que Usted tiene para poder resolver esta interrogante con prontitud. En consecuencia, Usted frente a la demanda de los buses pertenecientes a este deber a implementar una simulaci on del desempeNo 8 nuevo recorrido, para un turno cualquiera del d a. La empresa ha realizado estudios de demanda bastante poco concluyentes, por lo que preere que Usted considere la demanda de manera muy simplicada: cada bus asignado a este nuevo recorrido tiene una capacidad para el transporte de pasajeros que oscila entre 60 y 100, y en cada paradero en la trayectoria del nuevo recorrido habr a una cantidad aleatoria de pasajeros en espera, ja para todo el turno, que oscila aleatoriamente entre 20 y 50 pasajeros. Por simplicidad, estos pasajeros llegan a los respectivos paraderos en el inicio del horario de operaci on de los buses, no llegando nuevos durante el d a. El programa lo dividiremos en 3 subconjuntos incrementales. Le recomendamos no comenzar con el siguiente subconjunto hasta terminar y probar el funcionamiento correcto del subconjunto actual. Incremento 1 Inicialmente, Ud. debe cargar del archivo buses.txt la informaci on correspondiente a los buses. Cada l nea del archivo representa la informaci on correspondiente a cada bus, donde va separado por una tabulaci on9 el id del bus, y la capacidad m axima del mismo, la que oscila entre 60 y 100, ambos inclusive. Luego, el programa debe pedir al usuario la cantidad de buses asignados al nuevo recorrido (de los previamente cargados) y tambi en la cantidad de paraderos que se encuentran en la trayectoria del nuevo recorrido. En el caso de los buses se deben usar para la simulaci on los primeros buses ya cargados (por ejemplo: si el usuario asigna 10 buses, se deben usar los primeros 10 buses cargados con el orden que aparece en el archivo buses.txt. Debe crear los Buses y Paraderos en base a la informaci on solicitada al usuario y al correspon ltimo Paradero del recorrido debe diente supuesto del modelo de demanda sugerido por la empresa10 . El u ser tal que no haya en el Pasajeros en espera, o sea, en este Paradero no debe subir ning un Pasajero al Bus y, por el contrario, deber an bajar todos los que se encuentren a bordo. Para este incremento todos los pasajeros deben bajar en el u ltimo paradero. Debe simular el itinerario de cada Bus a lo largo de su trayectoria por los Paraderos del recorrido. Cada Bus debe ser enviado sucesivamente (tras el t ermino del recorrido del Bus anterior) a realizar el recorrido, y en cada paradero deber a subir al m aximo de pasajeros que pueda de acuerdo a su capacidad disponible. Si el Bus est a lleno, no se detendr a hasta el u ltimo paradero, donde bajar an todos los pasajeros. Tras el t ermino de cada itinerario, debe mostrar la cantidad total de Pasajeros transportados por cada Bus (en este incremento este valor ser a igual al n umero de pasajeros con los que llega el bus al u ltimo paradero). Por ejemplo, una simulaci on corrida con un total de 6 Buses y 20 Paraderos, que cumple con las caracter sticas de este incremento, mostr o un mensaje como el siguiente: El Bus 1 transport o 86 pasajeros durante su recorrido
8 Un turno hace referencia a la salida de cada uno de los buses del recorrido desde el terminal de origen y sus respectivas llegadas al terminal de destino, una sola vez. 9 Caracter \t, invisible al abrir el archivo con alg un editor de texto, pero detectable a la hora de recorrerlo. 10 Recuerde que puede disponer del m etodo Aleatorio.entero(int a,int b) presente en el paquete del Curso para generar un n umero aleatorio que se encuentre entre los enteros a y b (ambos inclusive).

IIC1103 Cap tulo 10: Simulaci on

42

El El El El El

Bus Bus Bus Bus Bus

2 3 4 5 6

transport o transport o transport o transport o transport o

100 pasajeros durante su recorrido 80 pasajeros durante su recorrido 68 pasajeros durante su recorrido 74 pasajeros durante su recorrido 14 pasajeros durante su recorrido

Incremento 2 Para este incremento debe permitir que cada uno de los Pasajeros que esperan un Bus en cada Paradero tenga como destino otro Paradero del recorrido, que se determina de manera aleatoria entre el Paradero siguiente (el que sigue m as adelante, en la misma direcci on del Bus) y el u ltimo Paradero del recorrido. El bus en cada Paradero deber a bajar a los Pasajeros que corresponda, antes de subir a aquellos que se encuentran esperando. Si el Bus est a lleno, no se detendr a hasta el siguiente Paradero en que corresponda que bajen Pasajeros. Incremento 3 Debe mostrar al nalizar la simulaci on, o sea, al nalizar las trayectorias de todos los Buses, el ndice de insatisfacci on. Cada vez que un Pasajero en espera no puede subirse a un Bus que se ha detenido en el Paradero en que se encuentra (o sea, el Bus se llen o antes de que se alcanzara a subir), suma una unidad de insatisfacci on al resultado de la simulaci on; si un Bus no se detiene en un Paradero, se suman dos unidades de insatisfacci on al resultado de la simulaci on por cada Pasajero en espera que se encuentre en dicho Paradero. La empresa ha determinado que un total de unidades de insatisfacci on equivalente al doble del total de Pasajeros que participan de la simulaci on debe arrojar un ndice de insatisfacci on igual a 100 %. De esta manera, el c alculo del ndice corresponde a la relaci on porcentual entre el total de unidades de insatisfacci on resultantes de la simulaci on y el n umero de estas que la empresa considera como m aximo admisible. ndice de insatisfacci on: 13 % Criterios de soluci on Posible soluci on
public class Bus { private private private private private private int nroBus ; int c a p a c i d a d; int [] d e s t i n o P a s a j e r o s; int p a s a j e r o s T r a n s p o r t a d o s; boolean lleno ; boolean enviado ;

public Bus ( int cap , int t o t a l P a r a d e r o s) { c a p a c i d a d = cap ; d e s t i n o P a s a j e r o s = new int [ t o t a l P a r a d e r o s]; p a s a j e r o s T r a n s p o r t a d o s = 0; lleno = false ; enviado = false ; } public int g e t N r o B u s() { return nroBus ; } public void s e t N r o B u s( int nroBus ) { this . nroBus = nroBus ; } public void a c t u a l i z a r E s t a d o() {

IIC1103 Cap tulo 10: Simulaci on

43

int p a s a j e r o s A B o r d o = 0; for ( int i = 0; i < d e s t i n o P a s a j e r o s. length ; i ++) { p a s a j e r o s A B o r d o += d e s t i n o P a s a j e r o s[ i ]; } if ( p a s a j e r o s A B o r d o >= c a p a c i d a d) { lleno = true ; } else { lleno = false ; } } public boolean s u b i r P a s a j e r o( Pasajero persona ) { if ( persona == null ) { return false ; } if (! isLleno ()) { persona . s e t E n E s p e r a( false ); d e s t i n o P a s a j e r o s[ persona . g e t D e s t i n o ()]++; p a s a j e r o s T r a n s p o r t a d o s ++; a c t u a l i z a r E s t a d o (); return true ; } return false ; } public int b a j a r P a s a j e r o s( int n u m P a r a d e r o) { int p a s a j e r o s Q u e B a j a n = d e s t i n o P a s a j e r o s[ n u m P a r a d e r o]; d e s t i n o P a s a j e r o s[ n u m P a r a d e r o] = 0; a c t u a l i z a r E s t a d o (); return p a s a j e r o s Q u e B a j a n; } public int o b t e n e r C a p a c i d a d D i s p o n i b l e() { int ocupado = 0; for ( int i = 0; i < d e s t i n o P a s a j e r o s. length ; i ++) { ocupado += d e s t i n o P a s a j e r o s[ i ]; } return g e t C a p a c i d a d() - ocupado ; } public boolean isLleno () { return lleno ; } public boolean i s E n v i a d o() { return enviado ; } public void s e t E n v i a d o( boolean enviado ) { this . enviado = enviado ; } public int g e t C a p a c i d a d() { return c a p a c i d a d; } public int g e t P a s a j e r o s T r a n s p o r t a d o s() { return p a s a j e r o s T r a n s p o r t a d o s; } } import i i c 1 1 0 3 P a c k a g e .*; public class Paradero { private Pasajero [] l i s t a P a s a j e r o s; // C o n s t r u c t o r. Recibe el indice que le c o r r e s p o n d i o (" numero ") y el mayor // indice que puede tener un paradero del arreglo de p a r a d e r o s u t i l i z a d o para // modelar la demanda (" t o t a l P a r a d e r o s") , como tambien la cantidad de gente que se // e n c u e n t r a e s p e r a n d o un bus en el paradero . public Paradero ( int numero , int totalParaderos , int c a n t G e n t e) { l i s t a P a s a j e r o s = new Pasajero [ c a n t G e n t e]; for ( int i = 0; i < l i s t a P a s a j e r o s. length ; i ++) { l i s t a P a s a j e r o s[ i ] = new Pasajero ( A l e a t o r i o. entero ( numero + 1 , t o t a l P a r a d e r o s )); }

IIC1103 Cap tulo 10: Simulaci on

44

} public int o b t e n e r N u m P a s a j e r o s() { return l i s t a P a s a j e r o s. length ; } public int o b t e n e r N u m P a s a j e r o s E n E s p e r a() { int num = 0; for ( int i = 0; i < l i s t a P a s a j e r o s. length ; i ++) { if ( l i s t a P a s a j e r o s[ i ]. i s E n E s p e r a ()) { num ++; } } return num ; } // Retorna el primer pasajero " en espera " del paradero public Pasajero s i g u i e n t e P a s a j e r o() { for ( int i = 0; i < l i s t a P a s a j e r o s. length ; i ++) { if ( l i s t a P a s a j e r o s[ i ]. i s E n E s p e r a ()) { return l i s t a P a s a j e r o s[ i ]; } } return null ; } } public class Pasajero { private int destino ; private boolean enEspera ; // C o n s t r u c t o r. Recibe el indice del paradero de destino c o r r e s p o n d i e n t e al // arreglo de p a r a d e r o s u t i l i z a d o para modelar la demanda . public Pasajero ( int p a r a d e r o D e s t i n o) { destino = p a r a d e r o D e s t i n o; // Se e s t a b l e c e i n i c i a l m e n t e su estado como " en espera " , que cambiara // solo si puede subirse a un bus del r e c o r r i d o. enEspera = true ; } public int g e t D e s t i n o() { return destino ; } public boolean i s E n E s p e r a() { return enEspera ; } public void s e t E n E s p e r a( boolean enEspera ) { this . enEspera = enEspera ; } } import java . io .*; import java . util . Scanner ; import i i c 1 1 0 3 P a c k a g e .*; public class P r i n c i p a l { public static void main ( String [] args ) throws I O E x c e p t i o n { // Pedimos la i n f o r m a c i o n n e c e s a r i a al usuario int numBuses = Usuario . entero ( " Ingrese el numero de buses del r e c o r r i d o: " ); int t o t a l B u s e s = n r o M a x B u s e s( " buses . txt " ); while ( numBuses > t o t a l B u s e s) { numBuses = Usuario . entero ( " El nro de buses a asignar debe ser menor a " + totalBuses + " .\ nIngrese el numero de buses que tiene el r e c o r r i d o: " ); } int n u m P a r a d e r o s = Usuario . entero ( " Ingrese el numero de p a r a d e r o s que recorre " + " un bus del r e c o r r i d o: " ); // Creamos los Buses del R e c o r r i d o Bus [] l i s t a B u s e s = new Bus [ numBuses ]; c a r g a r B u s e s( " buses . txt " , listaBuses , numBuses , n u m P a r a d e r o s);

IIC1103 Cap tulo 10: Simulaci on

45

// Creamos los P a r a d e r o s del R e c o r r i d o Paradero [] p a r a d e r o s = new Paradero [ n u m P a r a d e r o s]; for ( int i = 0; i < n u m P a r a d e r o s - 1; i ++) { p a r a d e r o s[ i ] = new Paradero (i , n u m P a r a d e r o s - 1 , A l e a t o r i o. entero (20 , 50)); } // en el ultimo paradero no se toman p a s a j e r o s. p a r a d e r o s[ n u m P a r a d e r o s - 1] = new Paradero (0 , 0 , 0); // V a r i a b l e s para la e v a l u a c i o n del r e n d i m i e n t o int n u m P a s a j e r o s S i m = 0; for ( int i = 0; i < n u m P a r a d e r o s; i ++) { n u m P a s a j e r o s S i m += p a r a d e r o s[ i ]. o b t e n e r N u m P a s a j e r o s(); } int d e s c o n t e n t o = 0; // Para cada bus del r e c o r r i d o for ( int bus = 0; bus < l i s t a B u s e s. length ; bus ++) { Bus b u s A c t u a l = l i s t a B u s e s[ bus ]; // r e c o r r e m o s todos los p a r a d e r o s for ( int p a r a d e r o A c t u a l = 0; p a r a d e r o A c t u a l < p a r a d e r o s. length ; p a r a d e r o A c t u a l ++) { // Hacemos d e s c e n d e r a los p a s a j e r o s que tenian como destino // este paradero . int p a s a j e r o s Q u e B a j a n = b u s A c t u a l. b a j a r P a s a j e r o s( p a r a d e r o A c t u a l); Si no c o r r e s p o n d e que bajen pasajeros , vemos si el bus esta lleno , caso en el cual debemos c o n s i d e r a r el ( doble ) d e s c o n t e n t o de todos los p a s a j e r o s al ver que el bus sigue de largo y no para . ( p a s a j e r o s Q u e B a j a n == 0 && b u s A c t u a l. isLleno ()) { d e s c o n t e n t o = 2 * p a r a d e r o s[ p a r a d e r o A c t u a l]. o b t e n e r N u m P a s a j e r o s(); } else { // I n t e n t a m o s subir al maximo de p a s a j e r o s posible for ( int i = 0; i < p a r a d e r o s[ p a r a d e r o A c t u a l] . o b t e n e r N u m P a s a j e r o s(); i ++) { if (! b u s A c t u a l. s u b i r P a s a j e r o( p a r a d e r o s[ p a r a d e r o A c t u a l] . s i g u i e n t e P a s a j e r o ())) { // Si el bus se llena subiendo pasajeros , el resto // de los p a s a j e r o s que no alcanzo a subir quedara d e s c o n t e n t o. d e s c o n t e n t o += p a r a d e r o s[ p a r a d e r o A c t u a l] . o b t e n e r N u m P a s a j e r o s E n E s p e r a (); break ; } } } } // Cantidad total de p a s a j e r o s t r a n s p o r t a d o s por el Bus durante su // i t i n e r a r i o. Usuario . m e n s a j e C o n s o l a( " El Bus " + ( bus + 1) + " t r a n s p o r t o " + l i s t a B u s e s[ bus ]. g e t P a s a j e r o s T r a n s p o r t a d o s () + " p a s a j e r o s durante su r e c o r r i d o" ); } // Datos sobre la calidad del servicio brindado durante un turno de la jornada float i n d i c e I n s a t i s f a c c i o n = ( float ) d e s c o n t e n t o * 100 / (2 * n u m P a s a j e r o s S i m); Usuario . m e n s a j e C o n s o l a( " indice de i n s a t i s f a c c i o n: " + i n d i c e I n s a t i s f a c c i o n + " %" ); } private static int n r o M a x B u s e s( String n o m b r e A r c h i v o) throws I O E x c e p t i o n { File archivo = new File ( n o m b r e A r c h i v o); if ( archivo . exists ()) { // Abrimos lectores Scanner bLector = new Scanner ( archivo ); int count = 0; String linea ; while ( bLector . h a s N e x t L i n e ()){ linea = bLector . nextLine (); count ++; } // Cerramos archivos bLector . close (); return count ; } else { return -1; } } // // // if

IIC1103 Cap tulo 10: Simulaci on

46

private static boolean c a r g a r B u s e s( String nombreArchivo , Bus [] listaBuses , int nroBuses , int n u m P a r a d e r o s) throws I O E x c e p t i o n { File archivo = new File ( n o m b r e A r c h i v o); if ( archivo . exists ()) { // Abrimos lectores Scanner bLector = new Scanner ( archivo ); String line ; for ( int i = 0; i < nroBuses ; i ++) { line = bLector . nextLine (); String [] s p l i t L i n e = line . split ( " \ t " ); l i s t a B u s e s[ i ] = new Bus ( Integer . parseInt ( s p l i t L i n e[1]) , n u m P a r a d e r o s); l i s t a B u s e s[ i ]. s e t N r o B u s( Integer . parseInt ( s p l i t L i n e [0])); } // Cerramos archivos bLector . close (); return true ; } else { return false ; } } }

IIC1103 Cap tulo 10: Simulaci on

47

Problema 15: Casino


Enunciado Usted deber a implementar una simulaci on del funcionamiento de un casino con una serie de m aquinas tragamonedas. El programa lo dividiremos en 3 subconjuntos incrementales. Le recomendamos no comenzar con el siguiente subconjunto hasta terminar y probar el funcionamiento correcto del subconjunto actual. Incremento 1 Su programa deber a pedir al usuario la cantidad de m aquinas tragamonedas al iniciar la simulaci on y el tiempo en minutos que durar a la simulaci on. Cada m aquina se podr a usar una vez por minuto, y costar a 100 su uso. Las m aquinas tendr an 3 pantallas, donde cada una mostrar a uno de los 15 posibles s mbolos, los cuales deben estar numerados del 1 al 15. Cuando el s mbolo en cada pantalla es el mismo, para algunos s mbolos, el jugador ganar a dinero. Si el s mbolo repetido en las 3 pantallas es el 7 ganar a 10 veces la apuesta, si es el 14, ganar a 1000 veces la apuesta, y si es el 15 ganar a 10000 veces lo apostado. Si es otro, simplemente recuperar a lo apostado (para este incremento ser an 100). Para este incremento asuma que llega un jugador por minuto al casino con dinero aleatorio entre 1000 y 100000. Este jugador intentar a sentarse en una m aquina, pero en caso de no haber ninguna vac a se retirar a del casino. En caso de sentarse en una m aquina jugar a durante cada minuto hasta que se le acabe el dinero. Al momento de que llegue un nuevo jugador debe mostrar en consola el tiempo de la simulaci on, as como el dinero con el cual ingresa. Cuando se retira un jugador, debe indicar el tiempo en que lo realiza y la cantidad de minutos que estuvo en el casino. Incremento 2 Para este incremento la llegada de jugadores por minuto ser a un valor aleatorio entre 0 y 10. Adem as las apuestas ya no ser an siempre 100, sino que depender an de la cantidad de dinero que tenga el jugador. En caso de tener menos de 5000 seguir a siempre apostando 100, si tiene entre 5000 y 10000 la apuesta ser a de 200, si tiene entre 10000 y 50000 apostar a la mitad de las veces 200 y la otra mitad 1000. Finalmente, si tiene m as de 50000, el 20 % apostar a 10000, el 30 % apostar a 1000 y el resto de las veces apostar a 500. El dinero inicial de cada jugador se debe cargar a partir del archivo dinero inicial.txt donde la k esima l nea representa el dinero del k- esimo jugador. En caso de superar el total de l neas del archivo, se debe partir nuevamente por la primera y as sucesivamente. Tambi en los jugadores podr an retirarse sin necesidad de perder todo el dinero, en caso de tener m as de 100000 habr a un 10 % de probabilidades de que un jugador se retire hacia su casa en cada minuto. En este caso debe mostrar un mensaje en consola indicando el dinero que se lleva el jugador. Incremento 3 Finalmente debe considerar que los jugadores pueden esperar por un tragamoneda hasta 20 minutos antes de retirarse. Se debe mantener la prioridad de utilizar los tragamonedas desocupados para aquellos que est en esperando IIC1103 Cap tulo 10: Simulaci on 48

durante m as tiempo. Adem as, cada 10 minutos deber a mostrar en consola el porcentaje de tragamonedas que se encuentran utilizados y la cantidad de jugadores esperando. Adem as, al nalizar su simulaci on se deber a mostrar en consola la siguiente informaci on: Cantidad de personas que jugaron en las m aquinas. Cantidad de personas que se fueron sin jugar. Tiempo de espera promedio para poder utilizar una m aquina. Tiempo promedio de utilizaci on de las m aquinas. La cantidad promedio de dinero ganado por hora por el casino (se deben restar los ingresos a los egresos). Criterios de soluci on Posible soluci on
import i i c 1 1 0 3 P a c k a g e .*; public class Casino { // Las maquinas private T r a g a m o n e d a s[] maquinas ; /* * * Constructor * * @param n u m M a q u i n a s * la cantidad de t r a g a m o n e d a s */ public Casino ( int n u m M a q u i n a s) { maquinas = new T r a g a m o n e d a s[ n u m M a q u i n a s]; for ( int i = 0; i < maquinas . length ; i ++) { maquinas [ i ] = new T r a g a m o n e d a s(); } } // Busca maquina libre y la retorna public T r a g a m o n e d a s b u s c a r M a q u i n a L i b r e() { for ( int i = 0; i < maquinas . length ; i ++) { if (! maquinas [ i ]. e s t a O c u p a d a()) { return maquinas [ i ]; } } return null ; } // Cuenta cuantas maquinas ocupadas o libres hay public int c o n t a r M a q u i n a s( boolean ocupadas ) { int total = 0; for ( int i = 0; i < maquinas . length ; i ++) { if ( maquinas [ i ]. e s t a O c u p a d a() == ocupadas ) { total ++; } } return total ; } // Usa todas las maquinas que esten con personas public void u s a r M a q u i n a s( int tiempo ){ for ( int i =0; i < maquinas . length ; i ++){ if ( maquinas [ i ]. e s t a O c u p a d a ()){ int ganancia = maquinas [ i ]. usar (); if ( ganancia > 0) { Usuario . m e n s a j e C o n s o l a( " Minuto " + tiempo + " : una persona gano " + ganancia );

IIC1103 Cap tulo 10: Simulaci on

49

} } } } /* * Revisa todas las maquinas , y hace que se vayan las personas que deben irse */ public void r e v i s a r P e r s o n a s V a n() { for ( int i = 0; i < maquinas . length ; i ++) { if ( maquinas [ i ]. e s t a O c u p a d a()) { // Si se le acabo el dinero , se va if ( maquinas [ i ]. g e t D i n e r o P e r s o n a() == 0) { maquinas [ i ]. d e s o c u p a r(); } else { // Segun el dinero que tenga , r e v i s a m o s si se va int prob = A l e a t o r i o. entero (0 , 100); if ( maquinas [ i ]. g e t D i n e r o P e r s o n a() < 50000 && prob < 20) { maquinas [ i ]. d e s o c u p a r(); } else if ( maquinas [ i ]. g e t D i n e r o P e r s o n a () < 500000 && prob < 10) { maquinas [ i ]. d e s o c u p a r(); } } } } } // Retorna el total de dinero ganado por el casino public int g e t T o t a l D i n e r o G a n a d o() { int suma = 0; for ( int i = 0; i < maquinas . length ; i ++) { suma += maquinas [ i ]. g e t D i n e r o R e c a u d a d o (); } return suma ; } // Retorna el dinero perdido por el casino public int g e t T o t a l D i n e r o P e r d i d o() { int suma = 0; for ( int i = 0; i < maquinas . length ; i ++) { suma += maquinas [ i ]. g e t D i n e r o P e r d i d o (); } return suma ; } } import i i c 1 1 0 3 P a c k a g e .*; public class T r a g a m o n e d a s { // El dinero que ha entrado a la maquina private int d i n e r o R e c a u d a d o = 0; private int d i n e r o P e r d i d o = 0; private int d i n e r o P e r s o n a = 0; private boolean ocupada = false ; /* * Simula el f u n c i o n a m i e n t o de la maquina * @return la cantidad de dinero ganado */ public int usar () { // A u m e n t a m o s dinero interno d i n e r o R e c a u d a d o += 100; d i n e r o P e r s o n a -= 100; if ( d i n e r o P e r s o n a < 0) { d i n e r o P e r s o n a = 0; } // R e s u l t a d o s a l e a t o r i o s de cada pantalla int res1 = A l e a t o r i o. entero (1 , 15); int res2 = A l e a t o r i o. entero (1 , 15); int res3 = A l e a t o r i o. entero (1 , 15); // C a l c u l a m o s si gano , y cuanto gano int ganancia = 0; if (( res1 == res2 ) && ( res2 == res3 )) { if ( res1 == 14) { ganancia = 10000; } else if ( res1 == 15) { ganancia = 100000;

IIC1103 Cap tulo 10: Simulaci on

50

} } d i n e r o P e r d i d o += ganancia ; d i n e r o P e r s o n a += ganancia ; return ganancia ; } // Retorna el dinero r e c a u d a d o public int g e t D i n e r o R e c a u d a d o () { return d i n e r o R e c a u d a d o; } // Retorna el dinero r e c a u d a d o public int g e t D i n e r o P e r d i d o () { return d i n e r o P e r d i d o; } // Retorna el dinero que tiene la persona i n s t a l a d a public int g e t D i n e r o P e r s o n a () { return d i n e r o P e r s o n a; } // Revisa si esta ocupada public boolean e s t a O c u p a d a() { return ocupada ; } // Ocupa la maquina con un jugador public void ocupar ( int d i n e r o O c u p a n t e) { ocupada = true ; d i n e r o P e r s o n a = d i n e r o O c u p a n t e; } // Desocupa la maquina public void d e s o c u p a r() { ocupada = false ; d i n e r o P e r s o n a = 0; } } import java . io . File ; import java . io . I O E x c e p t i o n; import java . util . Scanner ; import i i c 1 1 0 3 P a c k a g e .*; public class P r i n c i p a l { // Arreglo de dineros iniciales , a usar en el i n c r e m e n t o 2 static int [] d i n e r o s I n i c i a l e s; // Main del programa public static void main ( String [] args ) throws I O E x c e p t i o n { // O b t e n e m o s info del usuario int n u m M i n u t o s = Usuario . entero ( " Ingrese el numero de minutos a simular : " ); int n u m M a q u i n a s = Usuario . entero ( " Ingrese el numero de maquinas a simular : " ); // Creamos casino Casino caesars = new Casino ( n u m M a q u i n a s); int t o t a l J u g a d o r e s = 0; int t o t a l F u e r o n = 0; // Cargamos los dineros i n i c i a l e s ( para usarlos en el i n c r e m e n t o 2) c a r g a r D i n e r o s( " d i n e r o _ i n i c i a l. txt " ); // Ciclo for ( int minutos = 0; minutos < n u m M i n u t o s; minutos ++) { // Vemos maquinas ocupadas y no if ( minutos % 10 == 0) { Usuario . m e n s a j e C o n s o l a( " Minuto " + minutos + " : " + caesars . c o n t a r M a q u i n a s( true ) + " maquinas ocupadas , " + caesars . c o n t a r M a q u i n a s( false ) + " maquinas d e s o c u p a d a s. " ); } // Vemos personas que se van

IIC1103 Cap tulo 10: Simulaci on

51

caesars . r e v i s a r P e r s o n a s V a n(); // Vemos cuantas personas llegaron int c a n t P e r s o n a s = A l e a t o r i o. entero (0 , 10); for ( int i = 0; i < c a n t P e r s o n a s; i ++) { // Vemos donde poner persona , y si juega o se va T r a g a m o n e d a s maquina = caesars . b u s c a r M a q u i n a L i b r e(); if ( maquina != null ) { // En i n c r e m e n t o 2 se deben usar los dineros cargados a // partir del archivo maquina . ocupar ( d i n e r o s I n i c i a l e s[ t o t a l J u g a d o r e s % d i n e r o s I n i c i a l e s. length ]); t o t a l J u g a d o r e s ++; } else { t o t a l F u e r o n ++; } } // Jugamos caesars . u s a r M a q u i n a s( minutos ); } // E s t a d i s t i c a s Usuario . m e n s a j e C o n s o l a( " \ nEl total de personas que jugaron es de " + t o t a l J u g a d o r e s + " personas " ); Usuario . m e n s a j e C o n s o l a( " El total de personas que no pudieron jugar es de " + t o t a l F u e r o n + " personas " ); Usuario . m e n s a j e C o n s o l a( " El total de dinero neto ganado por el casino es de " + ( caesars . g e t T o t a l D i n e r o G a n a d o() - caesars . g e t T o t a l D i n e r o P e r d i d o ())); Usuario . m e n s a j e C o n s o l a( " El dinero promedio ganado por el casino por hora es de " + ( caesars . g e t T o t a l D i n e r o G a n a d o() - caesars . g e t T o t a l D i n e r o P e r d i d o()) / ( n u m M i n u t o s / 60.0)); } // I n c r e m e n t o 2 private static int c u e n t a D i n e r o s I n i c i a l e s( String n o m b r e A r c h i v o) throws I O E x c e p t i o n { File archivo = new File ( n o m b r e A r c h i v o); if ( archivo . exists ()) { // Abrimos lectores Scanner bLector = new Scanner ( archivo ); int count = 0; String linea ; while ( bLector . h a s N e x t L i n e()) { linea = bLector . nextLine (); count ++; } // Cerramos archivos bLector . close (); return count ; } else { return -1; } } // I n c r e m e n t o 2 private static boolean c a r g a r D i n e r o s( String n o m b r e A r c h i v o) File archivo = new File ( n o m b r e A r c h i v o); if ( archivo . exists ()) { // Abrimos lectores Scanner bLector = new Scanner ( archivo );

throws I O E x c e p t i o n {

int t o t a l D i n e r o s = c u e n t a D i n e r o s I n i c i a l e s( n o m b r e A r c h i v o); d i n e r o s I n i c i a l e s = new int [ t o t a l D i n e r o s]; for ( int i = 0; i < t o t a l D i n e r o s; i ++) { d i n e r o s I n i c i a l e s[ i ] = Integer . parseInt ( bLector . nextLine ()); } // Cerramos archivos bLector . close (); return true ; } else { return false ; }

IIC1103 Cap tulo 10: Simulaci on

52

} }

IIC1103 Cap tulo 10: Simulaci on

53

Problema 16: Parque de diversiones


Enunciado Usted deber a realizar una simulaci on del funcionamiento de un parque de diversiones con diversas atracciones y gente que las utiliza. El programa lo dividiremos en 3 subconjuntos incrementales. Le recomendamos no comenzar con el siguiente subconjunto hasta terminar y probar el funcionamiento correcto del subconjunto actual. Incremento 1 Su programa deber a realizar una simulaci on de 12 horas de funcionamiento, asumiendo que cada 10 minutos llega un n umero aleatorio de personas entre 0 y 15, durante las primeras 6 horas. Durante las siguientes 6 horas no llega m as gente. La cantidad de atracciones debe solic tasela al usuario al comenzar la simulaci on. Para cada atracci on deber a calcular aleatoriamente su capacidad en el rango [10, 30], y adem as deber a calcular su atractivo el cual ser a un valor entero entre 0 y 100 y cuya suma entre las atracciones siempre ser a 10011 (no se utilizar a en este incremento). Las personas elijen una atracci on de forma aleatoria y se ponen a la la para poder ingresar a ella. Al nalizar el tiempo de uso de esa atracci on buscan otra. Su programa deber a mostrar un mensaje cada vez que llega un grupo de personas, indicando el tiempo y la cantidad. Adem as deber a mostrar un mensaje cuando cada atracci on comienza a funcionar indicando la capacidad utilizada y la cantidad de personas esperando por ella. Incremento 2 Para este incremento deber a considerar que despu es de utilizar una atracci on, las personas descansan durante 10 minutos antes de elegir otra atracci on. En las u ltimas 6 horas es posible que algunos de los que est an descansando decida irse del parque, existiendo una probabilidad de un 5 % de que cada uno de los que est a descansando decida irse. Debe mostrar un mensaje en consola por cada persona que se retira, indicando el tiempo que estuvo en el parque y cuantas atracciones utiliz o. Adem as deber a considerar el atractivo de cada atracci on para que las personas elijan dicha atracci on. De esta forma, el atractivo indicar a la probabilidad de que elijan esa atracci on en comparaci on con las otras atracciones. Por ejemplo, si el atractivo de la atracci on A es 50, el de la B es 30 y el de la C es 20, entonces una persona tendr a un 50 % de posibilidades de escoger la atracci on A, un 30 % de escoger la B y un 20 % de escoger la C. Incremento 3 Finalmente deber a considerar que las personas tienen una tolerancia m axima de espera, de esta forma, si la cola del juego elegido es mayor al triple de la capacidad de ese juego, entonces preeren elegir otra atracci on
11 Para lograr que la suma siempre sea 100, puede primero asignar un valor aleatorio entre 0 y 100 a cada atracci on y luego 100 normalizar dichos valores multiplic andolos por Suma , donde Suma es la suma de los atractivos calculados para todas las atracciones

IIC1103 Cap tulo 10: Simulaci on

54

antes de esperar todo ese tiempo. Si ninguna atracci on cumple con tener una cola de tama no adecuado, entonces se retiran del parque. Adem as debe considerar que cada persona utilizar a a lo m as 3 veces cada atracci on. Por u ltimo, su programa, al nalizar la simulaci on debe mostrar en consola: Cantidad de personas que entraron al parque. Cantidad de personas que se fueron del parque antes de que cerrara. Tiempo promedio de estad a de las personas en el parque. Cantidad promedio de atracciones utilizadas por las personas en su estad a. Para cada atracci on, el porcentaje promedio de utilizaci on en cada funcionamiento, y el largo promedio de la cola de espera. Criterios de soluci on Posible soluci on
public class A t r a c c i o n { // A t r i b u t o s private String nombre ; private int a t r a c t i v o; private int p e r s o n a s U s a n d o; private int p e r s o n a s E n C o l a; /* * C o n s t r u c t o r * @param sNombre el nombre * @param n A t r a c t i v o el atractivo , de 0 a 100 */ public A t r a c c i o n( String sNombre , int n A t r a c t i v o) { nombre = sNombre ; a t r a c t i v o = n A t r a c t i v o; p e r s o n a s U s a n d o = p e r s o n a s E n C o l a = 0; } // Retorna nombre public String g e t N o m b r e() { return nombre ; } // Retorna a t r a c t i v o public int g e t A t r a c t i v o() { return a t r a c t i v o; } // Retorna personas en la a t r a c c i o n public int g e t P e r s o n a s E n U s o () { return p e r s o n a s U s a n d o; } // Retorna personas en cola public int g e t P e r s o n a s E n C o l a () { return p e r s o n a s E n C o l a; } // Setea personas en la a t r a c c i o n public void s u b i r P e r s o n a s() { if ( p e r s o n a s E n C o l a - 10 < 0) { p e r s o n a s U s a n d o = p e r s o n a s E n C o l a; p e r s o n a s E n C o l a = 0; } else { p e r s o n a s U s a n d o = 10; p e r s o n a s E n C o l a -= 10; } } // Aumenta la cola public void a u m e n t a r C o l a( int personas ) { p e r s o n a s E n C o l a += personas ;

IIC1103 Cap tulo 10: Simulaci on

55

} } import java . io .*; import java . util . Scanner ; import i i c 1 1 0 3 P a c k a g e .*; public class Parque { // A t r i b u t o s private A t r a c c i o n[] a t r a c c i o n e s; private int c a n t A t r a c c i o n e s = 0; private int p e r s o n a s D e a m b u l a n d o = 0; private double s u m a P r o m e d i o C o l a = 0.0; // C o n s t r u c t o r public Parque () throws I O E x c e p t i o n { // Creamos a t r a c c i o n e s = new A t r a c c i o n [30]; for ( int i = 0; i < a t r a c c i o n e s. length ; i ++) { a t r a c c i o n e s[ i ] = null ; } // Abrimos archivo y r e v i s a m o s si existe File archivo = new File ( " a t r a c c i o n e s. txt " ); if ( archivo . exists ()) { // Abrimos lectores Scanner bLector = new Scanner ( archivo ); // Leemos cada linea String linea ; while ( bLector . h a s N e x t L i n e()) { linea = bLector . nextLine (); int posGuion = linea . indexOf ( " -" ); a t r a c c i o n e s[ c a n t A t r a c c i o n e s++] = new A t r a c c i o n( linea . s u b s t r i n g( 0 , posGuion ) , Integer . parseInt ( linea . s u b s t r i n g( posGuion + 1))); } // Cerramos archivos bLector . close (); } } // Simula llegada de nuevas personas public void l l e g a d a P e r s o n a s( int n u e v a s P e r s o n a s) { p e r s o n a s D e a m b u l a n d o += n u e v a s P e r s o n a s; } // Hace que se vayan personas de las deambulantes , // y retorna cuantas r e a l m e n t e se fueron public int i d a P e r s o n a s( int personas ) { int seVan ; if ( p e r s o n a s D e a m b u l a n d o - personas < 0) { seVan = p e r s o n a s D e a m b u l a n d o; } else { seVan = personas ; } p e r s o n a s D e a m b u l a n d o -= seVan ; return seVan ; } // Hace que cada persona d e a m b u l a n d o elija una a t r a c c i o n public void e l e g i r A t r a c c i o n e s() { for (; p e r s o n a s D e a m b u l a n d o > 0; p e r s o n a s D e a m bu la nd o - -) { // Calcula p r o b a b i l i d a d para esa persona int prob = A l e a t o r i o. entero (1 , 100); int rango = 0; for ( int j = 0; j < c a n t A t r a c c i o n e s; j ++) { // Revisa si p r o b a b i l i d a d esta en un rango c o r r e s p o n d i e n t e if (( rango < prob ) && ( prob <= rango + a t r a c c i o n e s[ j ]. g e t A t r a c t i v o ())) { a t r a c c i o n e s[ j ]. a u m e n t a r C o l a (1); break ; } rango += a t r a c c i o n e s[ j ]. g e t A t r a c t i v o ();

IIC1103 Cap tulo 10: Simulaci on

56

} } a c t u a l i z a r P r o m e d i o C o l a (); } // Baja gente de una atraccion , y sube las de la cola public void b a j a r Y S u b i r() { // Baja a las personas que habia y las deja como d e a m b u l a n d o; sube gente // de la cola for ( int i = 0; i < c a n t A t r a c c i o n e s; i ++) { p e r s o n a s D e a m b u l a n d o += a t r a c c i o n e s[ i ]. g e t P e r s o n a s E n U s o (); a t r a c c i o n e s[ i ]. s u b i r P e r s o n a s(); } } // A c t u a l i z a el promedio de las colas ( en estricto rigor , va sumando los p r o m e d i o s) public void a c t u a l i z a r P r o m e d i o C o l a() { int suma = 0; for ( int i = 0; i < c a n t A t r a c c i o n e s; i ++) { suma += a t r a c c i o n e s[ i ]. g e t P e r s o n a s E n C o l a (); } s u m a P r o m e d i o C o l a += ( double ) (( double ) suma / ( double ) c a n t A t r a c c i o n e s); } // Retorna el promedio total de las colas en cada i n t e r v a l o durante toda la // s i m u l a c i o n public double g e t P r o m e d i o C o l a() { return s u m a P r o m e d i o C o l a / (12.0 * 60.0 / 10.0); } // Muestra info de personas d e a m b u l a n d o y en cola public void m o s t r a r I n f o( int tiempo ) { String mensaje = " Minuto " + tiempo + " : Hay " + p e r s o n a s D e a m b u l a n d o + " personas d e a m b u l a n d o. Largo de cada cola : \ n " ; for ( int i = 0; i < c a n t A t r a c c i o n e s; i ++) { mensaje += a t r a c c i o n e s[ i ]. g e t N o m b r e() + " : " + a t r a c c i o n e s[ i ]. g e t P e r s o n a s E n C o l a() + " personas ; " ; } Usuario . m e n s a j e C o n s o l a( mensaje ); } } import i i c 1 1 0 3 P a c k a g e .*; import java . io .*; public class P r i n c i p a l { // Main del programa public static void main ( String [] args ) throws I O E x c e p t i o n { // Creamos parque Parque disney = new Parque (); int t o t a l E n t r a r o n = 0; int t o t a l F u e r o n = 0; // Ciclo for ( int minutos = 0; minutos < 60 * 12; minutos += 10) { // G e n e r a m o s nuevas personas que llegan int n u e v a s P e r s o n a s = 0; if ( minutos <= 60 * 6) { n u e v a s P e r s o n a s = A l e a t o r i o. entero (0 , 30); } disney . l l e g a d a P e r s o n a s( n u e v a s P e r s o n a s); t o t a l E n t r a r o n += n u e v a s P e r s o n a s; // La gente d e a m b u l a n d o elige y se va a la cola , la usando se baja , // y se suben de la cola disney . e l e g i r A t r a c c i o n e s (); disney . b a j a r Y S u b i r (); // Vemos cuantos se van if ( minutos > 60 * 6) { int p e r s o n a s V a n = A l e a t o r i o. entero (1 , 5); disney . i d a P e r s o n a s( p e r s o n a s V a n); t o t a l F u e r o n += p e r s o n a s V a n; }

IIC1103 Cap tulo 10: Simulaci on

57

// M o s t r a m o s info disney . m o s t r a r I n f o( minutos ); } // E s t a d i s t i c a s Usuario . m e n s a j e C o n s o l a( " \ nEl total de personas que entraron al parque es de " + t o t a l E n t r a r o n + " personas " ); Usuario . m e n s a j e C o n s o l a( " El total de personas que se fueron antes de cerrar es de " + t o t a l F u e r o n + " personas " ); Usuario . m e n s a j e C o n s o l a( " El largo promedio de las colas es de " + disney . g e t P r o m e d i o C o l a ()); } }

IIC1103 Cap tulo 10: Simulaci on

58

Problema 17: Cine


Enunciado El due no del cine CineMarc est a preocupado por las quejas que ha recibido de parte de sus clientes debido a que suele pasar que entran atrasados a las pel culas. Para analizar c omo solucionar el problema, le ha solicitado a usted que simule el funcionamiento de su cine durante un d a, y en particular el proceso de compra de entradas. Al due no le interesa principalmente saber como afecta el n umero de vendedores y el tiempo que toman en vender las entradas, en los atrasos de sus clientes. El programa lo dividiremos en 3 subconjuntos incrementales. Le recomendamos no comenzar con el siguiente subconjunto hasta terminar y probar el funcionamiento correcto del subconjunto actual. Incremento 1 Para comenzar, usted deber a implementar todo lo necesario para que se simule la llegada de clientes a comprar entradas al cine (la venta de entradas y atenci on de clientes no se deben implementar a un). En este incremento, debe considerar las siguientes caracter sticas del cine CineMarc: Asuma que el cine tiene s olo una sala, pero en esta sala se van cambiando las pel culas a lo largo del d a. Los clientes que van a comprar entradas a una pel cula comienza a llegar una hora antes de que comience y dejan de llegar cuando esta ha comenzado. La llegada de clientes para ver una determinada pel cula est a determinada por su popularidad. Cada pel cula tiene asignado un ndice de popularidad p, el cual toma valores entre 0 y 100. Desde 1 hora antes hasta que comienza la pel cula, en cada minuto que transcurre existe una probabilidad de p % de que llegue un nuevo cliente a ver esa pel cula. Por ejemplo, si una determinada pel cula tiene un ndice de 50, cada minuto que transcurre desde una hora antes que comience la funci on, habr a un 50 % de que llegue un cliente. Los clientes a medida que llegan, se colocan en una la u nica. La cartelera de pel culas para el d a que se quiere simular debe cargarla del archivo denominado cartelera.txt, donde cada l nea representa la informaci on de una pel cula. La informaci on almacenada por l nea es (en este orden) el nombre, hora de inicio, hora de t ermino y popularidad. Cada uno de estos campos se encuentra separado por el s mbolo %. Adem as de lo anterior, al nalizar la simulaci on su programa debe mostrar ciertas estad sticas relevantes: el n umero total de clientes del d a, as como el n umero de personas que fueron a ver cada una de las pel culas. Incremento 2 En este incremento, Ud. debe considerar las siguientes caracter sticas en su simulaci on, complementarias a las del incremento 1: El cine tiene ahora la posibilidad de contar con m as de una sala, que operan bajo las mismas condiciones que en el incremento 1. Para ello, su programa debe solicitar al usuario el n umero de salas que desea tener el cine, antes de comenzar con la simulaci on. La posibilidad de entrar a cada sala distribuye de manera uniforme (i.e. es equiprobable entrar a cualquier sala). Cada una de las salas tiene una capacidad limitada (entre 80 y 120 asistentes) por funci on. Su programa debe asignarle su capacidad a cada sala, de forma aleatoria. En el caso de que un asistente desee entrar IIC1103 Cap tulo 10: Simulaci on 59

a la funci on en una determinada sala, y no pueda, su programa debe escoger otra sala, hasta que encuentre alguna con espacio. Si no existe ninguna sala con espacio, se debe informar en consola que existi o un cliente que no pudo entrar ver la pel cula, adem as de agregar dentro de las estad sticas nales el n umero total de clientes no satisfechos con ingresar a ver alguna pel cula por esta causa. Incremento 3 Ahora que tiene implementada la simulaci on de la llegada de clientes, es el momento de agregar la venta de entradas, de manera de poder obtener la informaci on que el due no del cine necesita. Para vender las entradas existe un n umero N de vendedores, los cuales demoran un tiempo aleatorio para atender a los clientes, entre 1 y TMax minutos. Cada vez que haya un vendedor desocupado, el primer cliente de la la u nica pasa a ser atendido por este. El vendedor podr a volver a atender a un nuevo cliente luego de que haya pasado el tiempo de atenci on asociado al cliente actual. Cada vez que un vendedor atiende a un cliente, su tiempo de atenci on para el siguiente debe ser recalculado. Note que antes de vender la entrada, se debe validar que exista capacidad en alguna de las salas, para que pueda ingresar el cliente. Si no existe espacio, no se debe vender la entrada, y el cliente se retira de la la, dando paso al siguiente. Su programa debe permitir que los valores N y TMax sean ingresados por el usuario. Adem as al nalizar deber a mostrar las estad sticas de cu antos clientes entraron atrasados a la pel cula y cu antos entraron a la hora. Criterios de soluci on Posible soluci on
public class Cliente { private Hora m _ h o r a L l e g a d a; private Hora m _ h o r a C o m p r a E n t r a d a; private Pelicula m _ p e l i c u l a; public Cliente ( Hora horaLlegada , Pelicula p ) { m _ h o r a L l e g a d a = h o r a L l e g a d a; m_pelicula = p; } public void C o m p r a r E n t r a d a( Hora hora ) { m _ h o r a C o m p r a E n t r a d a = hora ; } public Pelicula g e t P e l i c u l a() { return m _ p e l i c u l a; } } public class Fila { private static int M A X _ C L I E N T E S = 100; private Cliente [] m _ c l i e n t e s; private int m _ n u m C l i e n t e s; public Fila () { m _ c l i e n t e s = new Cliente [ M A X _ C L I E N T E S]; m _ n u m C l i e n t e s = 0; } public boolean Agregar ( Cliente c ) { if ( m _ n u m C l i e n t e s < M A X _ C L I E N T E S) { m _ c l i e n t e s[ m _ n u m C l i e n t e s++] = c ; return true ; } return false ;

IIC1103 Cap tulo 10: Simulaci on

60

} public Cliente S a c a r P r i m e r o() { if ( m _ n u m C l i e n t e s >= 0) { Cliente primero = m _ c l i e n t e s [0]; for ( int i = 1; i < M A X _ C L I E N T E S; i ++) { m _ c l i e n t e s[ i - 1] = m _ c l i e n t e s[ i ]; } m_numClientes - -; return primero ; } return null ; } public boolean E s t a V a c i a() { if ( m _ n u m C l i e n t e s <= 0) { return true ; } return false ; } public int g e t N u m C l i e n t e s() { return m _ n u m C l i e n t e s; } } import i i c 1 1 0 3 P a c k a g e .*; // I m p l e m e n t a c i o n de la clase Hora public class Hora { private int hh ; private int mm ; public Hora ( int hh , int mm ) { this . hh = hh ; this . mm = mm ; } public Hora ( Hora h2 ) { hh = h2 . hh ; mm = h2 . mm ; } public void I n c r e m e n t a r H o r a( int mm ) { if ( this . mm + mm < 60) { this . mm += mm ; } else { this . hh = this . hh + ( this . mm + mm ) / 60; this . mm = ( this . mm + mm ) % 60; } } public boolean S o n I g u a l e s( Hora h2 ) { if ( hh == h2 . hh && mm == h2 . mm ) { return true ; } else { return false ; } } public boolean EsMayor ( Hora h2 ) { if (( hh > h2 . hh ) || ( hh == h2 . hh && mm > h2 . mm )) { return true ; } else { return false ; } } public int D e l t a M i n u t o s( Hora h2 ) { return ( hh - h2 . hh ) * 60 + ( mm - h2 . mm ); }

IIC1103 Cap tulo 10: Simulaci on

61

public String Listar () { String s = hh + " : " + mm ; return s ; } public void Mostrar () { Usuario . m e n s a j e C o n s o l a( Listar ()); } public Hora Copia () { return new Hora ( hh , mm ); } public void D e c r e m e n t a r H o r a( int hh ) { this . hh -= hh ; } } public class Pelicula { private private private private Hora m _ h o r a I n i c i o; Hora m _ h o r a T e r m i n o; String m_nombre ; int m _ p o p u l a r i d a d;

public Pelicula ( Hora hora , Hora horaFin , String nombre , int p o p u l a r i d a d) { m _ h o r a I n i c i o = hora ; m _ h o r a T e r m i n o = horaFin ; m_nombre = nombre ; m _ p o p u l a r i d a d = p o p u l a r i d a d; } public int g e t P o p u l a r i d a d() { return m _ p o p u l a r i d a d; } public Hora g e t I n i c i o() { return m _ h o r a I n i c i o; } public String g e t N o m b r e() { return m_nombre ; } } import java . io . I O E x c e p t i o n; import i i c 1 1 0 3 P a c k a g e .*; public class P r i n c i p a l { public static void main ( String [] args ) throws I O E x c e p t i o n { int n V e n d e d o r e s = Usuario . entero ( " Ingrese el numero de v e n d e d o r e s: " ); int nTMax = Usuario . entero ( " Ingrese el tiempo maximo de atencion : " ); int nroSalas = Usuario . entero ( " Ingrese el numero de salas : " ); S i m u l a c i o n s = new S i m u l a c i o n( nVendedores , nTMax , nroSalas ); s . E j e c u t a r S i m u l a c i o n (); } } import i i c 1 1 0 3 P a c k a g e .*; public class Sala { private int n r o P e r s o n a s A c t u a l = 0; private int c a p M a x i m a; public Sala () { c a p M a x i m a = A l e a t o r i o. entero (80 , 120); } public int g e t N r o P e r s o n a s A c t u a l() { return n r o P e r s o n a s A c t u a l; }

IIC1103 Cap tulo 10: Simulaci on

62

public void i n c r e m e n t a r P e r s o n a s( int n r o P e r s o n a s) { this . n r o P e r s o n a s A c t u a l += n r o P e r s o n a s; } public void v a c i a r S a l a() { this . n r o P e r s o n a s A c t u a l = 0; } public int g e t C a p M a x i m a() { return c a p M a x i m a; } } import java . io . File ; import java . io . I O E x c e p t i o n; import java . util . Scanner ; import i i c 1 1 0 3 P a c k a g e .*; public class S i m u l a c i o n { Fila m _ f i l a E n t r a d a s; Hora m _ h o r a A c t u a l; // P e l i c u l a s Pelicula [] m _ p e l i c u l a s; Hora m _ h o r a V e n t a E n t r a d a s P e l i c u l a; Hora m _ h o r a P e l i c u l a A c t u a l; int m _ p e l i c u l a A c t u a l; int m _ m a x P e l i c u l a s; // V e n d e d o r e s Hora [] m _ a t e n c i o n V e n d e d o r e s; int m _ n u m V e n d e d o r e s; int m _ m a x T i e m p o A t e n c i o n; // Salas Sala [] m_salas ; int m _ c l i e n t e s S i n S a l a = 0; // E s t a d i s t i c a s int m _ s t a t T o t a l P e r s o n a s; int m _ s t a t P e r s o n a s A t r a s a d a s; int m _ s t a t P e r s o n a s N o A t r a s a d a s; int [] m _ s t a t P e r s o n a s P o r P e l i c u l a; public S i m u l a c i o n( int numeroVendedores , int m a x T i e m p o A te nci on , int nroSalas ) throws I O E x c e p t i o n { m _ f i l a E n t r a d a s = new Fila (); m_salas = new Sala [ nroSalas ]; for ( int i = 0; i < m_salas . length ; i ++) { m_salas [ i ] = new Sala (); } m _ n u m V e n d e d o r e s = n u m e r o V e n d e d o r e s; m _ m a x T i e m p o A t e n c i o n = m a x T i e m p o A t e n c i o n; m _ a t e n c i o n V e n d e d o r e s = new Hora [ m _ n u m V e n d e d o r e s]; m _ p e l i c u l a A c t u a l = -1; I n f o P e l i c u l a s(); m _ s t a t P e r s o n a s A t r a s a d a s = 0; m _ s t a t P e r s o n a s N o A t r a s a d a s = 0; m _ s t a t T o t a l P e r s o n a s = 0; m _ s t a t P e r s o n a s P o r P e l i c u l a = new int [ m _ m a x P e l i c u l a s]; } public void I n f o P e l i c u l a s() throws I O E x c e p t i o n { m _ m a x P e l i c u l a s = n r o P e l i c u l a s( " c a r t e l e r a. txt " ); m _ p e l i c u l a s = new Pelicula [ m _ m a x P e l i c u l a s]; c a r g a r P e l i c u l a s( " c a r t e l e r a. txt " ); }

IIC1103 Cap tulo 10: Simulaci on

63

public void E j e c u t a r S i m u l a c i o n() { // Tiempo h a r d c o d e a d o en funcion de los datos del archivo m _ h o r a A c t u a l = new Hora (10 , 15); for ( int i = 0; i < m _ n u m V e n d e d o r e s; i ++) { m _ a t e n c i o n V e n d e d o r e s[ i ] = new Hora (10 , 15); } S i g u i e n t e P e l i c u l a (); Usuario . m e n s a j e C o n s o l a( " - - - - - - - - - - - - S i m u l a c i o n Cine - - - - - - - - - - - -\ n \ n " ); while ( m _ p e l i c u l a A c t u a l <= m _ m a x P e l i c u l a s) { if ( m _ h o r a A c t u a l. EsMayor ( m _ h o r a P e l i c u l a A c t u a l )) { Usuario . m e n s a j e C o n s o l a( " \n - > Comienza la funcion de : " + m _ p e l i c u l a s[ m _ p e l i c u l a A c t u a l]. g e t N o m b r e() + " \ n " ); if (! S i g u i e n t e P e l i c u l a ()) { break ; } } Sala s a l a C o n C a p a c i d a d = null ; if ( m _ h o r a A c t u a l. EsMayor ( m _ h o r a V e n t a E n t r a d a s P e l i c u l a )) { if ( A l e a t o r i o. entero (0 , 100) < m _ p e l i c u l a s[ m _ p e l i c u l a A c t u a l] . g e t P o p u l a r i d a d ()) { s a l a C o n C a p a c i d a d = g e t S a l a C o n C a p a c i d a d (); if ( s a l a C o n C a p a c i d a d != null ) { Usuario . m e n s a j e C o n s o l a( " Entrada vendida para " + m _ p e l i c u l a s[ m _ p e l i c u l a A c t u a l]. g e t N o m b r e() + " a las : " + m _ h o r a A c t u a l. Listar ()); m _ f i l a E n t r a d a s. Agregar ( new Cliente ( m _ h o r a A c t u a l. Copia () , m _ p e l i c u l a s[ m _ p e l i c u l a A c t u a l ])); m _ s t a t P e r s o n a s P o r P e l i c u l a[ m _ p e l i c u l a A c t u a l ]++; m _ s t a t T o t a l P e r s o n a s ++; s a l a C o n C a p a c i d a d. i n c r e m e n t a r P e r s o n a s (1); } else { m _ c l i e n t e s S i n S a l a ++; Usuario . m e n s a j e C o n s o l a( " Cliente no pudo entrar a ver pelicula por falta " + " de c a p a c i d a d en salas a las : " + m _ h o r a A c t u a l. Listar ()); } } } // I n c r e m e n t o 3 for ( int i = 0; i < m _ n u m V e n d e d o r e s; i ++) { if ( m _ h o r a A c t u a l. EsMayor ( m _ a t e n c i o n V e n d e d o r e s[ i ])) { if (! m _ f i l a E n t r a d a s. E s t a V a c i a ()) { Cliente c = m _ f i l a E n t r a d a s. S a c a r P r i m e r o(); if ( s a l a C o n C a p a c i d a d != null ) { if (! c . g e t P e l i c u l a(). equals ( m _ p e l i c u l a s[ m _ p e l i c u l a A c t u a l ])) { m _ s t a t P e r s o n a s A t r a s a d a s ++; } else { m _ s t a t P e r s o n a s N o A t r a s a d a s ++; } c . C o m p r a r E n t r a d a( m _ h o r a A c t u a l. Copia ()); } S i g u i e n t e A t e n c i o n( i ); } } } m _ h o r a A c t u a l. I n c r e m e n t a r H o r a (1); } // I n c r e m e n t o 1 Usuario . m e n s a j e C o n s o l a( " \ n E s t a d i s t i c a s" ); Usuario . m e n s a j e C o n s o l a( " Total de clientes : " + m _ s t a t T o t a l P e r s o n a s ); for ( int i = 0; i < m _ m a x P e l i c u l a s; i ++) { Usuario . m e n s a j e C o n s o l a( " Clientes que fueron a la pelicula " + m _ p e l i c u l a s[ i ]. g e t N o m b r e() + " : " + m _ s t a t P e r s o n a s P o r P e l i c u l a[ i ]); } // I n c r e m e n t o 2 Usuario . m e n s a j e C o n s o l a( " Clientes que no entraron por falta de c a p a c i d a d: "

IIC1103 Cap tulo 10: Simulaci on

64

+ m _ c l i e n t e s S i n S a l a); // I n c r e m e n t o 3 Usuario . m e n s a j e C o n s o l a( " Clientes que entraron a t r a s a d o s: " + m _ s t a t P e r s o n a s A t r a s a d a s ); Usuario . m e n s a j e C o n s o l a( " Clientes que entraron a la hora : " + m _ s t a t P e r s o n a s N o A t r a s a d a s ); } public boolean S i g u i e n t e P e l i c u l a() { m _ p e l i c u l a A c t u a l ++; if ( m _ p e l i c u l a A c t u a l >= m _ m a x P e l i c u l a s) { return false ; } m _ h o r a V e n t a E n t r a d a s P e l i c u l a = m _ p e l i c u l a s[ m _ p e l i c u l a A c t u a l]. g e t I n i c i o(). C opia (); m _ h o r a V e n t a E n t r a d a s P e l i c u l a. D e c r e m e n t a r H o r a (1); m _ h o r a P e l i c u l a A c t u a l = m _ p e l i c u l a s[ m _ p e l i c u l a A c t u a l]. g e t I n i c i o (); for ( int i = 0; i < m_salas . length ; i ++) { m_salas [ i ]. v a c i a r S a l a (); } return true ; } public void S i g u i e n t e A t e n c i o n( int i ) { Hora h = m _ h o r a A c t u a l. Copia (); h . I n c r e m e n t a r H o r a( A l e a t o r i o. entero (1 , m _ m a x T i e m p o A t e n c i o n )); m _ a t e n c i o n V e n d e d o r e s[ i ] = h ; } private Sala g e t S a l a C o n C a p a c i d a d() { int s a l a I n i c i a l = A l e a t o r i o. entero (0 , m_salas . length - 1); int s a l a A c t u a l = s a l a I n i c i a l; while ( true ) { if ( m_salas [ s a l a A c t u a l]. g e t N r o P e r s o n a s A c t u a l () < m_salas [ s a l a A c t u a l] . g e t C a p M a x i m a ()) { return m_salas [ s a l a A c t u a l]; } else { s a l a A c t u a l = ( s a l a A c t u a l + 1) % m_salas . length - 1; } if ( s a l a A c t u a l == s a l a I n i c i a l) { return null ; } } } private int n r o P e l i c u l a s( String n o m b r e A r c h i v o) throws I O E x c e p t i o n { File archivo = new File ( n o m b r e A r c h i v o); if ( archivo . exists ()) { // Abrimos lectores Scanner bLector = new Scanner ( archivo ); int count = 0; String linea ; while ( bLector . h a s N e x t L i n e()) { linea = bLector . nextLine (); count ++; } // Cerramos archivos bLector . close (); return count ; } else { return -1; } } private boolean c a r g a r P e l i c u l a s( String n o m b r e A r c h i v o) throws I O E x c e p t i o n { File archivo = new File ( n o m b r e A r c h i v o); if ( archivo . exists ()) { // Abrimos lectores Scanner bLector = new Scanner ( archivo ); for ( int i = 0; i < m _ p e l i c u l a s. length ; i ++) { String line = bLector . nextLine ();

IIC1103 Cap tulo 10: Simulaci on

65

String [] s p l i t L i n e = line . split ( " %" ); String nombre = s p l i t L i n e [0]; String h o r a I n i c i o = s p l i t L i n e [1]; int inicioH = Integer . parseInt ( h o r a I n i c i o. split ( " : " )[0]); int inicioM = Integer . parseInt ( h o r a I n i c i o. split ( " : " )[1]); String h o r a T e r m i n o = s p l i t L i n e [2]; int terminoH = Integer . parseInt ( h o r a T e r m i n o. split ( " : " )[0]); int terminoM = Integer . parseInt ( h o r a T e r m i n o. split ( " : " )[1]); String p o p u l a r i d a d = s p l i t L i n e [3]; m _ p e l i c u l a s[ i ] = new Pelicula ( new Hora ( inicioH , inicioM ) , new Hora ( terminoH , terminoM ) , nombre , Integer . parseInt ( p o p u l a r i d a d )); } // Cerramos archivos bLector . close (); return true ; } else { return false ; } } }

IIC1103 Cap tulo 10: Simulaci on

66

Problema 18: Urgencias


Enunciado Un hospital est a interesado en simular el funcionamiento de su secci on de urgencias, de manera de mejorar la atenci on de los pacientes. En particular, interesa saber c omo afecta el n umero de doctores disponibles al tiempo de espera de las personas que van llegando a ser atendidas. El programa lo dividiremos en 3 subconjuntos incrementales. Le recomendamos no comenzar con el siguiente subconjunto hasta terminar y probar el funcionamiento correcto del subconjunto actual. Incremento 1 Para comenzar, usted deber a implementar todo lo necesario para que se simule la llegada de pacientes al hospital, la atenci on de los pacientes por los doctores no debe ser implementada a un. Para realizar esta parte debe tener las siguientes consideraciones: La simulaci on debe realizarse considerando que llegan pacientes entre las 06:00 y las 18:00 horas. La simulaci on termina cuando todos los pacientes han sido atendidos. Cada minuto que transcurre hay una probabilidad de un 20 % que llegue un nuevo paciente. Existen tres niveles de gravedad de las condiciones que afecten a los pacientes: Urgencia Alta, Urgencia Media y Urgencia Baja. De los pacientes que llegan, un 60 % son de urgencia baja, un 30 % de urgencia media y un 10 % de urgencia alta. La atenci on de los pacientes se realiza por orden de urgencia, siendo atendidos primero los de urgencia alta. En caso de pacientes del mismo nivel de urgencia, se atender a primero a los pacientes que llegaron antes. De los pacientes que llegan, hay un 70 % se probabilidad que su problema sea de tipo traumatol ogico (fractura, esquince, etc). Estos pacientes son atendidos por separado que el resto, ya que los hay doctores especializados para esta a rea. Adem as de lo anterior, al nalizar la simulaci on su programa debe mostrar ciertas estad sticas relevantes: el n umero total de pacientes y el n umero de pacientes de urgencia alta. Incremento 2 Ahora Ud. debe considerar los siguientes aspectos en su programa, complementarios a los del incremento 1: Ahora la proporci on de pacientes con distinto tipo de gravedad var a en el d a dependiendo de la hora. Para ello, Ud. debe cargar en su programa la informaci on correspondiente a la proporci on de pacientes seg un gravedad a partir del archivo urgencia.txt, donde cada l nea representa la informaci on de una cierta etapa del d a. La informaci on almacenada por l nea es (en este orden) hora de inicio, hora de t ermino, porcentaje urgencia baja, porcentaje urgencia media y porcentaje urgencia alta. Cada uno de estos campos se encuentra separado por el s mbolo %. Adem as, al nal la simulaci on debe agregar a las estad sticas relevantes el n umero total de pacientes atendidos desglosado por tramo horario (de acuerdo a los establecidos en el archivo urgencia.txt).

IIC1103 Cap tulo 10: Simulaci on

67

Incremento 3 Ahora que tiene implementada la simulaci on de la llegada de los pacientes, es necesario simular la atenci on de los doctores. Existen N doctores para atender a los pacientes de traumatolog a y M doctores para atender al resto. Todos los doctores demoran un tiempo aleatorio entre 10 y 20 minutos en atender a los pacientes. Cada vez que haya un doctor de traumatolog a desocupado, el siguiente paciente con este tipo de problemas que corresponda por orden de urgencia es atendido. Equivalentemente, cada vez que un doctor que no es de traumatolog a se desocupa, el siguiente paciente con problemas no traumatol ogicos y que corresponda por orden de urgencia es atendido. Su programa debe permitir que los valores N y M sean ingresados por el usuario. Adem as al nalizar deber a mostrar las estad sticas de tiempo de espera promedio de los pacientes de traumatolog a, de tiempo de espera promedio de los pacientes que no eran de traumatolog a y el tiempo de espera promedio de todos los pacientes. Criterios de soluci on Posible soluci on
public class Cola { private private private private Paciente [][] p a c i e n t e s; int [] n u m P a c i e n t e s; int [] p o s A c t u a l C o l a; int [] p o s P r i m e r o C o l a;

public Cola () { p a c i e n t e s = new Paciente [ 3 ] [ 1 0 0 0 ] ; n u m P a c i e n t e s = new int [3]; p o s A c t u a l C o l a = new int [3]; p o s P r i m e r o C o l a = new int [3]; } public Paciente [] g e t P a c i e n t e s( int tipo ) { return p a c i e n t e s[ tipo ]; } public boolean a g r e g a r P a c i e n t e( Paciente paciente ) { if ( p o s A c t u a l C o l a[ paciente . g e t T i p o S e r v i c i o ()] >= p a c i e n t e s[ paciente . g e t T i p o S e r v i c i o ()]. length ) { return false ; } p a c i e n t e s[ paciente . g e t T i p o S e r v i c i o ()][ p o s A c t u a l C o l a[ paciente . g e t T i p o S e r v i c i o ()]] = paciente ; p o s A c t u a l C o l a[ paciente . g e t T i p o S e r v i c i o ()]++; n u m P a c i e n t e s[ paciente . g e t T i p o S e r v i c i o ()]++; return true ; } public Paciente s a c a r P a c i e n t e() { for ( int i = 0; i < 3; i ++) { if ( h a y P a c i e n t e s T i p o( i )) { return s a c a r P a c i e n t e T i p o( i ); } } return null ; } public Paciente s a c a r P a c i e n t e T i p o( int tipo ) { if ( p o s P r i m e r o C o l a[ tipo ] >= p o s A c t u a l C o l a[ tipo ]) { return null ; } Paciente sacado = p a c i e n t e s[ tipo ][ p o s P r i m e r o C o l a[ tipo ]]; p o s P r i m e r o C o l a[ tipo ]++;

IIC1103 Cap tulo 10: Simulaci on

68

n u m P a c i e n t e s[ tipo ] - -; return sacado ; } public boolean h a y P a c i e n t e s() { return h a y P a c i e n t e s T i p o (0) || h a y P a c i e n t e s T i p o (1)|| h a y P a c i e n t e s T i p o(2); } public boolean h a y P a c i e n t e s T i p o( int tipo ) { return n u m P a c i e n t e s[ tipo ] > 0; } public int n u m P a c i e n t e s E n C o l a () { return n u m P a c i e n t e s E n C o l a T i p o (0) + n u m P a c i e n t e s E n C o l a T i p o (1) + n u m P a c i e n t e s E n C o l a T i p o (2); } public int n u m P a c i e n t e s E n C o l a T i p o( int tipo ) { return n u m P a c i e n t e s[ tipo ]; } public int n u m T o t a l P a c i e n t e s () { return n u m T o t a l P a c i e n t e s T i p o (0) + n u m T o t a l P a c i e n t e s T i p o (1) + n u m T o t a l P a c i e n t e s T i p o (2); } public int n u m T o t a l P a c i e n t e s T i p o( int tipo ) { return p o s A c t u a l C o l a[ tipo ]; } public double e s p e r a P r o m e d i o() { double prom = 0; for ( int tipo = 0; tipo < 3; tipo ++) { for ( int i = 0; i < p o s A c t u a l C o l a[ tipo ]; i ++) { prom += p a c i e n t e s[ tipo ][ i ]. g e t T E s p e r a (); } } return prom ; } } public class Doctor { private int tipo ; // 0: F , 1: NF private int t A t e n c i o n; private int tLibre ; public Doctor ( int _tipo ) { tipo = _tipo ; } public void atender ( int _tAtencion , int _tLibre ) { t A t e n c i o n = _ t A t e n c i o n; tLibre = _tLibre ; } public boolean e s t a O c u p a d o( int t ) { return t < tLibre ; } } public class Paciente { private int tLlegada ; private int t A t e n c i o n; private int t i p o S e r v i c i o; // Alta =0 , Media =1 , Baja =2 public Paciente ( int _tLlegada , int _ t i p o S e r v i c i o) { tLlegada = _ t L l e g a d a; t i p o S e r v i c i o = _ t i p o S e r v i c i o; } public void e s A t e n d i d o( int t ) { tAtencion = t;

IIC1103 Cap tulo 10: Simulaci on

69

} public int g e t T L l e g a d a() { return tLlegada ; } public int g e t T i p o S e r v i c i o () { return t i p o S e r v i c i o; } public int g e t T E s p e r a() { return t A t e n c i o n - tLlegada ; } } public class P e r i o d o D i a { private private private private String h o r a I n i c i o; String h o r a T e r m i n o; int tMin ; int tMax ;

private double [] probs ; private int n u m P a c i e n t e s; private int [] n u m P a c i e n t e s T i p o; private int n u m P a c i e n t e s T r a u m a; public P e r i o d o D i a( String _horaInicio , String _horaTermino , double _probAlta , double _probMedia , double _ p r o b B a j a) { h o r a I n i c i o = _ h o r a I n i c i o; h o r a T e r m i n o = _ h o r a T e r m i n o; String [] inicio = h o r a I n i c i o. split ( " : " ); String [] termino = h o r a T e r m i n o. split ( " : " ); tMin = h o r a A M i n u t o( Integer . parseInt ( inicio [0]) , Integer . parseInt ( inicio [1])); tMax = h o r a A M i n u t o( Integer . parseInt ( termino [0]) , Integer . parseInt ( termino [1])); probs = new double [3]; probs [0] = _ p r o b A l t a; probs [1] = _ p r o b M e d i a; probs [2] = _ p r o b B a j a; n u m P a c i e n t e s T i p o = new int [3]; n u m P a c i e n t e s = 0; n u m P a c i e n t e s T r a u m a = 0; } public String g e t H o r a I n i c i o() { return h o r a I n i c i o; } public String g e t H o r a T e r m i n o() { return h o r a T e r m i n o; } private int h o r a A M i n u t o( int hora , int minuto ) { return minuto + 60 * hora ; } public boolean e s t a E n P e r i o d o( int t ) { return ( t >= tMin && t <= tMax ); } public double [] getProbs () { return probs ; } public void a g r e g a r P a c i e n t e s T i p o( int tipo ) { n u m P a c i e n t e s T i p o[ tipo ]++; n u m P a c i e n t e s++; } public void a g r e g a r P a c i e n t e s T r a u m a() {

IIC1103 Cap tulo 10: Simulaci on

70

n u m P a c i e n t e s T r a u m a ++; } public int g e t T o t a l P a c i e n t e s () { return n u m P a c i e n t e s; } public int g e t P a c i e n t e s T i p o( int tipo ) { return n u m P a c i e n t e s T i p o[ tipo ]; } public int g e t P a c i e n t e s T r a u m a () { return n u m P a c i e n t e s T r a u m a; } } import i i c 1 1 0 3 P a c k a g e. Usuario ; import java . io . F i l e N o t F o u n d E x c e p t i o n; public class P r i n c i p a l { /* * * @param args * @throws F i l e N o t F o u n d E x c e p t i o n */ public static void main ( String [] args ) throws F i l e N o t F o u n d E x c e p t i o n { int noTrauma = Usuario . entero ( " Ingrese el numero de doctores no t r a u m a t o l o g o s: " ); int trauma = Usuario . entero ( " Ingrese el numero de t r a u m a t o l o g o s: " ); S i m u l a c i o n sim = new S i m u l a c i o n( noTrauma , trauma ); sim . c a r g a r A r c h i v o( " urgencia . txt " ); sim . simular (6 , 0 , 18 , 0); } } import java . io . File ; import java . io . F i l e N o t F o u n d E x c e p t i o n; import java . util . Scanner ; import i i c 1 1 0 3 P a c k a g e. A l e a t o r i o; import i i c 1 1 0 3 P a c k a g e. Usuario ; public class S i m u l a c i o n { private private private private private private Cola c o l a N o T r a u m a; Cola c o l a T r a u m a; Doctor [] noTrauma ; Doctor [] trauma ; P e r i o d o D i a[] periodos ; int n u m P e r i o d o s;

public S i m u l a c i o n( int numDigitales , int n u m A n a l o g o s) { periodos = new P e r i o d o D i a [100]; n u m P e r i o d o s = 0; noTrauma = new Doctor [ n u m D i g i t a l e s]; for ( int i = 0; i < n u m D i g i t a l e s; i ++) { noTrauma [ i ] = new Doctor (0); } trauma = new Doctor [ n u m A n a l o g o s]; for ( int i = 0; i < n u m A n a l o g o s; i ++) { trauma [ i ] = new Doctor (1); } c o l a N o T r a u m a = new Cola (); c o l a T r a u m a = new Cola (); } public void c a r g a r A r c h i v o( String path ) throws F i l e N o t F o u n d E x c e p t i o n { File archivo = new File ( path ); Scanner lector = new Scanner ( archivo ); while ( lector . hasNext ()) {

IIC1103 Cap tulo 10: Simulaci on

71

String linea = lector . nextLine (); String [] arreglo = linea . split ( " %" ); double probAlta = Double . p a r s e D o u b l e( arreglo [2]) / 100.0; double p r o b M e d i a = Double . p a r s e D o u b l e( arreglo [3]) / 100.0; double probBaja = Double . p a r s e D o u b l e( arreglo [4]) / 100.0; P e r i o d o D i a p = new P e r i o d o D i a( arreglo [0] , arreglo [1] , probAlta , probMedia , probBaja ); periodos [ n u m P e r i o d o s] = p ; n u m P e r i o d o s++; } lector . close (); } public void simular ( int horaInicio , int minutoInicio , int horaTermino , int m i n u t o T e r m i n o) { int tMax = 60 * h o r a T e r m i n o + m i n u t o T e r m i n o; int t = 60 * h o r a I n i c i o + m i n u t o I n i c i o; // Ciclo p r i n c i p a l de s i m u l a c i o n while ( t < tMax || c o l a N o T r a u m a. h a y P a c i e n t e s() || c o l a T r a u m a. h a y P a c i e n t e s()) { // Llegada de p a c i e n t e s if ( A l e a t o r i o. real (0 , 1) < 0.2 && t < tMax ) { P e r i o d o D i a p = b u s c a r P e r i o d o( t ); if ( p == null ) { p = periodos [ n u m P e r i o d o s - 1]; } double [] p r o b s A c t u a l e s = p . getProbs (); double r a n d o m T i p o = A l e a t o r i o. real (0 , 1); int t i p o S e r v i c i o = 0; if ( r a n d o m T i p o >= p r o b s A c t u a l e s [0] && r a n d o m T i p o < p r o b s A c t u a l e s [0] + p r o b s A c t u a l e s [1]) t i p o S e r v i c i o = 1; else if ( r a n d o m T i p o >= p r o b s A c t u a l e s [0] + p r o b s A c t u a l e s [1]) t i p o S e r v i c i o = 2; p . a g r e g a r P a c i e n t e s T i p o( t i p o S e r v i c i o); Paciente paciente = new Paciente (t , t i p o S e r v i c i o); if ( A l e a t o r i o. real (0 , 1) < 0.7) { p . a g r e g a r P a c i e n t e s T r a u m a (); c o l a T r a u m a. a g r e g a r P a c i e n t e( paciente ); } else { c o l a N o T r a u m a. a g r e g a r P a c i e n t e( paciente ); } } // Atencion doctores for ( int i = 0; i < noTrauma . length ; i ++) { if (! noTrauma [ i ]. e s t a O c u p a d o( t )) { if ( c o l a N o T r a u m a. h a y P a c i e n t e s ()) { noTrauma [ i ]. atender (t , t + A l e a t o r i o. entero (10 , 20)); Paciente c = c o l a N o T r a u m a. s a c a r P a c i e n t e(); c . e s A t e n d i d o( t ); } } } for ( int i = 0; i < trauma . length ; i ++) { if (! trauma [ i ]. e s t a O c u p a d o( t )) { if ( c o l a T r a u m a. h a y P a c i e n t e s()) { trauma [ i ]. atender (t , t + A l e a t o r i o. entero (10 , 20)); Paciente c = c o l a T r a u m a. s a c a r P a c i e n t e(); c . e s A t e n d i d o( t ); } } } t ++; } // E s t a d i s t i c a s e s t a d i s t i c a s C l i e n t e s (); } public void e s t a d i s t i c a s C l i e n t e s() { for ( int i = 0; i < n u m P e r i o d o s; i ++) { Usuario . m e n s a j e C o n s o l a( " Periodo " + periodos [ i ]. g e t H o r a I n i c i o()

IIC1103 Cap tulo 10: Simulaci on

72

+ " - " + periodos [ i ]. g e t H o r a T e r m i n o ()); Usuario . m e n s a j e C o n s o l a( " Numero total de p a c i e n t e s: " + periodos [ i ]. g e t T o t a l P a c i e n t e s ()); Usuario . m e n s a j e C o n s o l a( " Numero p a c i e n t e s Urgencia Alta : " + periodos [ i ]. g e t P a c i e n t e s T i p o (0)); Usuario . m e n s a j e C o n s o l a( " Numero p a c i e n t e s Urgencia Media : " + periodos [ i ]. g e t P a c i e n t e s T i p o (1)); Usuario . m e n s a j e C o n s o l a( " Numero p a c i e n t e s Urgencia Baja : " + periodos [ i ]. g e t P a c i e n t e s T i p o (2)); Usuario . m e n s a j e C o n s o l a( " Numero p a c i e n t e s t r a u m a t o l o g i c o s: " + periodos [ i ]. g e t P a c i e n t e s T r a u m a ()); } Usuario . m e n s a j e C o n s o l a( " Tiempo espera promedio p a c i e n t e s no t r a u m a t o l o g i c o s: " + c o l a N o T r a u m a. e s p e r a P r o m e d i o ()); Usuario . m e n s a j e C o n s o l a( " Tiempo espera promedio p a c i e n t e s t r a u m a t o l o g i c o s: " + c o l a T r a u m a. e s p e r a P r o m e d i o ()); int n u m D i g i t a l e s = c o l a N o T r a u m a. n u m T o t a l P a c i e n t e s(); int n u m A n a l o g o s = c o l a T r a u m a. n u m T o t a l P a c i e n t e s (); double p e r c D i g i t a l e s = ( double ) n u m D i g i t a l e s / ( double ) ( n u m D i g i t a l e s + n u m A n a l o g o s); double p e r c A n a l o g o s = ( double ) n u m A n a l o g o s / ( double ) ( n u m D i g i t a l e s + n u m A n a l o g o s); Usuario . m e n s a j e C o n s o l a( " Tiempo espera promedio todos : " + ( c o l a T r a u m a. e s p e r a P r o m e d i o() * p e r c A n a l o g o s + c o l a N o T r a u m a . e s p e r a P r o m e d i o() * p e r c D i g i t a l e s )); } private P e r i o d o D i a b u s c a r P e r i o d o( int t ) { for ( int i = 0; i < n u m P e r i o d o s; i ++) { if ( periodos [ i ]. e s t a E n P e r i o d o( t )) { return periodos [ i ]; } } return null ; } }

IIC1103 Cap tulo 10: Simulaci on

73

Problema 19: Restaurant


Enunciado Un restaurant est a tratando de optimizar sus procesos, y para ello necesita modelar c omo es la auencia de p ublico durante el d a, como es su comportamiento de compra, y el personal necesario para atenderlos. El programa lo dividiremos en 3 subconjuntos incrementales. Le recomendamos no comenzar con el siguiente subconjunto hasta terminar y probar el funcionamiento correcto del subconjunto actual. Incremento 1 Para comenzar, usted deber a implementar todo lo necesario para que se simule la llegada de clientes al restaurant. Para realizar esta parte debe tener las siguientes consideraciones: La simulaci on debe realizarse considerando que llegan clientes entre las 08:00 (desayuno) y las 24:00 horas (cena). La simulaci on termina cuando todos los clientes han sido atendidos. Asuma que existe capacidad de mobiliario y espacio innitas, no as de meseros. Cada minuto que transcurre hay una probabilidad de un 20 % que llegue un nuevo cliente. Asuma que cada uno viene solo, y es necesario tomarle su pedido de forma independiente. El restaurant ofrece durante el d a diversos servicios. Transversales a ellos, los platos se pueden clasicar en tres tipos: Naturista, Proteico y DeliciaDulce, existiendo alternativas de cada uno de ellos durante el d a, seg un sea desayuno, almuerzo, once o cena. De los clientes que llegan, 50 % preere los platos de tipo Naturista , un 20 % los de tipo Proteico y un 30 % preere los DeliciaDulce. Asuma que cada cliente s olo pide un s olo tipo de plato por vez. Existe una probabilidad de un 80 % de que el cliente sea no fumador. Ellos son atendidos por otros meseros, que no est an contaminados con el humo ni aroma del cigarrillo. Una vez nalizada la ejecuci on de la simulaci on, se deben mostrar estad sticas relevantes, tales como n umero de clientes que preri o cada tipo de plato, n umero total de clientes atendidos y n umero de personas no fumadoras. Incremento 2 Ahora Ud. debe considerar los siguientes aspectos en su programa, complementarios a los del incremento 1: La suposici on de proporciones uniformes a lo largo del d a para los distintos tipos de platos es algo ilusa, pues el tipo de clientes que asiste al restaurant var a durante el d a. Para ello, Ud. debe cargar en su programa la informaci on correspondiente a la proporci on de clientes seg un la preferencia por los distintos platos a partir del archivo preferencias.txt, donde cada l nea representa la informaci on de una cierta etapa del d a. La informaci on almacenada por l nea es (en este orden) hora de inicio, hora de t ermino, porcentaje Naturista, porcentaje Proteico y porcentaje DeliciaDulce. Cada uno de estos campos se encuentra separado por el s mbolo %. Adem as, al nal la simulaci on debe agregar a las estad sticas relevantes el n umero total de clientes atendidos desglosado por tramo horario (de acuerdo a los establecidos en el archivo preferencias.txt).

IIC1103 Cap tulo 10: Simulaci on

74

Incremento 3 Una vez que est a modelada la llegada de clientes al restaurant y sus preferencias, hay que simular la atenci on de los meseros. Ellos se dividen en dos: los que atienden a los fumadores (F) y los que atienden al exigente p ublico de los no fumadores (NF). Cada mesero, sin importar de qu e tipo sea, demora entre 1 a 3 minutos en atender a los clientes, tiempo que distribuye uniforme. Recuerde que un cliente no fumador s olo puede ser atendido por un mesero no fumador, y un cliente fumador s olo puede ser atendido por un mesero fumador. Su programa debe permitir el ingreso del n umero de meseros, separado por tipo (F y NF). Al nalizar se debe agregar a las estad sticas de los incrementos anteriores el tiempo de espera promedio de cada cliente, desglosado entre fumadores y no fumadores, adem as del promedio en conjunto (todos los clientes). Criterios de soluci on Posible soluci on
public class Cliente { private int tLlegada ; private int t A t e n c i o n; private int t i p o S e r v i c i o; // N a t u r i s t a=0 , Proteico =1 , Delicia =2 public Cliente ( int _tLlegada , int _ t i p o S e r v i c i o) { tLlegada = _ t L l e g a d a; t i p o S e r v i c i o = _ t i p o S e r v i c i o; } public void e s A t e n d i d o( int t ) { tAtencion = t; } public int g e t T L l e g a d a() { return tLlegada ; } public int g e t T i p o S e r v i c i o () { return t i p o S e r v i c i o; } public int g e t T E s p e r a() { return t A t e n c i o n - tLlegada ; } } public class Cola { private private private private Cliente [] clientes ; int n u m C l i e n t e s; int p o s A c t u a l C o l a; int p o s P r i m e r o C o l a;

public Cola () { clientes = new Cliente [1000]; n u m C l i e n t e s = 0; p o s A c t u a l C o l a = 0; p o s P r i m e r o C o l a = 0; } public Cliente [] g e t C l i e n t e s() { return clientes ; } public boolean a g r e g a r C l i e n t e( Cliente cliente ) { if ( p o s A c t u a l C o l a >= clientes . length ) { return false ; } clientes [ p o s A c t u a l C o l a] = cliente ; p o s A c t u a l C o l a++;

IIC1103 Cap tulo 10: Simulaci on

75

n u m C l i e n t e s++; return true ; } public Cliente s a c a r C l i e n t e() { if ( p o s P r i m e r o C o l a >= p o s A c t u a l C o l a) { return null ; } Cliente sacado = clientes [ p o s P r i m e r o C o l a]; p o s P r i m e r o C o l a ++; numClientes - -; return sacado ; } public boolean h a y C l i e n t e s() { return n u m C l i e n t e s > 0; } public int n u m C l i e n t e s E n C o l a () { return n u m C l i e n t e s; } public int n u m T o t a l C l i e n t e s () { return p o s A c t u a l C o l a; } public double e s p e r a P r o m e d i o() { double prom = 0; for ( int i = 0; i < p o s A c t u a l C o l a; i ++) { prom += clientes [ i ]. g e t T E s p e r a(); } return prom ; } } public class Mesero { private int tipo ; // 0: F , 1: NF private int t A t e n c i o n; private int tLibre ; public Mesero ( int _tipo ) { tipo = _tipo ; } public void atender ( int _tAtencion , int _tLibre ) { t A t e n c i o n = _ t A t e n c i o n; tLibre = _tLibre ; } public boolean e s t a O c u p a d o( int t ) { return t < tLibre ; } } public class P e r i o d o D i a { private private private private String h o r a I n i c i o; String h o r a T e r m i n o; int tMin ; int tMax ;

private double [] probs ; private int n u m C l i e n t e s; private int [] n u m C l i e n t e s T i p o; private int n u m C l i e n t e s N o F u m a d o r; public P e r i o d o D i a( String _horaInicio , String _horaTermino , double _probNaturista , double _probProteico , double _ p r o b D e l i c i a D u l c e) { h o r a I n i c i o = _ h o r a I n i c i o; h o r a T e r m i n o = _ h o r a T e r m i n o; String [] inicio = h o r a I n i c i o. split ( " : " ); String [] termino = h o r a T e r m i n o. split ( " : " ); tMin = h o r a A M i n u t o( Integer . parseInt ( inicio [0]) , Integer . parseInt ( inicio [1]));

IIC1103 Cap tulo 10: Simulaci on

76

tMax = h o r a A M i n u t o( Integer . parseInt ( termino [0]) , Integer . parseInt ( termino [1])); probs = new double [3]; probs [0] = _ p r o b N a t u r i s t a; probs [1] = _ p r o b P r o t e i c o; probs [2] = _ p r o b D e l i c i a D u l c e; n u m C l i e n t e s T i p o = new int [3]; n u m C l i e n t e s = 0; n u m C l i e n t e s N o F u m a d o r = 0; } public String g e t H o r a I n i c i o() { return h o r a I n i c i o; } public String g e t H o r a T e r m i n o() { return h o r a T e r m i n o; } private int h o r a A M i n u t o( int hora , int minuto ) { return minuto + 60 * hora ; } public boolean e s t a E n P e r i o d o( int t ) { return ( t >= tMin && t <= tMax ); } public double [] getProbs () { return probs ; } public void a g r e g a r C l i e n t e s T i p o( int tipo ) { n u m C l i e n t e s T i p o[ tipo ]++; n u m C l i e n t e s++; } public void a g r e g a r C l i e n t e s N o F u m a d o r() { n u m C l i e n t e s N o F u m a d o r ++; } public int g e t T o t a l C l i e n t e s () { return n u m C l i e n t e s; } public int g e t C l i e n t e s T i p o( int tipo ) { return n u m C l i e n t e s T i p o[ tipo ]; } public int g e t C l i e n t e s N o F u m a d o r() { return n u m C l i e n t e s N o F u m a d o r; } } import i i c 1 1 0 3 P a c k a g e. Usuario ; import java . io . F i l e N o t F o u n d E x c e p t i o n; public class P r i n c i p a l { public static void main ( String [] args ) throws F i l e N o t F o u n d E x c e p t i o n { int f u m a d o r e s = Usuario . entero ( " Ingrese el numero de meseros f u m a d o r e s: " ); int n o F u m a d o r e s = Usuario . entero ( " Ingrese el numero de meseros no f u m a d o r e s: " ); S i m u l a c i o n sim = new S i m u l a c i o n( fumadores , n o F u m a d o r e s); sim . c a r g a r A r c h i v o( " p r e f e r e n c i a s. txt " ); sim . simular (8 ,0 ,24 ,0); } } import java . io . File ; import java . io . F i l e N o t F o u n d E x c e p t i o n; import java . util . Scanner ; import i i c 1 1 0 3 P a c k a g e. A l e a t o r i o; import i i c 1 1 0 3 P a c k a g e. Usuario ;

IIC1103 Cap tulo 10: Simulaci on

77

public class S i m u l a c i o n { private private private private private private Cola c o l a F u m a d o r e s; Cola c o l a N o F u m a d o r e s; Mesero [] f u m a d o r e s; Mesero [] n o F u m a d o r e s; P e r i o d o D i a[] periodos ; int n u m P e r i o d o s;

public S i m u l a c i o n( int numDigitales , int n u m A n a l o g o s) { periodos = new P e r i o d o D i a [100]; n u m P e r i o d o s = 0; f u m a d o r e s = new Mesero [ n u m D i g i t a l e s]; for ( int i = 0; i < n u m D i g i t a l e s; i ++) { f u m a d o r e s[ i ] = new Mesero (0); } n o F u m a d o r e s = new Mesero [ n u m A n a l o g o s]; for ( int i = 0; i < n u m A n a l o g o s; i ++) { n o F u m a d o r e s[ i ] = new Mesero (1); } c o l a F u m a d o r e s = new Cola (); c o l a N o F u m a d o r e s = new Cola (); } public void c a r g a r A r c h i v o( String path ) throws F i l e N o t F o u n d E x c e p t i o n { File archivo = new File ( path ); Scanner lector = new Scanner ( archivo ); while ( lector . hasNext ()) { String linea = lector . nextLine (); String [] arreglo = linea . split ( " %" ); double p r o b N a t u r i s t a = Double . p a r s e D o u b l e( arreglo [2]) / 100.0; double p r o b P r o t e i c o = Double . p a r s e D o u b l e( arreglo [3]) / 100.0; double p r o b D e l i c i a = Double . p a r s e D o u b l e( arreglo [4]) / 100.0; P e r i o d o D i a p = new P e r i o d o D i a( arreglo [0] , arreglo [1] , probNaturista , probProteico , p r o b D e l i c i a); periodos [ n u m P e r i o d o s] = p ; n u m P e r i o d o s++; } lector . close (); } public void simular ( int horaInicio , int minutoInicio , int horaTermino , int m i n u t o T e r m i n o) { int tMax = 60 * h o r a T e r m i n o + m i n u t o T e r m i n o; int t = 60 * h o r a I n i c i o + m i n u t o I n i c i o; // Ciclo p r i n c i p a l de s i m u l a c i o n while ( t < tMax || c o l a F u m a d o r e s. h a y C l i e n t e s() || c o l a N o F u m a d o r e s. h a y C l i e n t e s ()) { // Llegada de clientes if ( A l e a t o r i o. real (0 , 1) < 0.2 && t < tMax ) { P e r i o d o D i a p = b u s c a r P e r i o d o( t ); if ( p == null ) p = periodos [ n u m P e r i o d o s - 1]; double [] p r o b s A c t u a l e s = p . getProbs (); double r a n d o m T i p o = A l e a t o r i o. real (0 , 1); int t i p o S e r v i c i o = 0; if ( r a n d o m T i p o >= p r o b s A c t u a l e s [0] && r a n d o m T i p o < p r o b s A c t u a l e s [0] + p r o b s A c t u a l e s [1]) { t i p o S e r v i c i o = 1; } else if ( r a n d o m T i p o >= p r o b s A c t u a l e s [0] + p r o b s A c t u a l e s [1]) { t i p o S e r v i c i o = 2; } p . a g r e g a r C l i e n t e s T i p o( t i p o S e r v i c i o); Cliente cliente = new Cliente (t , t i p o S e r v i c i o); if ( A l e a t o r i o. real (0 , 1) < 0.8) { p . a g r e g a r C l i e n t e s N o F u m a d o r(); c o l a N o F u m a d o r e s. a g r e g a r C l i e n t e( cliente ); } else { c o l a F u m a d o r e s. a g r e g a r C l i e n t e( cliente ); } } // Atencion meseros

IIC1103 Cap tulo 10: Simulaci on

78

for ( int i = 0; i < f u m a d o r e s. length ; i ++) { if (! f u m a d o r e s[ i ]. e s t a O c u p a d o( t )) { if ( c o l a F u m a d o r e s. h a y C l i e n t e s ()) { f u m a d o r e s[ i ]. atender (t , t + A l e a t o r i o. entero (1 , 3)); Cliente c = c o l a F u m a d o r e s. s a c a r C l i e n t e(); c . e s A t e n d i d o( t ); } } } for ( int i = 0; i < n o F u m a d o r e s. length ; i ++) { if (! n o F u m a d o r e s[ i ]. e s t a O c u p a d o( t )) { if ( c o l a N o F u m a d o r e s. h a y C l i e n t e s ()) { n o F u m a d o r e s[ i ]. atender (t , t + A l e a t o r i o. entero (1 , 3)); Cliente c = c o l a N o F u m a d o r e s. s a c a r C l i e n t e(); c . e s A t e n d i d o( t ); } } } t ++; } // E s t a d i s t i c a s e s t a d i s t i c a s C l i e n t e s (); } public void e s t a d i s t i c a s C l i e n t e s() { for ( int i = 0; i < n u m P e r i o d o s; i ++) { Usuario . m e n s a j e C o n s o l a( " Periodo " + periodos [ i ]. g e t H o r a I n i c i o() + " - " + periodos [ i ]. g e t H o r a T e r m i n o ()); Usuario . m e n s a j e C o n s o l a( " Numero total de clientes : " + periodos [ i ]. g e t T o t a l C l i e n t e s ()); Usuario . m e n s a j e C o n s o l a( " Numero clientes N a t u r i s t a: " + periodos [ i ]. g e t C l i e n t e s T i p o (0)); Usuario . m e n s a j e C o n s o l a( " Numero clientes Proteico : " + periodos [ i ]. g e t C l i e n t e s T i p o (1)); Usuario . m e n s a j e C o n s o l a( " Numero clientes D e l i c i a D u l c e: " + periodos [ i ]. g e t C l i e n t e s T i p o (2)); Usuario . m e n s a j e C o n s o l a( " Numero clientes N o F u m a d o r e s: " + periodos [ i ]. g e t C l i e n t e s N o F u m a d o r ()); } Usuario . m e n s a j e C o n s o l a( " Tiempo espera promedio clientes f u m a d o r e s: " + c o l a F u m a d o r e s. e s p e r a P r o m e d i o ()); Usuario . m e n s a j e C o n s o l a( " Tiempo espera promedio clientes no f u m a d o r e s: " + c o l a N o F u m a d o r e s. e s p e r a P r o m e d i o ()); int n u m D i g i t a l e s = c o l a F u m a d o r e s. n u m T o t a l C l i e n t e s(); int n u m A n a l o g o s = c o l a N o F u m a d o r e s. n u m T o t a l C l i e n t e s(); double p e r c D i g i t a l e s = ( double ) n u m D i g i t a l e s / ( double ) ( n u m D i g i t a l e s + n u m A n a l o g o s); double p e r c A n a l o g o s = ( double ) n u m A n a l o g o s / ( double ) ( n u m D i g i t a l e s + n u m A n a l o g o s); Usuario . m e n s a j e C o n s o l a( " Tiempo espera promedio todos : " + ( c o l a N o F u m a d o r e s. e s p e r a P r o m e d i o() * p e r c A n a l o g o s + c o l a F u m a d o r e s . e s p e r a P r o m e d i o() * p e r c D i g i t a l e s )); } private P e r i o d o D i a b u s c a r P e r i o d o( int t ) { for ( int i = 0; i < n u m P e r i o d o s; i ++) { if ( periodos [ i ]. e s t a E n P e r i o d o( t )) { return periodos [ i ]; } } return null ; } }

IIC1103 Cap tulo 10: Simulaci on

79

Problema 20: Fotograf as


Enunciado Aunque el contar con c amaras fotogr acas en el hogar ya no es un lujo, muchas fotograf as requieren ser tomadas por especialistas, desde eventos especiales, como fotrograf as para tr amites legales son el nicho de negocio de fot ografos, con distinto tipo de experticia. En este ejercicio Ud. modelar a el ujo de clientes de un local de fotograf a tradicional t pica de alg un centro de ciudad chileno, sus necesidades fotogr acas y los fot ografos necesarios para atender la demanda. El programa lo dividiremos en 3 subconjuntos incrementales. Le recomendamos no comenzar con el siguiente subconjunto hasta terminar y probar el funcionamiento correcto del subconjunto actual. Incremento 1 Para comenzar, usted deber a implementar todo lo necesario para que se simule la llegada de clientes al estudio fotogr aco. Para realizar esta parte debe tener las siguientes consideraciones: La simulaci on debe realizarse considerando que llegan clientes entre las 07:00 y las 18:00 horas. La simulaci on termina cuando todos los clientes han sido atendidos. Cada minuto que transcurre hay una probabilidad de un 15 % que llegue un nuevo cliente. Asuma que viene solo, y cada fot ografo realiza la venta completa: desde la toma de la fotograf a, el cobro y la entrega del producto. Tal como se mencion o al inicio, los estudios fotogr acos tradicionales prestan distintos tipos de servicios, los cuales son: FotoCarne, FotoRecuerdoRapida (para llaveros y tarjetas) y FotoCompleja (incluye cambio de vestuario, donde se incluye modelaje). De los clientes que llegan, 60 % necesita FotoCarne, un 25 % necesita FotoRecuerdoRapida y un 15 % necesita una FotoCompleja. Asuma que cada cliente s olo pide un producto por venta. Existe una probabilidad de un 10 % de que el cliente requiera los servicios de una c amara an aloga, ya sea por delidad de la fotograf a o bien por necesidad del tr amite (algunas embajadas requieren este tipo de fotograf as para las visas). Este grupo de clientes es atendido por fot ografos especializados en estas c amaras y que no saben trabajar con las c amaras tradicionales digitales. Recuerde que este requerimiento es independiente del producto solicitado. Una vez nalizada la ejecuci on de la simulaci on, se deben mostrar estad sticas relevantes, tales como n umero de clientes por tipo de producto vendido, n umero total de clientes atendidos y n umero de personas que requirieron los servicios de fotograf a an aloga. Incremento 2 Ahora Ud. debe considerar los siguientes aspectos en su programa, complementarios a los del incremento 1: En este incremento, la proporci on de clientes que requiere los distintos productos var a durante el d a. Para ello, Ud. debe cargar en su programa la informaci on correspondiente a la proporci on de clientes seg un la preferencia por los distintos tipos de fotograas a partir del archivo fotografias.txt, donde cada l nea representa la informaci on de una cierta etapa del d a. La informaci on almacenada por l nea es (en este orden) hora de inicio, hora de t ermino, porcentaje FotoCarne, porcentaje FotoRecuerdoRapida y porcentaje FotoCompleja. Cada uno de estos campos se encuentra separado por el s mbolo %. Adem as, al nal la simulaci on debe agregar a las estad sticas relevantes el n umero total de clientes atendidos desglosado por tramo horario (de acuerdo a los establecidos en el archivo fotografias.txt). IIC1103 Cap tulo 10: Simulaci on 80

Incremento 3 Una vez completado lo anterior, hay que realizar la modelaci on de la atenci on del personal fotogr aco. Los fot ografos del estudio se dividen en dos tipos seg un su experticia: digitales (D) y an alogos (A). Los fot ografos digitales demoran entre 2 a 5 minutos en su trabajo, en tanto los fot ografos an alogos demoran entre 3 y 8 minutos. Su programa debe permitir el ingreso del n umero de fot ografos trabajando en el estudio, separado por tipo (D y A). Al nalizar se debe agregar a las estad sticas de los incrementos anteriores el tiempo de espera promedio de cada cliente, separado entre digital y an alogo, adem as del promedio en conjunto (todos los clientes). Criterios de soluci on Posible soluci on
public class Cliente { private int tLlegada ; private int t A t e n c i o n; private int t i p o S e r v i c i o; // F o t o C a r n e=0 , F o t o R e c u e r d o=1 , F o t o C o m p l e j a=2 public Cliente ( int _tLlegada , int _ t i p o S e r v i c i o) { tLlegada = _ t L l e g a d a; t i p o S e r v i c i o = _ t i p o S e r v i c i o; } public void e s A t e n d i d o( int t ) { tAtencion = t; } public int g e t T L l e g a d a() { return tLlegada ; } public int g e t T i p o S e r v i c i o () { return t i p o S e r v i c i o; } public int g e t T E s p e r a() { return t A t e n c i o n - tLlegada ; } } public class Cola { private private private private Cliente [] clientes ; int n u m C l i e n t e s; int p o s A c t u a l C o l a; int p o s P r i m e r o C o l a;

public Cola () { clientes = new Cliente [1000]; n u m C l i e n t e s = 0; p o s A c t u a l C o l a = 0; p o s P r i m e r o C o l a = 0; } public Cliente [] g e t C l i e n t e s() { return clientes ; } public boolean a g r e g a r C l i e n t e( Cliente cliente ) { if ( p o s A c t u a l C o l a >= clientes . length ) { return false ; } clientes [ p o s A c t u a l C o l a] = cliente ; p o s A c t u a l C o l a++;

IIC1103 Cap tulo 10: Simulaci on

81

n u m C l i e n t e s++; return true ; } public Cliente s a c a r C l i e n t e() { if ( p o s P r i m e r o C o l a >= p o s A c t u a l C o l a) { return null ; } Cliente sacado = clientes [ p o s P r i m e r o C o l a]; p o s P r i m e r o C o l a ++; numClientes - -; return sacado ; } public boolean h a y C l i e n t e s() { return n u m C l i e n t e s > 0; } public int n u m C l i e n t e s E n C o l a () { return n u m C l i e n t e s; } public int n u m T o t a l C l i e n t e s () { return p o s A c t u a l C o l a; } public double e s p e r a P r o m e d i o() { double prom = 0; for ( int i = 0; i < p o s A c t u a l C o l a; i ++) { prom += clientes [ i ]. g e t T E s p e r a(); } return prom ; } } public class F o t o g r a f o { private int tipo ; // 0: D , 1: A private int t A t e n c i o n; private int tLibre ; public F o t o g r a f o( int _tipo ) { tipo = _tipo ; } public void atender ( int _tAtencion , int _tLibre ) { t A t e n c i o n = _ t A t e n c i o n; tLibre = _tLibre ; } public boolean e s t a O c u p a d o( int t ) { return t < tLibre ; } } public class P e r i o d o D i a { private private private private String h o r a I n i c i o; String h o r a T e r m i n o; int tMin ; int tMax ;

private double [] probs ; private int n u m C l i e n t e s; private int [] n u m C l i e n t e s T i p o; private int n u m C l i e n t e s C a m a r a A n a l o g a; public P e r i o d o D i a( String _horaInicio , String _horaTermino , double _probFotoCarne , double _ p r o b F o t o R e cue rd o , double _ p r o b F o t o C o m p l e j a) { h o r a I n i c i o = _ h o r a I n i c i o; h o r a T e r m i n o = _ h o r a T e r m i n o; String [] inicio = h o r a I n i c i o. split ( " : " ); String [] termino = h o r a T e r m i n o. split ( " : " ); tMin = h o r a A M i n u t o( Integer . parseInt ( inicio [0]) , Integer . parseInt ( inicio [1])); tMax = h o r a A M i n u t o( Integer . parseInt ( termino [0]) , Integer . parseInt ( termino [1]));

IIC1103 Cap tulo 10: Simulaci on

82

probs = new double [3]; probs [0] = _ p r o b F o t o C a r n e; probs [1] = _ p r o b F o t o R e c u e r d o; probs [2] = _ p r o b F o t o C o m p l e j a; n u m C l i e n t e s T i p o = new int [3]; n u m C l i e n t e s = 0; n u m C l i e n t e s C a m a r a A n a l o g a = 0; } public String g e t H o r a I n i c i o() { return h o r a I n i c i o; } public String g e t H o r a T e r m i n o() { return h o r a T e r m i n o; } private int h o r a A M i n u t o( int hora , int minuto ) { return minuto + 60 * hora ; } public boolean e s t a E n P e r i o d o( int t ) { return ( t >= tMin && t <= tMax ); } public double [] getProbs () { return probs ; } public void a g r e g a r C l i e n t e s T i p o( int tipo ) { n u m C l i e n t e s T i p o[ tipo ]++; n u m C l i e n t e s++; } public void a g r e g a r C l i e n t e s C a m a r a A n a l o g a() { n u m C l i e n t e s C a m a r a A n a l o g a ++; } public int g e t T o t a l C l i e n t e s () { return n u m C l i e n t e s; } public int g e t C l i e n t e s T i p o( int tipo ) { return n u m C l i e n t e s T i p o[ tipo ]; } public int g e t C l i e n t e s C a m a r a A n a l o g a() { return n u m C l i e n t e s C a m a r a A n a l o g a; } } import i i c 1 1 0 3 P a c k a g e. Usuario ; import java . io . F i l e N o t F o u n d E x c e p t i o n; public class P r i n c i p a l { public static void main ( String [] args ) throws F i l e N o t F o u n d E x c e p t i o n { int d i g i t a l e s = Usuario . entero ( " Ingrese el numero de f o t o g r a d o s d i g i t a l e s: " ); int analogos = Usuario . entero ( " Ingrese el numero de f o t o g r a d o s analogos : " ); S i m u l a c i o n sim = new S i m u l a c i o n( digitales , analogos ); sim . c a r g a r A r c h i v o( " f o t o g r a f i a s. txt " ); sim . simular (7 ,0 ,18 ,0); } } import import import import import java . io . File ; java . io . F i l e N o t F o u n d E x c e p t i o n; java . util . Scanner ; i i c 1 1 0 3 P a c k a g e. A l e a t o r i o; i i c 1 1 0 3 P a c k a g e. Usuario ;

public class S i m u l a c i o n { private Cola c o l a D i g i t a l e s;

IIC1103 Cap tulo 10: Simulaci on

83

private private private private private

Cola c o l a A n a l o g o s; F o t o g r a f o[] d i g i t a l e s; F o t o g r a f o[] analogos ; P e r i o d o D i a[] periodos ; int n u m P e r i o d o s;

public S i m u l a c i o n( int numDigitales , int n u m A n a l o g o s) { periodos = new P e r i o d o D i a [100]; n u m P e r i o d o s = 0; d i g i t a l e s = new F o t o g r a f o[ n u m D i g i t a l e s]; for ( int i = 0; i < n u m D i g i t a l e s; i ++) { d i g i t a l e s[ i ] = new F o t o g r a f o (0); } analogos = new F o t o g r a f o[ n u m A n a l o g o s]; for ( int i = 0; i < n u m A n a l o g o s; i ++) { analogos [ i ] = new F o t o g r a f o (1); } c o l a D i g i t a l e s = new Cola (); c o l a A n a l o g o s = new Cola (); } public void c a r g a r A r c h i v o( String path ) throws F i l e N o t F o u n d E x c e p t i o n { File archivo = new File ( path ); Scanner lector = new Scanner ( archivo ); while ( lector . hasNext ()) { String linea = lector . nextLine (); String [] arreglo = linea . split ( " %" ); double p r o b F o t o C a r n e = Double . p a r s e D o u b l e( arreglo [2]) / 100.0; double p r o b F o t o R e c u e r d o = Double . p a r s e D o u b l e( arreglo [3]) / 100.0; double p r o b F o t o C o m p l e j a = Double . p a r s e D o u b l e( arreglo [4]) / 100.0; P e r i o d o D i a p = new P e r i o d o D i a( arreglo [0] , arreglo [1] , probFotoCarne , probFotoRecuerdo , p r o b F o t o C o m p l e j a); periodos [ n u m P e r i o d o s] = p ; n u m P e r i o d o s++; } lector . close (); } public void simular ( int horaInicio , int minutoInicio , int horaTermino , int m i n u t o T e r m i n o) { c o l a D i g i t a l e s = new Cola (); int tMax = 60 * h o r a T e r m i n o + m i n u t o T e r m i n o; int t = 60 * h o r a I n i c i o + m i n u t o I n i c i o; // Ciclo p r i n c i p a l de s i m u l a c i o n while ( t < tMax || c o l a D i g i t a l e s. h a y C l i e n t e s() || c o l a A n a l o g o s. h a y C l i e n t e s()) { // Llegada de clientes if ( A l e a t o r i o. real (0 , 1) < 0.15 && t < tMax ) { P e r i o d o D i a p = b u s c a r P e r i o d o( t ); if ( p == null ) { p = periodos [ n u m P e r i o d o s - 1]; } double [] p r o b s A c t u a l e s = p . getProbs (); double r a n d o m T i p o = A l e a t o r i o. real (0 , 1); int t i p o S e r v i c i o = 0; if ( r a n d o m T i p o >= p r o b s A c t u a l e s [0] && r a n d o m T i p o < p r o b s A c t u a l e s [0] + p r o b s A c t u a l e s [1]) { t i p o S e r v i c i o = 1; } else if ( r a n d o m T i p o >= p r o b s A c t u a l e s [0] + p r o b s A c t u a l e s [1]) { t i p o S e r v i c i o = 2; } p . a g r e g a r C l i e n t e s T i p o( t i p o S e r v i c i o); Cliente cliente = new Cliente (t , t i p o S e r v i c i o); if ( A l e a t o r i o. real (0 , 1) < 0.1) { p . a g r e g a r C l i e n t e s C a m a r a A n a l o g a (); c o l a A n a l o g o s. a g r e g a r C l i e n t e( cliente ); } else { c o l a D i g i t a l e s. a g r e g a r C l i e n t e( cliente ); } } // Atencion f o t o g r a f o s for ( int i = 0; i < d i g i t a l e s. length ; i ++) { if (! d i g i t a l e s[ i ]. e s t a O c u p a d o( t )) { if ( c o l a D i g i t a l e s. h a y C l i e n t e s ()) { d i g i t a l e s[ i ]. atender (t , t + A l e a t o r i o. entero (2 , 5)); Cliente c = c o l a D i g i t a l e s. s a c a r C l i e n t e();

IIC1103 Cap tulo 10: Simulaci on

84

c . e s A t e n d i d o( t ); } } } for ( int i = 0; i < analogos . length ; i ++) { if (! analogos [ i ]. e s t a O c u p a d o( t )) { if ( c o l a A n a l o g o s. h a y C l i e n t e s ()) { analogos [ i ]. atender (t , t + A l e a t o r i o. entero (3 , 8)); Cliente c = c o l a A n a l o g o s. s a c a r C l i e n t e(); c . e s A t e n d i d o( t ); } } } t ++; } // E s t a d i s t i c a s e s t a d i s t i c a s C l i e n t e s (); } public void e s t a d i s t i c a s C l i e n t e s() { for ( int i = 0; i < n u m P e r i o d o s; i ++) { Usuario . m e n s a j e C o n s o l a( " Periodo " + periodos [ i ]. g e t H o r a I n i c i o() + " - " + periodos [ i ]. g e t H o r a T e r m i n o ()); Usuario . m e n s a j e C o n s o l a( " Numero total de clientes : " + periodos [ i ]. g e t T o t a l C l i e n t e s ()); Usuario . m e n s a j e C o n s o l a( " Numero clientes F o t o C a r n e: " + periodos [ i ]. g e t C l i e n t e s T i p o (0)); Usuario . m e n s a j e C o n s o l a( " Numero clientes F o t o R e c u e r d o: " + periodos [ i ]. g e t C l i e n t e s T i p o (1)); Usuario . m e n s a j e C o n s o l a( " Numero clientes F o t o C o m p l e j a: " + periodos [ i ]. g e t C l i e n t e s T i p o (2)); Usuario . m e n s a j e C o n s o l a( " Numero clientes C a m a r a A n a l o g a: " + periodos [ i ]. g e t C l i e n t e s C a m a r a A n a l o g a ()); } Usuario . m e n s a j e C o n s o l a( " Tiempo espera promedio clientes d i g i t a l e s: " + c o l a D i g i t a l e s. e s p e r a P r o m e d i o ()); Usuario . m e n s a j e C o n s o l a( " Tiempo espera promedio clientes analogos : " + c o l a A n a l o g o s. e s p e r a P r o m e d i o ()); int n u m D i g i t a l e s = c o l a D i g i t a l e s. n u m T o t a l C l i e n t e s(); int n u m A n a l o g o s = c o l a A n a l o g o s. n u m T o t a l C l i e n t e s(); double p e r c D i g i t a l e s = ( double ) n u m D i g i t a l e s / ( double ) ( n u m D i g i t a l e s + n u m A n a l o g o s); double p e r c A n a l o g o s = ( double ) n u m A n a l o g o s / ( double ) ( n u m D i g i t a l e s + n u m A n a l o g o s); Usuario . m e n s a j e C o n s o l a( " Tiempo espera promedio todos : " + ( c o l a A n a l o g o s. e s p e r a P r o m e d i o() * p e r c A n a l o g o s + c o l a D i g i t a l e s . e s p e r a P r o m e d i o() * p e r c D i g i t a l e s )); } private P e r i o d o D i a b u s c a r P e r i o d o( int t ) { for ( int i = 0; i < n u m P e r i o d o s; i ++) { if ( periodos [ i ]. e s t a E n P e r i o d o( t )) { return periodos [ i ]; } } return null ; } }

IIC1103 Cap tulo 10: Simulaci on

85

S-ar putea să vă placă și