
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Random;

import aima.search.framework.Problem;
import aima.search.framework.Search;
import aima.search.framework.SearchAgent;
import aima.search.informed.HillClimbingSearch;
import aima.search.informed.SimulatedAnnealingSearch;

public class HorarioTrabajo{

	public static ArrayList todosTrabajos;
	public static Horario h;

	public static void llenarLista(){
		todosTrabajos = new ArrayList();
		Random rand=new Random(1);
		
		int cuantos = 500;
		for(int i=0; i<cuantos; i++){
			int hora = rand.nextInt(167)+1; // 1 a 167
			int tamano = rand.nextInt(5)+1; // 1 a 5
			int izquierda = rand.nextInt(6); // 0 a 5
			int derecha = rand.nextInt(6); // 0 a 5
			
			Trabajo dummy =
				new Trabajo(i, hora, tamano, izquierda, derecha);
			todosTrabajos.add(dummy);
		}
	}
	
	public static void imprimir(){
		System.out.println("La lista de trabajos con "+
				todosTrabajos.size()+"\n");
		for(int i=0; i<todosTrabajos.size(); i++){
			System.out.println((Trabajo)todosTrabajos.get(i));
		}
	}

	// Crea un horario con bastantes trabajos al azar, sacados de todosTrabajos
	// Es un posible estado inicial
	public static Horario horarioAleatorio(){
		h = new Horario();
		Trabajo t;
		for(int i=0; i<todosTrabajos.size(); i++){
			t = (Trabajo)todosTrabajos.get(i);
			if (h.sePuedePoner(t,0)) h.poner(t,0);
		}
		return h;
	}

	public static void main(String[]args){
		llenarLista();
		//imprimir();
		//System.exit(0);

		h = new Horario();

		//h = horarioAleatorio();

		//System.out.println(  h  );
		
		//horarioTrabajoHillClimbingDemo();
		horarioTrabajoSimulatedAnnealingDemo();

	}

	public static void horarioTrabajoHillClimbingDemo() {
		System.out.println("\nHorarioTrabajo con el algoritmo Hill Climbing -->");
		try {
			Problem problem = new Problem(h,
					new Sucesores(),
					new ComprFin(),
					new Heuristica());

			Search search = new HillClimbingSearch();
			SearchAgent agent = new SearchAgent(problem, search);
			printActions(agent.getActions());
			printInstrumentation(agent.getInstrumentation());

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private static void horarioTrabajoSimulatedAnnealingDemo() {
		System.out.println("\nHorarioTrabajo con el algoritmo Simulated Annealing -->");
		try {
			Problem problem = new Problem(h,
					new Sucesores(),
					new ComprFin(),
					new Heuristica());
			
		// SimulatedAnnealingSearch(int steps, int stiter, int k, double lamb)
		//                            10000      100       20     0.005
			
			Search search =
				new SimulatedAnnealingSearch(10000,100,20,0.005);
			
			SearchAgent agent = new SearchAgent(problem, search);
			
			printActions(agent.getActions());
			printInstrumentation(agent.getInstrumentation());
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private static void printInstrumentation(Properties properties) {
		Iterator keys = properties.keySet().iterator();
		while (keys.hasNext()) {
			String key = (String) keys.next();
			String property = properties.getProperty(key);
			System.out.println(key + " : " + property);
		}

	}

	private static void printActions(List actions) {
		for (int i = 0; i < actions.size(); i++) {
			String action = (String) actions.get(i);
			System.out.println(action);
		}
	}
}

