package registro;

import java.util.Random;
import java.io.IOException;
import javax.swing.JOptionPane;
import java.util.StringTokenizer;
import java.io.RandomAccessFile;

/**
 * <p>Title: </p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2006</p>
 *
 * <p>Company: </p>
 *
 * @author not attributable
 * @version 1.0
 */
public class Busca_Husdorff02 extends geneticos_mejorados {
    public double P[][], Q[][];
    int m = 361;
    public static void main(String[] args) {
        double ran[][] = { {-1.5708, 1.5708}, {-1500, 1500}, {-1500, 1500}};
        System.out.println("dos");


        Busca_Husdorff02 aplica = new Busca_Husdorff02(10, 3, 20, ran);

        aplica.Itera();
        aplica.sal_ptos();

        System.out.println("Fin de ejecución");
    }


    Busca_Husdorff02(int poblacion, int parametros, int iter, double Ran[][])
    {
        super(poblacion, parametros, iter, Ran);
        P = new double[m][2];
        Q = new double[m][2];
        lee_archivo("c:\\algoritmos\\registro\\conj_A.txt", P);
        lee_archivo("c:\\algoritmos\\registro\\conj_B.txt", Q);
        guarda_ptos("inicial02.txt", P, Q);
    }

    public double funcion(double x[]) {
        double f, x1 = x[0], x2 = x[1];
        double Pn[][] = new double[m][2];
        double T[] = new double[6];
        T[0] = Math.cos(x[0]);
        T[1] = -Math.sin(x[0]);
        T[2] = x[1];
        T[3] = Math.sin(x[0]);
        T[4] = Math.cos(x[0]);
        T[5] = x[2];

        afin(P, Pn, T);

        f = distance(Pn, Q);
        return f;
    }

    public double distance(double A[][], double B[][])
    {
        int i, j, n, m;
        double min, aux;
        n = A.length;
        m = B.length;
        double dk[] = new double[n];

        for(i=0; i<n; i++)
        {
            min = d(A[i], B[0]);
            for (j = 1; j < m; j++)
            {
                aux = d(A[i], B[j]);
                if(min > aux) min = aux;
            }
            dk[i] = min;
        }
        quiksort(0, m-1, dk);
        return dk[m/2];
    }

    public double d(double x[], double y[])
    {
        double aux = (x[0] -y[0])*(x[0] -y[0]) + (x[1] -y[1])*(x[1] -y[1]);
        return(Math.sqrt(aux));
    }

    public void quiksort(int lo,int ho, double valor[])
    {
        int l = lo, h = ho;
        double aux, mid;

        if (ho > lo) {
            mid = valor[(lo + ho) / 2];
            while (l < h) {
                while ((l < ho) && (valor[l] < mid))++l;
                while ((h > lo) && (valor[h] > mid))--h;
                if (l <= h) {

                    aux = valor[l];
                    valor[l] = valor[h];
                    valor[h] = aux;

                    ++l;
                    --h;
                }
            }

            if (lo < h)
                quiksort(lo, h, valor);
            if (l < ho)
                quiksort(l, ho, valor);
        }
    }

    public void sal_ptos()
    {
        int i;
        double Pn[][] = new double[m][2], x[] = new double[3];
        double T[] = new double[6];

        for(i=0; i<3; i++) x[i] = Cromosomas[0][i];

        T[0] = Math.cos(x[0]);
        T[1] = -Math.sin(x[0]);
        T[2] = x[1];
        T[3] = Math.sin(x[0]);
        T[4] = Math.cos(x[0]);
        T[5] = x[2];

        afin(P, Pn, T);

        guarda_ptos("salida02.txt", Pn, Q);
    }

    public void genera_ptos(double P[][], double Q[][], double T[])
    {
        int i, k, l, n=P.length;
        double max =50, min = 10, aux;
        Random alfa = new Random();


        for(i=0; i<n; i++)
        {
            P[i][0] = (max - min)*alfa.nextFloat() + min;
            P[i][1] = (max - min)*alfa.nextFloat() + min;
        }

        afin(P, Q, T);

        for(i=0; i<n; i++)
        {
            aux = alfa.nextFloat();
            if(aux < 0.4)
            {
                System.out.println("Si alfa = " + aux + "i = " + i );
                Q[i][0] += alfa.nextGaussian()*10.0;
                Q[i][1] += alfa.nextGaussian()*10.0;
            }

            k = Math.abs(alfa.nextInt())%m;
            l = Math.abs(alfa.nextInt())%m;

            aux = Q[k][0];
            Q[k][0] = Q[l][0];
            Q[l][0] = aux;

            aux = Q[k][1];
            Q[k][1] = Q[l][1];
            Q[l][1] = aux;
        }
    }

    public void afin(double P[][], double Q[][], double T[])
    {
        int i, n;
        n = P.length;
        for (i = 0; i < n; i++) {
            Q[i][0] = T[0] * P[i][0] + T[1] * P[i][1] + T[2];
            Q[i][1] = T[3] * P[i][0] + T[4] * P[i][1] + T[5];
        }
    }

    public void guarda_ptos(String archivo, double A[][], double B[][])
    {
        int i;
        String aux;
        try {
            RandomAccessFile DIS = new RandomAccessFile(archivo, "rw");
            for(i=0; i<m; i++)
            {
                aux = "";
                aux += A[i][0] + " " + A[i][1] + " " + B[i][0] + " " + B[i][1] + "\n";
                DIS.writeBytes(aux);
            }
            DIS.close();
        }

        catch (IOException e) {
            JOptionPane.showMessageDialog(null, "Error" + e.toString(), "ERROR",
                                          JOptionPane.ERROR_MESSAGE);
        }
    }

    public void lee_archivo(String archivo, double A[][]) {
        String linea = "", dato = "";
        StringTokenizer st;
        int nren = 0, ncol = 0, i=0, j;
        double x, X[] = new double[2];

        try {

            RandomAccessFile DIS = new RandomAccessFile(archivo, "r");

            while (((linea = DIS.readLine()) != null)) {
                st = new StringTokenizer(linea);
                if (st.countTokens() != 0 && nren%2 != 0) {
                    st = new StringTokenizer(linea);
                    ncol = 0;
                    while (st.hasMoreTokens()) {
                        dato = st.nextToken();
                        X[ncol] = Double.parseDouble(dato);
                        ncol++;
                        if(ncol >1)
                        {
                            //System.out.print(P[0] + " " + P[1] + " -->  ");
                            ncol = 0;
                            //System.out.println(ncol + ".- " +X[1]*Math.cos(X[0]*(Math.PI/180.0)) + " " + X[1]*Math.sin(X[0]*(Math.PI/180.0)));
                            //if(i%3 ==0){
                            //    j = i/3;
                            //    System.out.println(j + " --");
                                A[i][0] = X[1] *
                                          Math.cos(X[0] * (Math.PI / 180.0));
                                A[i][1] = X[1] *
                                          Math.sin(X[0] * (Math.PI / 180.0));
                           // }
                            i++;
                        }
                    }
                }
                nren++;
            }
            DIS.close();
        } catch (IOException e) {
            JOptionPane.showMessageDialog(null, "Error" + e.toString(), "ERROR",
                                          JOptionPane.ERROR_MESSAGE);
        }
    }
}


