Search code examples
c++genetic-algorithmcrossover

Crossover in genetic algorithm


The part where I get an error (more specifically, where I get a popup saying Debug error! Abort () has been called) is the part where I try to do a crossover.

for (int i = 0; i < number_of_variables; i++)
    {
        int gene1 = gene_selection(rng);
        std::cout << gene1 << " ";
        if (gene1 == 0)
        {
            std::cout << "test 0";
            new_individuals[k].chromosomes[0].at(i) = individuals[father].chromosomes[0].at(i);
        }
        else if (gene1 == 1)
        {
            std::cout << "test 1";
            new_individuals[k].chromosomes[0].at(i) = individuals[mother].chromosomes[0].at(i);
        }
    }

It gets far enough to display "test 0" or "test 1" but it won't actually assign the genes from the father/mother to the new_individual.

I've tried changing up the line where it assigns the old genes to the new individual, but regardless of what I try I can't get it working.

If anyone could show me where (or how) I'm messing up, I'd be very thankful :)

Edit: Stepping through the debugger, I get the following

http://prnt.sc/b0iprq Unhandled exception at .... in LearnCPP.exe: Microsoft C++ exception: std::out_of_range at memory location .....

Another edit: Just to be clear, it's this exact line where the abort occurs:

new_individuals[k].chromosomes[0].at(i) = individuals[father].chromosomes[0].at(i);

Solution

  • I'm surprised you get "test0" or "test1", without a std::endl

    Follow the story of new_individuals

    You allocate and resize it with

    std::vector<one_individual> new_individuals;
    new_individuals.resize(population_size);
    

    Next this resize(), you have a vector of population_size (5) one_individual elements where chromosomes are std::vector<std::vector<double>> of size 0.

    Next you resize the chromosomes with

    for (int i = 0; i < population_size; i++)
    {
        new_individuals[i].chromosomes.resize(number_of_variables);
    }
    

    At this point you have cromosomes of size number_of_variables (7) but what's the meaning of this?

    It's mean than every cromosomes is an std::vector of seven std::vector<double> of size zero.

    So, when you access

    new_individuals[k].chromosomes[0].at(i)
    

    with k == 1 (why 1 and not 0?) and i == 0, new_individual[1].chromosomes[0] exist but is of size 0, new_individuals[k].chromosomes[0].at(i) check the size of chromomoses[0] to see if at least 1, fail and cause an exception (std::out_of_range)

    Your intention was to allocate every new_individuals[i].chromosomes[j]?

    Or your intention was to write

    new_individuals[k].chromosomes[0].push_back(individuals[father].chromosomes[0].at(i));
    

    ?

    p.s.: sorry for my bad English.

    --- EDIT---

    If your intention is to reserve 7x7 chromosomes, one way can be

    for (int i = 0; i < population_size; i++)
    {
        new_individuals[i].chromosomes.resize(number_of_variables);
    
        for (int j = 0; j < population_size; j++)
            new_individuals[i].chromosomes[j].resize(number_of_variables);
    }
    

    Even using push_back(), I suggest you to reserve space

    for (int i = 0; i < population_size; i++)
    {
        new_individuals[i].chromosomes.resize(number_of_variables);
    
        for (int j = 0; j < population_size; j++)
            new_individuals[i].chromosomes[j].reserve(number_of_variables);
    }