GA 경험을 가진 사람이 내 피트니스 기능을 검사 할 수 있습니까?
문제
여기에 내 문제가 있습니다. 저는 유전자 알고리즘에 대해 내가 발견 한 코드를 수정하여 기능의 수치 최적화를 수행합니다. 본질적으로 함수 F와 우리의 원하는 값이 주어지면, 프로그램은 GA를 사용하여 적절한 원하는 값을 제공하는 x 및 y의 값을 검색합니다. 나는 이슈의 근원이라고 생각하는 나의 체력 함수로 땜질을 유지합니다.
기본 코드가 중단됩니다 :
무작위 염색체 인구를 생성
각각의 염색체 휘트니스에 따라 버블 정렬을 사용하십시오
그 중 하나가 함수를 해결하는지 확인하는지 확인하십시오
하나가 해결하면 멈추고 인쇄하십시오
else, 부모를 기반으로 아이들을 창출합니다 정렬, 최상의 답변 확인, 루프
누군가 나를 올바른 방향으로 가리킬 수 있기를 바랍니다. 나는 오늘 밤 더 많이 해부 할 것입니다. 그러나 나는 이것에 걸리는 걸 칠을 한 것처럼 보입니다. 더 복잡한 코드를 사용하는 것보다 더 복잡한 기능을 보려면 무작위 백분율 (일반적으로 20 미만) 주위에 수렴하는 것 같습니다. 그러나 단순한 코딩 된 기능은 99 % 차이를 반환합니다 ... 그래서 나는 무엇을 100 %가 아닙니다.
import java.util.*;
import java.util.Comparator;
import java.util.TreeMap;
/**
* Modified from a file created Jul 9, 2003
* Original @author Fabian Jones
* Modified @author Cutright
* @version 2
*/
public class ScratchGA
{
private static int NUM_CHROMOSOMES = 100; //num of chromosomes in population
private static double MUTATE = .01; //chance of a mutation i.e. 88.8%
private static int desiredValue = 60466176; //desired value of function
private static int cutoff = 1000; // number of iterations before cut off
private static int longPrint = 0; //1 means print out each iteration of the population
private boolean done = false;
private Chromosome[] population;
int iteration = 0;
/**
* Constructor for objects of class ScratchGA
*/
public ScratchGA()
{
generateRandomPopulation(NUM_CHROMOSOMES);
printPopulation();
}
/**
* Generate a random population of chromosomes - WORKS
*
*/
private void generateRandomPopulation(int pop)
{
System.out.println("Generating random population of " + pop + ", now." +"\n");
population = new Chromosome[pop];
for(int i=0; i<pop; i++)
{
int rand = (int)(Math.random()*4095); // Range 0 to 4095
population[i] = (new Chromosome(rand, 12));
}
}
/**
* Codesaver for generating a new line in the output
*/
private void newLine()
{
System.out.println("\n");
}
/**
* Prints the population (the chromosomes)
*/
private void printPopulation()
{
int x=1; // variable to print 10 chromosomes on a line
if (iteration==0)
{
System.out.println("Initial population: " + "\n" );
}
else
{
if (longPrint ==1)
{
System.out.println("Population " + iteration + " :" + "\n");
for(int i=0; i<=(NUM_CHROMOSOMES-1); i++)
{
System.out.print(population[i] + " ");
if(x == 10)
{
newLine();
x=1;
}
else
{
x++;
}
}
newLine();
}
else
{
System.out.println("Best answer for iteration " + iteration + " is: " + population[0] + " with a % difference of " +population[0].getFitness());
newLine();
}
}
}
/**
* Start
* Bubblesort initial population by their fitness, see if the first chromosome
* in the sorted array satisfies our constraint.
* IF done ==true or max num of iterations
* Print best solution and its fitness
* ELSE
* generate new population based on old one, and continue on
*/
public void start()
{
// System.out.println("Starting bubblesort... Please Wait.");
bubbleSort();
//System.out.println("After Bubblesort: " );
//printPopulation();
topFitness();
if(done || iteration==cutoff){
System.out.println("DONE!!");
System.out.println("Best solution: " + population[0] + " % Difference: " + population[0].getFitness());
}
else{
iteration++;
generateNewPopulation();
printPopulation();
start();
}
}
/**
* If the top chromosomes fitness (after being sorted by bubblesort) is 100%
* done == true
*/
private void topFitness()
{
if (population[0].getFitness() == 0)
{
done = true;
}
}
/**
* Called from chromosome,
* Tests the x and y values in the function and returns their output
*/
public static double functionTest(int x, int y)
{
return (3*x)^(2*y); // From our desired value we're looking for x=2, y=5
}
/**
* Returns the desired outcome of the function, with ideal x and y
* Stored above in a private static
*/
public static int getDesired()
{
return desiredValue;
}
/**
* Sort Chromosome array, based on fitness
* utilizes a bubblesort
*/
private void bubbleSort()
{
Chromosome temp;
for(int i=0; i<NUM_CHROMOSOMES; i++){
for(int j=1; j<(NUM_CHROMOSOMES-i); j++){
if(population[j-1].getFitness() > population[j].getFitness())
{
//swap elements
temp = population[j-1];
population[j-1] = population[j];
population[j] = temp;
}
}
}
}
/**
* Top 30: Elitism
* Next 60: Offspring of Elitists
* Next 10: Random
*/
private void generateNewPopulation(){
System.out.println("***Generating New Population");
Chromosome[] temp = new Chromosome[100];
for (int i = 0; i < 30; i++)
{
Chromosome x = population[i];
if (shouldMutate())
mutate(x);
temp[i]=x;
}
for (int i = 0; i < 30; i++)
{
temp[i+30] =cross1(population[i], population[i+1]);
temp[i+60] = cross2(population[i], population[i+1]);
}
for (int i = 90; i<100; i++)
{
int rand = (int)(Math.random()*4095); // Range 0 to 4095
Chromosome x = new Chromosome(rand, 12);
temp[i] = x;
}
population = temp;
}
/**
* First cross type, with two parents
*/
private Chromosome cross1(Chromosome parent1, Chromosome parent2){
String bitS1 = parent1.getBitString();
String bitS2 = parent2.getBitString();
int length = bitS1.length();
int num = (int)(Math.random()*length); // number from 0 to length-1
String newBitString = bitS2.substring(0, num) + bitS1.substring(num, length);
Chromosome offspring = new Chromosome();
offspring.setBitString(newBitString);
if(shouldMutate()){
mutate(offspring);
}
return offspring;
}
/**
* Second cross type, parents given in same order as first, but reverses internal workings
*/
private Chromosome cross2(Chromosome parent1, Chromosome parent2){
String bitS1 = parent1.getBitString();
String bitS2 = parent2.getBitString();
int length = bitS1.length();
int num = (int)(Math.random()*length); // number from 0 to length-1
String newBitString = bitS2.substring(0, num) + bitS1.substring(num, length);
Chromosome offspring = new Chromosome();
offspring.setBitString(newBitString);
if(shouldMutate()){
mutate(offspring);
}
return offspring;
}
/**
* Returns a boolean of whether a character should mutate based on the mutation value at top
*/
private boolean shouldMutate(){
double num = Math.random()*100;
return (num <= MUTATE);
}
/**
* Returns a boolean of whether a character should mutate based on the mutation value at top
*/
private void mutate(Chromosome offspring){
String s = offspring.getBitString();
int num = s.length();
int index = (int) (Math.random()*num);
String newBit = flip(s.substring(index, index+1));
String newBitString = s.substring(0, index) + newBit + s.substring(index+1, s.length());
offspring.setBitString(newBitString);
}
/**
* Flips bits in a string 1 to 0, 0 to 1
*/
private String flip(String s){
return s.equals("0")? "1":"0";
}
.
}
import java.lang.Comparable;
import java.math.*;
/**
* Modified from a file created on Jul 9, 2003
* Unsure of original author
*
*/
public class Chromosome implements Comparable
{
protected String bitString;
/**
* Constructor for objects of class Chromosome
*/
public Chromosome()
{
}
public Chromosome(int value, int length)
{
bitString = convertIntToBitString(value, length);
}
public void setBitString(String s)
{
bitString = s;
}
public String getBitString()
{
return bitString;
}
public int compareTo(Object o)
{
Chromosome c = (Chromosome) o;
int num = countOnes(this.bitString) - countOnes(c.getBitString());
return num;
}
public double getFitness()
{
String working = bitString;
int x1 = Integer.parseInt(working.substring(0,6),2);
int x2 = Integer.parseInt(working.substring(6),2);
double result = ScratchGA.functionTest(x1,x2);
double percentDiff = ((ScratchGA.getDesired() - result)/ScratchGA.getDesired())*100;
if (percentDiff >= 0)
{
return percentDiff;
}
else
{
return -percentDiff;
}
}
public boolean equals(Object o)
{
if(o instanceof Chromosome)
{
Chromosome c = (Chromosome) o;
return c.getBitString().equals(bitString);
}
return false;
}
public int hashCode()
{
return bitString.hashCode();
}
public String toString()
{
return bitString;
}
public static int countOnes(String bits)
{
int sum = 0;
for(int i = 0; i < bits.length(); ++ i){
String test = bits.substring(i, i+1);
if(test.equals("1")){
sum = sum + 1;
}
}
return sum;
}
public static String convertIntToBitString(int val, int length)
{
int reval = val;
StringBuffer bitString = new StringBuffer(length);
for(int i = length-1; i >=0; --i ){
if( reval - (Math.pow(2, i)) >= 0 ){
bitString.append("1");
reval = (int) (reval - Math.pow(2, i));
}
else{
bitString.append("0");
}
}
return bitString.toString();
}
public static void main(String[] args
){
//System.out.println(convertIntToBitString(2046, 10));
Chromosome c = new Chromosome(1234, 10);
//System.out.println(c.fitness());
}
}
. 해결책
실제로, 나는 나를 잃어버린 간단한 오류였습니다.주요 문제는 return (3 * x) ^ (2 * y)을 사용하는 것이 었습니다.^ Java의 Bitwise XOR이지만 지수입니다.(WHOOPS) 문제는 Math.POW (3 * x, 2 * y)를 사용하여 수정되었습니다.... 피트니스 기능의 약간의 이중 검사는 다른 사소한 변화로 작동하고 실행 중입니다.)