Domáca č. 6 - Hill Climbing algorithm (podla toho co vravel Oravec...)

Created: 2008-11-23 - 11:45


import java.util.ArrayList;


public class HillClimbing {
	/**
	 * @param args
	 */
	
	final private static double Pperm = 0.2;
	
	final private static int k = 2;
	final private static int n = 7;
	final private static int c0 = 5;
	
	//kedze hladame maximum tak:
	private static double max;
	
	public static double f(double x1,double x2){
		//dajme si, ze f(x) = sin(x1)cos(2x2)
		return Math.sin(x1)*Math.cos(2*x2);
	}
	
	public static int[] vymysliCislo(int dlzka){
		//toto len generuje pole nul a jednotiek...
		int[] cislo = new int[dlzka];
		for (int i = 0; i < cislo.length; i++) {
			int n = (int)(Math.random()*100-50);
			if(n>0)
				cislo[i]=1;
			else
				cislo[i]=0;
		}
		return cislo;
	}
	
	public static int[] prevedDoGrayovhoKodu(int[] hodnoty){
		int[] noveHodnoty = new int[hodnoty.length];
		if(hodnoty.length!=0){
			noveHodnoty[0]=hodnoty[0];
			for (int i = 1; i < noveHodnoty.length; i++) {
				noveHodnoty[i]=hodnoty[i-1]^hodnoty[i]; //binarny XOR ^
			}
		}
		return noveHodnoty;
	}
	
	public static int[] prevedZGrayovhoKodu(int[] hodnoty){
		int[] noveHodnoty = new int[hodnoty.length];
		if(hodnoty.length!=0){
			noveHodnoty[0]=hodnoty[0];
			for (int i = 1; i < noveHodnoty.length; i++) {
				noveHodnoty[i]=hodnoty[i]^noveHodnoty[i-1];
			}
		}
		return noveHodnoty;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		hillClimbing(k, n, c0, vymysliCislo(k*n));
	}
	
	public static ArrayList<Integer[]> ziskajMnozinu(int c0,int[] vektorVGrayovomKode){
		ArrayList<Integer[]> u = new ArrayList<Integer[]>();
		
		for(int i=0;i<c0;i++){
			int[] spracovavanyVektor = vektorVGrayovomKode.clone();
			Integer[] permutovany = new Integer[vektorVGrayovomKode.length];
			for(int j=0;j<spracovavanyVektor.length;j++){
				double nahoda = Math.random();
				if(nahoda<Pperm){
					if(spracovavanyVektor[j]==0)
						spracovavanyVektor[j]=1;
					else
						spracovavanyVektor[j]=0;
				}
			}				
			
			for (int j = 0; j < permutovany.length; j++) {
				permutovany[j] = Integer.valueOf(spracovavanyVektor[j]);
			}
			u.add(permutovany);
		}
		Integer[] suRovnake = u.get(0);
		boolean jeTrebaToPrejstZnova = true;
		for (Integer[] integers : u) {
			if(!integers.equals(suRovnake))
				jeTrebaToPrejstZnova = false;
		}
		if(jeTrebaToPrejstZnova)
			return ziskajMnozinu(c0, vektorVGrayovomKode);
		else
			return u;
	}
	
	public static int[] ziskajOptimum(ArrayList<Integer[]> lokalneOptima){
		int[] optimalnaHodnota = new int[lokalneOptima.get(0).length];
		double nmax = 0;
		for(Integer[] i : lokalneOptima){
			int[] pom = new int[i.length];
			for (int j = 0; j < i.length; j++) {
				pom[j] = (int)i[j];
			}
			pom = prevedZGrayovhoKodu(pom);
			
			int intAlpha1=0; 
			//hodnota alpha v prir. cislach
			for (int j = (pom.length-1); j >= pom.length/2; j--) {
				intAlpha1+=pom[j]*Math.pow(2, pom.length-j-1);
			}
			double realAlpha1=0+(3*Math.PI-0)/(Math.pow(2, n)-1)*intAlpha1; 
			
			int intAlpha2=0; 
			//hodnota alpha v prir. cislach
			for (int j = (pom.length/2+1); j >= 0; j--) {
				intAlpha2+=pom[j]*Math.pow(2, pom.length/2-j);
			}
			double realAlpha2=0+(3*Math.PI-0)/(Math.pow(2, n)-1)*intAlpha2; 
			
			double hodnota = f(realAlpha1,realAlpha2);
			if(nmax<hodnota){
				nmax = hodnota;
				optimalnaHodnota = pom.clone();
			}
				
		}
		if(max<nmax) max = nmax;
		return optimalnaHodnota;
	}
	
	public static void hillClimbing(int k,int n, int c0,int[] pociatocnyVektor){
		//hladame napr. maximum na intervale <0,3pi>x<0,3pi>
		for(int t = 0; t < 100;t++){
			int[] vGrayovomKode = prevedDoGrayovhoKodu(pociatocnyVektor);
			ArrayList<Integer[]> lokalneOptima = ziskajMnozinu(c0, vGrayovomKode);
			int[] optimalnaHodnota = ziskajOptimum(lokalneOptima);
			pociatocnyVektor = optimalnaHodnota.clone();
		}
		System.out.println(max);
	}

}