0

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);
Milan
  • 205
  • 2
  • 9
  • The best way to find out what's wrong is stepping through your code with the debugger. – πάντα ῥεῖ May 05 '16 at 11:04
  • I did, but it doesn't make it much clearer for me :\ http://prnt.sc/b0iprq is what I get. In text: Unhandled exception at .... in LearnCPP.exe: Microsoft C++ exception: std::out_of_range at memory location ..... – Milan May 05 '16 at 11:07
  • Check if `k` and `i` contain valid values to access the elements when you reach that line. – πάντα ῥεῖ May 05 '16 at 11:13
  • I just tested it this way: new_individuals[1].chromosomes[0].at(0) = individuals[father].chromosomes[0].at(0); Which should be valid values.. Father and mother also both have a valid value, I normally output that but I trimmed the code before posting it on here. I also just tried it by simply having it output i and k before trying to assign values to the new vector, and it outputs i = 0 and k = 1 which is correct. – Milan May 05 '16 at 11:18

1 Answers1

1

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);
}
max66
  • 65,235
  • 10
  • 71
  • 111
  • new_individuals[k].chromosomes[0].push_back(individuals[father].chromosomes[0].at(i)); is exactly what I needed indeed! Thank you so much. As for why k == 1 and not 0, the first vector (so k = 0) is already filled with the best genes from the last generation, as a sort of simply elitism. Just one more question, how should I have done the resizing if I wanted to have chromosomes as a vector of size 7 instead of size 0? I thought by doing the chromosomes.resize I was resizing them to 7, but you say I'm not resizing the vector? Anyway, thanks so much! – Milan May 05 '16 at 12:27
  • Thanks again for your edit :) You've been very helpful, thanks. – Milan May 05 '16 at 13:07