viernes, 15 de febrero de 2013

Práctica #1 - Control de semaforos

Practica #1 - Control de calles 

Introducción

En esta práctica programaremos un sistema adaptativo, el programa consiste en un cruce de calles y tenemos que controlar el tráfico de cada calle con su respectivo semáforo, brindándole prioridad a las calles más congestionadas. No solo se tiene que tomar en cuenta el tráfico de la calle, si no también tenemos que prevenir que los semáforos de calles contrarias se enciendan al mismo tiempo para evitar un choque. Como sabemos, el trafico en las calles pueden variar dependiendo de la hora del dia, por lo que tambien consideramos la hora del dia como otro factor para la afluencia de trafico.  

Entonces, el objetivo de esta practica es implementar un sistema que se adapte a la necesidad de ese cruce de calles, que se minimicen las congestiones y sea un sistema funcional, adaptable y con el menor número de fallos, adaptandose tambien a la hora del dia en que se encuentre. Para esto usaremos el lenguaje de programación Java con el compilador Eclipse. 

Desarrollo 

Se decidió trabajar con las calles en pares. Solo un par de calles podrá estar en verde al mismo tiempo mientras que el otro par estará en luz roja evitando así cualquier colisión.



Estos pares son las calles:
       A y B
       C y D




Los tiempos de los intervalos de los semáforos se modificarán cada vez que un, comprobando también cuantos autos se encuentran ahora en los pares de calles. Esto para saber si se modificará de nuevo los tiempos o seguirán igual.

La clasificación que se le da a una calle está en función del número de autos que tenga detrás de su semáforo correspondiente. 

Con la utilización de hilos de tiempo controlamos los cambios de luces de los semáforos y la entrada de nuevos autos a cada calle. 

Usando una matriz de conflictos y un grafo de conflictos podemos ver el total de combinaciones que es posible hacer, para que no existan problemas a la hora de encender los semáforos.

Matriz de conflictos


Grafo de conflictos

Diseño de la solucion 

Empezamos generando de forma aleatoria el trafico inicial de cada calle. Usaremos dos variables booleanas, para determinar que semaforos encender (los de las calles A y B o los de las calles C y D). Pasamos a obtener la hora del dia con la funcion Calendar.HOUR_OF_DAY (ubicada en la clase java.util.Calendar). 

Con una estructura de decision if, el programa decidira que cantidad de trafico habrá para cada calle dependiendo de la hora del dia. 

Cabe mencionar que por ahora, el programa solo funciona de 3 a 9 de la noche, pero lo podemos modificar para que funcione las 24 horas del dia. 

Usando un hilo de tiempo, haremos transcurrir el tiempo de encendido del semáforo en cada par de calles.

Los tiempos de encendido de los semáforos dependen del trafico y de la hora del dia:
              -De 3 a 5 de la tarde, se dan 5 segundos a las calles con poca afluencia y 8 segundos a las calles con mucha afluencia.

              -De 6 a 9 de la noche, se dan 8 segundos a las calles con poca afluencia y 14 segundos a las calles con mucha afluencia.

El trafico se va reduciendo o aumentando segun la hora del dia:

             -De 3 a 5 de la tarde, se aumenta/reduce 1 vehiculo cada segundo para las calles A y B cuando los semaforos de estas calles se encuentran encendidas/apagadas, se aumenta/reduce 1 vehiculo para las calles C y D cuando su respectivo semaforo se encuentra encendido.

             -De 6 a 9 de la noche, se reducen 2  vehiculos cada segundo para las calles A y B (tenian prisa los automovilistas :P) y se aumenta 1 vehiculo para las calles C y D cuando el semaforo AB se encuentra encendido, se reducen 2 vehiculos en las calles C y D y se aumenta 1 vehiculo para las calles A y B cuando el semaforo CD se encuentra encendidos.

Si el trafico de una calle llega a 0 se volvera a generar un trafico de 1 a 4 o 7 vehiculos, dependiendo de las horas del dia.

Podemos ver una cómo funciona una parte del código aqui:


if(hora == 15 || hora == 16 || hora == 17) { //Dependiendo del valor de la variable hora, habra mucho o poco trafico en las calles
	
	//Semaforos A y B
	
		if(AB == true){
			System.out.print("\n== Se encienden los semaforos A y B == \n");
			System.out.print("== Se apagan los semaforos C y D == \n");
			trAB = A+B; //Suma los traficos de las calles A y B
			trCD = C+D; //Suma los traficos de las calles C y D
			Random tr2 = new Random(); //Nuevo random
			if(trAB > trCD){ //Si el trafico de las calles A y B mayores que C y D, se da un tiempo de 8 segundos para que pasen los autos
			try{
				for(n=1;n<9;n++){
					A= A-1; //Se elimina un auto cada segundo
					B= B-1;
					if (A <= 0){ //Si el numero de autos en la calle A es menor o igual a 0, se genera un nuevo numero de trafico de manera aleatoria
						
						A = 1 + (tr2.nextInt(3));
					}
					
					if(B <= 0){
						B = 1 + (tr2.nextInt(3));
					}
					C= C+1;//Se suma un nuevo carro a la calle C
					D= D+1;
					Thread.sleep(1000);
					System.out.print(", "+n); //Imprime los segundos
				}
			}//Fin del try
			
			catch (InterruptedException e) { 
				System.out.println(e.getMessage()); 
				}
			
			System.out.print("\nTrafico en la calle A = "+A+"\n");
			System.out.print("Trafico en la calle B = "+B+"\n");
			System.out.print("Trafico en la calle C = "+C+"\n");
			System.out.print("Trafico en la calle D = "+D+"\n");
			}
			
			if(trAB < trCD){//Si el trafico de las calles A y B menores que C y D, se da un tiempo de 5 segundos para que pasen los autos
				try{
					for(n=1;n<6;n++){
						A= A-1;
						B= B-1;
						if (A <= 0){
							
							A = 1 + (tr2.nextInt(3));
						}//Fin del if
						
						if(B <= 0){
							B = 1 + (tr2.nextInt(3));
						}//Fin del if
						C= C+1;
						D= D+1;
						Thread.sleep(1000);
					System.out.print(", "+n);	
					}//Fin del for
				}//Fin del try
				
				catch (InterruptedException e) { 
					System.out.println(e.getMessage()); 
					}//Fin del catch
				
				System.out.print("\nTrafico en la calle A = "+A+"\n");
				System.out.print("Trafico en la calle B = "+B+"\n");
				System.out.print("Trafico en la calle C = "+C+"\n");
				System.out.print("Trafico en la calle D = "+D+"\n");
				}//Fin del if
			AB=false; //Se apagan los semaforos A y B
			CD=true;//Se encienden los semaforos C y D
			hora = cal.get(Calendar.HOUR_OF_DAY); //Se obtiene de nuevo la hora, para asegurar si hay una transicion de horas, por ejemplo de 5 p.m. a 6 p.m.
		}//fin del super If
		
		//Semaforos C y D
	
		if(CD == true){
			System.out.print("\n== Se encienden los semaforos C y D ==\n");
			System.out.print("== Se apagan los semaforos A y B == \n");
			trAB = A+B;
			trCD = C+D;
			Random tr2 = new Random();
			if(trCD > trAB){ //Si el trafico de las calles C y D mayores que A y B, se da un tiempo de 8 segundos para que pasen los autos
			try{
				for(n=1;n<9;n++){
					A= A+1;
					B= B+1;
					C= C-1;
					D= D-1;
					if (C <= 0){
						
						C = 1 + (tr2.nextInt(3));
					}
					
					if(D <= 0){
						D = 1 + (tr2.nextInt(3));
					}
					
					Thread.sleep(1000);
					System.out.print(", "+n);
				}
			}//Fin del try
			
			catch (InterruptedException e) { 
				System.out.println(e.getMessage()); 
				}
			
			System.out.print("\nTrafico en la calle A = "+A+"\n");
			System.out.print("Trafico en la calle B = "+B+"\n");
			System.out.print("Trafico en la calle C = "+C+"\n");
			System.out.print("Trafico en la calle D = "+D+"\n");
			}
			
			if(trCD < trAB){//Si el trafico de las calles C y D menores que A y B, se da un tiempo de 5 segundos para que pasen los autos
				try{
					for(n=1;n<6;n++){
						A= A+1;
						B= B+1;
						C= C-1;
						D= D-1;
						if (C <= 0){
							
							C = 1 + (tr2.nextInt(3));
						}//Fin del if
						
						if(D <= 0){
							D = 1 + (tr2.nextInt(3));
						}//Fin del if
						
						Thread.sleep(1000);
					System.out.print(", "+n);	
					}//Fin del for
				}//Fin del try
				
				catch (InterruptedException e) { 
					System.out.println(e.getMessage()); 
					}//Fin del catch
				
				System.out.print("\nTrafico en la calle A = "+A+"\n");
				System.out.print("Trafico en la calle B = "+B+"\n");
				System.out.print("Trafico en la calle C = "+C+"\n");
				System.out.print("Trafico en la calle D = "+D+"\n");
				}//Fin del if
				AB=true; //Se encienden los semaforos A y B
				CD=false;//Se apagan los semaforos C y D
				hora = cal.get(Calendar.HOUR_OF_DAY);
		}//fin del super If
	}// Fin del if de horas



Aqui se puede consultar el resto del código:



A continuación un video con la demostración del programa en ejecución:

Conclusiones
Sabemos que podemos mejorar el codigo y la logica, además de agregarle la interfaz grafica para dar una mejor impresión al programa, pero con esta practica hemos comprendido como pueden funcionar el uso de hilos y el autoajuste de parametros.

Referencias

Deitel M., Harvey (2008). Java, Como programar. México: Editorial Prentice Hall.
Sin autor, "http://lineadecodigo.com/java/obtener-la-hora-en-java/" (2007)
Sin autor, "http://equis.umh.es/alex-bia/teaching/PC/material/hilos_tutorial-java/cap10-2.htm" (2006)