views:

31

answers:

2

So I've written a roulette selection function for my genetic algorithm which follows:

public String tournament(float fitness, Chromosome pop[], int selection)
{
    // roulette
    if (selection == 1)
    {
        Random random = new Random();
        float slice = random.nextFloat() * fitness;

        float curFitness = 0.0f;

        for (int i = 0; i < initialPopulation; i++)
        {
            curFitness += pop[i].fitness;

            if (curFitness >= slice)
                return pop[i].bits;
        }
    }
    return "";
}

The problem is that it is sometimes returning the blank string, which has only been placed their to satisfy the return condition. This is generally not a problem, but during some runs it causes the GA to terminate since the next step involves the crossover stage. Any ideas?

A: 

My guess would be that the problem is that your fitness is occasionally less than the sum of your pop[i].fitnesses. Try putting a return "ERROR: " + fitness + " / " + curFitness; line after the for loop but within the if, or something of that nature, and see what gets returned.

Antal S-Z
+1  A: 

So it turns out the mutation function was occasionally nulling some of my bit strings, which was causing the population to contain empty strings.

Before, it looked like this:

public String mutate(String bits)
{   
    Random random = new Random();
    StringBuffer buf = new StringBuffer(bits);
    for (int i = 0; i < bits.length(); i++)
    {
        if (random.nextFloat() < mutationRate)
        {
            if (bits.charAt(i) == '1')
            {
                buf.setCharAt(i, '0');
                                    return buf.toString();

            }
            else
            {
                buf.setCharAt(i, '1');
                                    return buf.toString();
            }
        }
    }
    return "";
}

And I changed it to this:

public String mutate(String bits)
{   
    Random random = new Random();
    StringBuffer buf = new StringBuffer(bits);
    for (int i = 0; i < bits.length(); i++)
    {
        if (random.nextFloat() < mutationRate)
        {
            if (bits.charAt(i) == '1')
            {
                buf.setCharAt(i, '0');
            }
            else
            {
                buf.setCharAt(i, '1');
            }
        }
    }
    return buf.toString();
}

Careless mistake.