
/**
 * @author Francisco Jose Aguilar Celdran
 *          Sergio Blanco Cuaresma
 *
 * Intel·ligencia Artificial II
 * Exercici de Memoria Associativa
 * GeneradorPatrons: Classe que obte un cert nombre de patrons diferents,
 *                   de longiud igual a la especificada.
 */

import java.util.*;
import java.io.*;

public class GeneradorPatrons {
   int nombrePatrons;
   int longitudPatrons;

   public GeneradorPatrons (int nombrePatrons, int longitudPatrons) {
      this.longitudPatrons = longitudPatrons;
      this.nombrePatrons = nombrePatrons;
   }

   // Genera un patro aleatori
   private Integer[] obtenirPatro() {
      Integer patro[] = new Integer[longitudPatrons];
      Date data = new Date();
      Random generador = new Random();
      generador.setSeed(data.getTime());
      for (int i = 0; i < longitudPatrons; i++) {
         int aleatori = generador.nextInt(2);
         if (aleatori < 0.5) {
            patro[i] = new Integer(-1);
         } else {
            patro[i] = new Integer(1);
         }
      }

      return patro;
   }

   // Compara dos vectors d'Integers
   private boolean patronsIguals(Integer patro1[], Integer patro2[]) {
      boolean iguals = true;

      int comptador = 0;
      while ((comptador < patro1.length) && (iguals == true)) {
         if (patro1[comptador].intValue() != patro2[comptador].intValue()) {
            iguals = false;
         }
         comptador++;
      }
      return iguals;
   }

   // Comproba que el vector especificat no es troba a la colecció de vectors indicada
   private boolean comprovarRepetits(Collection conjunt, Integer patroActual[]) {
      boolean repetit = false;

      Iterator it = conjunt.iterator();
      while (it.hasNext() && (repetit == false)) {
         Integer patroExistent[] = (Integer[])it.next();
         if (patronsIguals(patroExistent,patroActual)) {
            repetit = true;
         }
      }
      return repetit;
   }

   // Genera "nombrePatrons" patrons de "longitudPatros" elements i els guarda
   // a l'arxiu especificat.
   public Collection generarPatrons(String nomFitxer) {
      boolean gravarFitxer = true;
      FileWriter arxiu = null;
      BufferedWriter sortida = null;
      try {
         arxiu = new FileWriter(nomFitxer);
         sortida = new BufferedWriter(arxiu);
      } catch (IOException e) {
         gravarFitxer = false;
      }
      Collection conjuntPatrons = new Vector();
      int comptador = 0;
      while (comptador < nombrePatrons) {
         Integer patro[] = obtenirPatro();
         boolean repetit = comprovarRepetits(conjuntPatrons,patro);
         if (!repetit) {
            conjuntPatrons.add(patro);
            comptador++;
            // Es copien en el fitxer especificat els patrons generats
            if (gravarFitxer) {
               try {
                  for (int i = 0; i < patro.length; i++) {
                     sortida.write(String.valueOf(patro[i].intValue()));
                     sortida.write(" ");
                  }
                  sortida.write("\n");
               } catch(IOException e) {
                  gravarFitxer = false;
               }
            }
         }
      }
      if (gravarFitxer) {
         try {
            sortida.close();
         } catch (IOException e) {}
      }
      return conjuntPatrons;
   }

   // Obté el "nombrePatrons" patrons guardats en un arxiu.
   public Collection llegirPatronsFitxer(String fitxerEntrada) throws IOException {
      int total_llegits= 0;
      Collection patrons = new Vector();
      FileReader arxiu = new FileReader(fitxerEntrada);
      BufferedReader entrada = new BufferedReader(arxiu);
      String linia = entrada.readLine();
      
      // Si a l'arxiu hi ha menys patrons que els que demanem es llençarà una excepció
      while ((linia != null) && (total_llegits < nombrePatrons)) {
         StringTokenizer valor = new StringTokenizer(linia);
         Integer patro[] = new Integer[longitudPatrons];
         int comptador = 0;
         while (valor.hasMoreElements()) {
            String lectura = (String)valor.nextElement();
            patro[comptador] = new Integer(Integer.parseInt(lectura));
            comptador++;
         }

         patrons.add(patro);
         linia = entrada.readLine();
         
         total_llegits++;
      }
      if (total_llegits < nombrePatrons) {
         throw new IOException();
      }
      
      
      return patrons;
   }
   
   // Llegeix un fitxer de patrons i afegeix un % de soroll
   public void afegirSorollPatrons(String fitxerEntrada, String fitxerSortida, int soroll) throws IOException {
      int total_llegits= 0;
      Collection patrons = new Vector();
      FileReader arxiu = new FileReader(fitxerEntrada);
      BufferedReader entrada = new BufferedReader(arxiu);
      String linia = entrada.readLine();
      
      // Si a l'arxiu hi ha menys patrons que els que demanem es llençarà una excepció
      while ((linia != null) && (total_llegits < nombrePatrons)) {
         StringTokenizer valor = new StringTokenizer(linia);
         Integer patro[] = new Integer[longitudPatrons];
         int comptador = 0;
         while (valor.hasMoreElements()) {
            String lectura = (String)valor.nextElement();
            patro[comptador] = new Integer(Integer.parseInt(lectura));
            comptador++;
         }

         patrons.add(patro);
         linia = entrada.readLine();
         
         total_llegits++;
      }
      if (total_llegits < nombrePatrons) {
         throw new IOException();
      }
      
      Date data = new Date();
      Random generador = new Random();
		generador.setSeed(data.getTime());
      Iterator it = patrons.iterator();
      Integer vector[][] = new Integer[74][1000];
      int comptador = 0;
      // Transformem la colecció en un vector
      while (it.hasNext() && (comptador < nombrePatrons)) {
         vector[comptador] = (Integer[])it.next();
         for (int i=0; i< 1000; i++) {
            if (generador.nextInt(99) < soroll) {
               vector[comptador][i] = new Integer (vector[comptador][i].intValue() * (-1));
            }
         }
         comptador++;
      }
      
      
      FileWriter arxiu2 = null;
      BufferedWriter sortida = null;
      try {
         arxiu2 = new FileWriter("soroll"+soroll+".txt");
         sortida = new BufferedWriter(arxiu2);
         for (int i=0; i< 74; i++) {
            for (int j=0; j< 1000; j++) {
               sortida.write(vector[i][j] + " ");
            }
            sortida.write("\n");
         }
         sortida.close();
      } catch (IOException e) {
      }
      
      //return patrons;
   }

}









