2013-09-27 51 views
1

我做一個小項目,我必須寫一個遺傳算法進化我的姓名和身份證號碼相同的結果。基本上,我隨機生成的比特串必須生成ASCII字符串,並測量生成的距離。然後,我會改變最好的10代,嘗試儘可能接近我的名字和身份證。二進制轉換爲ASCII,但得到的所有位串

我有此刻的麻煩位是ASCII產生。對於第一個字符串,它工作正常,但是,儘管事實上每個字符串都不相同,但對於其餘的字符串只是重複其自身。任何人都可以看到問題嗎?任何幫助深表感謝。

到目前爲止的代碼:

import java.util.Random ; 

public class GeneticAlgorithm { 

    public static void main(String[] args) throws Exception 
    { 
     int popSize = 0 ; 
     int gen ; 
     double repRate ; 
     double crossRate ; 
     double mutRate ; 
     int seed = 9005970 ; 
     String id = "John Connolly 00000000" ; 
     int bits = 7 * id.length() ; 
     String output ; 
     int pop ; 
     int bitGen ; 

     Random rand = new Random(seed) ; 
     ConvertToAscii convert = new ConvertToAscii() ; 
     Fitness fit = new Fitness() ; 

     try { 
      popSize = Integer.parseInt(args[0]) ; 
      if(popSize < 0 || popSize > 100000) 
      { 
       System.out.print("Invalid number! A positive number between 0 and 100000 must be used for the population rate!") ; 
       System.exit(1) ; // Signifies system exit if error occurs 
      } 
      gen = Integer.parseInt(args[1]) ; 
      if(gen < 0 || gen > 100000) 
      { 
       System.out.println("Invalid number! A positive number between 0 and 100000 must be used for the generation rate!") ; 
       System.exit(1) ; 
      } 
      repRate = Double.parseDouble(args[2]) ; 
      if(repRate < 0 || repRate > 1.0) 
      { 
       System.out.println("Invalid number! A positive decimal point number between 0 and 1.0 must be used for the reproduction rate!") ; 
       System.exit(1) ; 
      } 
      crossRate = Double.parseDouble(args[3]) ; 
      if(crossRate < 0 || crossRate > 1.0) 
      { 
       System.out.println("Invalid number! A positive decimal point number between 0 and 1.0 must be used for the crossover rate!") ; 
       System.exit(1) ; 
      } 
      mutRate = Double.parseDouble(args[4]) ; 
      if(mutRate < 0 || mutRate > 1.0) 
      { 
       System.out.println("Invalid number! A positive decimal point number between 0 and 1.0 must be used for the mutation rate!") ; 
       System.exit(1) ; 
      } 
      if(repRate + crossRate + mutRate != 1.0) 
      { 
       System.out.println("The Reproduction Rate, Crossover Rate and Mutation Rate when sumed together must equal 1.0!") ; 
       System.exit(1) ; 
      } 
      output = args[5] ; 
      java.io.File file = new java.io.File(output); 
      java.io.PrintWriter writeOut = new java.io.PrintWriter(file) ; 
      StringBuffer bitString = new StringBuffer() ; 
      int bestFit = 0, fitness = 0, totalFit = 0 ; 
      String ascii = "" ; 
      writeOut.println(popSize + " " + gen + " " + repRate + " " + crossRate + " " + mutRate + " " + output + " " + seed) ; 
      for(pop = 0 ; pop < popSize ; pop++) 
      { 
       ascii = "" ; 
       writeOut.print(pop + " ") ; 
       for(int i = 0 ; i < bits ; i++) 
       { 
        bitGen = rand.nextInt(2); 
        writeOut.print(bitGen) ; 
        bitString.append(bitGen) ; 
       } 
       ascii = convert.binaryToASCII(bitString) ; 
       writeOut.print(" " + ascii) ; 
       writeOut.println() ; 
      } 
      writeOut.close() ; 
      System.exit(0) ;    

     } catch(ArrayIndexOutOfBoundsException e) { 
      System.out.println("You have entered the incorrect number of arguments!") ; 
      System.out.println("Please enter the required 6 arguments.") ; 
      System.exit(1) ; 
     } catch(NumberFormatException n) { 
      System.out.println("Invalid argument type") ; 
      System.exit(1) ; 
     } 
    } 
} 

下面是轉換代碼:

public class ConvertToAscii { 

    public String binaryToASCII(StringBuffer bitString) 
    { 
     String ascii = "" ; 
     String byteString ; 
     int decimal ; 
     int i = 0, n = 7 ; 
     int baseNumber = 2 ; 
     char asciiChar ; 
     while(n <= 154) 
     { 
      byteString = bitString.substring(i, n) ; 
      decimal = Integer.parseInt(byteString, baseNumber) ; 
      System.out.print(" " + decimal) ; 
      i += 7 ; 
      n += 7 ; 
      if(decimal < 33 || decimal > 136) 
      { 
       decimal = 32 ; 
       asciiChar = (char) decimal ; 
      } else { 
       asciiChar = (char) decimal ; 
      } 
      ascii += asciiChar ; 
     } 
     return ascii ; 
    } 

} 
+1

建議:使用'StringBuilder'代替'StringBuffer'在非線程環境。 –

回答

2

你反覆使用同一個StringBuffer的再次從不清除它。您將第一個人口添加到StringBuffer,這是第154個字符......然後第二個成員位於155-308號插槽,但是您的binaryToASCII()方法絕不會看起來過了154號插槽。

嘗試每次使用一個新的StringBuffer(並且,如上所述,嘗試使用StringBuilder,因爲它在非線程環境中效率更高)。

+1

也可以使用[StringBuilder.setLength(0)](http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html#setLength%28int%29)。 – OldCurmudgeon

1

就像他的回答dcsohl狀態,您發送和評估在每次迭代同位串。我做了這個更正,並且爲了可讀性,代碼重用和正確的數據類型而優化了代碼。

import java.util.Random ; 

public class GeneticAlgorithm { 
    public static void main(String[] args) throws Exception 
    { 
     int popSize = 0 ; 
     int gen ; 
     double repRate ; 
     double crossRate ; 
     double mutRate ; 
     int seed = 9005970 ; 
     String id = "John Connolly 00000000" ; 
     int bits = 7 * id.length() ; 
     String output ; 
     int pop ; 
     int bitGen ; 

     Random rand = new Random(seed) ; 
     ConvertToAscii convert = new ConvertToAscii() ; 
     Fitness fit = new Fitness() ; 

     try { 
      popSize = validateIntArg(args[0], "population rate"); 
      gen = validateIntArg(args[1], "generation rate"); 

      repRate = validateDoubleArg(args[2], "reproduction rate"); 
      crossRate = validateDoubleArg(args[3], "crossover rate"); 
      mutRate = validateDoubleArg(args[4], "mutationRate") ; 

      if(repRate + crossRate + mutRate != 1.0) 
      { 
       System.out.println("The Reproduction Rate, Crossover Rate and Mutation Rate when sumed together must equal 1.0!") ; 
       System.exit(1) ; 
      } 
      output = args[5] ; 
      java.io.File file = new java.io.File(output); 
      java.io.PrintWriter writeOut = new java.io.PrintWriter(file) ; 
      StringBuilder bitString = new StringBuilder() ; 

      int bestFit = 0, fitness = 0, totalFit = 0 ; 
      String ascii = "" ; 
      writeOut.println(popSize + " " + gen + " " + repRate + " " + crossRate + " " + mutRate + " " + output + " " + seed) ; 

      for(pop = 0 ; pop < popSize ; pop++) 
      { 
       bitString.setLength(0); 
       writeOut.print(pop + " "); 
       for(int i = 0 ; i < bits ; i++) 
       { 
        bitGen = rand.nextInt(2); 
        writeOut.print(bitGen); 
        bitString.append(bitGen); 
       } 
       ascii = convert.binaryToASCII(bitString) ; 
       writeOut.print(" " + ascii) ; 
       writeOut.println(); 
      } 
      writeOut.close() ; 
      System.exit(0) ;    

     } catch(ArrayIndexOutOfBoundsException e) { 
      System.out.println("You have entered the incorrect number of arguments!") ; 
      System.out.println("Please enter the required 6 arguments.") ; 
      System.exit(1) ; 
     } catch(NumberFormatException n) { 
      System.out.println("Invalid argument type") ; 
      System.exit(1) ; 
     } 
    } 

    private static int validateIntArg(String arg, String argName) { 
     int n = Integer.parseInt(arg); 
     if (n < 0 || n > 100000) { 
      System.out.print("Invalid number! A positive number between 0 and 100000 must be used for the " + argName + "!") ; 
      System.exit(1); 
     } 

     return n; 
    } 

    private static int validateDoubleArg(String arg, String argName) { 
     double n = Double.parseDouble(arg); 
     if (n < 0 || n > 100000) { 
      System.out.print("Invalid number! A positive decimal point number between 0 and 1.0 must be used for the " + argName + "!") ; 
      System.exit(1); 
     } 

     return n; 
    } 
} 

類ConvertToAscii:

public class ConvertToAscii { 

    public String binaryToASCII(StringBuilder bitString) 
    { 
     StringBuilder ascii = new StringBuilder(); 
     String byteString ; 
     int decimal ; 
     int i = 0, n = 7 ; 
     int baseNumber = 2 ; 
     char asciiChar ; 
     while(n <= 154) 
     { 
      byteString = bitString.substring(i, n) ; 
      decimal = Integer.parseInt(byteString, baseNumber) ; 
      System.out.print(" " + decimal) ; 
      i += 7 ; 
      n += 7 ; 
      if(decimal < 33 || decimal > 136) 
      { 
       decimal = 32 ; 
      } 
      asciiChar = (char) decimal ; 
      ascii.append(asciiChar); 
     } 
     return ascii.toString(); 
    } 

} 
+1

我猜我需要以任何方式清除StringBuilder?驗證args的方法現在看起來非常明顯,謝謝Marcelo! – Schonge

相關問題