简体   繁体   中英

Converting Binary To Ascii but Getting Same Result for all bit strings

I am doing a little project where I have to write a Genetic Algorithm to evolve my name and id number. Basically I'm randomly generating bit strings which have to then be generated into strings of ascii characters and measure to see how close the generation gets. I will then mutate the best 10 generations to try and get it as close as possible to my name and id.

The bit I am having trouble with at the moment is the ascii generation. It works fine for the first bit string but then just repeats itself for the rest of them despite the fact that each bit string is different. Can anyone see the problem? Any help is much appreciated.

Code so far:

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) ;
        }
    }
}

Here is the conversion code:

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 ;
    }

}

You're using the same StringBuffer over and over again and never clearing it. You add the first member of your population to the StringBuffer, which is the first 154 characters... and then the second member is in slots 155-308, but your binaryToASCII() method never looks past slot 154.

Try using a new StringBuffer each time (and, as commented above, try using a StringBuilder since it's more efficient in non-threaded environments).

Like dcsohl states in his answer, you are sending and evaluating the same bitString in every iteration. I did this correction, and also optimized the code a bit for readibility, code reutilization and correct data types.

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;
    }   
}

Class 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();
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM