import java.util.Random; import java.util.Date; public class Tests { private static final int drive_drive = 10; private static final int drive_reves = 30; private static final int reves_drive = 50; private static final int reves_reves = 20; private static double K = 0.0005; private static double noise = 0.0001; private static double alberto_p_drive = 0.4; // alberto_p_reves = 1-alberto_p_drive private static double ana_p_drive = 0.4; // ana_p_reves = 1-ana_p_drive private static double esperanza = 0.0; private static double alberto_p_ratio = 0.1; // != 0 private static double ana_p_ratio = 0.1; // != 0 private static Random r = new Random(new Date().getTime()); private static double cerouno(double in) { if (in<0.0) return 0.0; if (in>1.0) return 1.0; return in; } private static void init() { esperanza = alberto_p_drive * ana_p_drive * drive_drive + alberto_p_drive * (1-ana_p_drive) * drive_reves + (1-alberto_p_drive) * ana_p_drive * reves_drive + (1-alberto_p_drive) * (1-ana_p_drive) * reves_reves; String alberto = String.format("Alberto P drive: %.4f (%+.4f); ", alberto_p_drive, alberto_p_ratio); String ana = String.format("Ana P drive: %.4f (%+.4f); ", ana_p_drive, ana_p_ratio); System.out.println("Estado inicial: " + alberto + ana); } private static void step(int i) { // Aplicamos el gradiente del paso anterior double nuevo_alberto_p_drive = cerouno(alberto_p_drive + alberto_p_ratio); double nuevo_ana_p_drive = cerouno(ana_p_drive + ana_p_ratio); // Calculamos la esperanza de la nueva situacion double nuevo_esperanza = nuevo_alberto_p_drive * nuevo_ana_p_drive * drive_drive + nuevo_alberto_p_drive * (1-nuevo_ana_p_drive) * drive_reves + (1-nuevo_alberto_p_drive) * nuevo_ana_p_drive * reves_drive + (1-nuevo_alberto_p_drive) * (1-nuevo_ana_p_drive) * reves_reves; // Calculamos una estimación del gradiente double gradiente_alberto = (nuevo_esperanza - esperanza) / (nuevo_alberto_p_drive - alberto_p_drive); double gradiente_ana = (nuevo_esperanza - esperanza) / (nuevo_ana_p_drive - ana_p_drive); if (Double.isNaN(gradiente_alberto) || Double.isInfinite(gradiente_alberto)) gradiente_alberto = 0.0; if (Double.isNaN(gradiente_ana) || Double.isInfinite(gradiente_ana)) gradiente_ana = 0.0; alberto_p_ratio = gradiente_alberto * K; // Alberto quiere maximizar ana_p_ratio = -gradiente_ana * K; // Ana quiere minimizar, por eso el signo negativo alberto_p_ratio += r.nextGaussian()*noise; ana_p_ratio += r.nextGaussian()*noise; // Preparamos el siguiente paso alberto_p_drive = nuevo_alberto_p_drive; ana_p_drive = nuevo_ana_p_drive; esperanza = nuevo_esperanza; // Mostramos el progreso String e = String.format("%3d: %3f; ", i, esperanza); String alberto = String.format("Alberto P drive: %.4f (%+.4f); ", alberto_p_drive, alberto_p_ratio); String ana = String.format("Ana P drive: %.4f (%+.4f); ", ana_p_drive, ana_p_ratio); System.out.println(e + alberto + ana); } public static void main(String[] args) { init(); for (int i=0; i<1000; i++) { step(i); } } }