Кроссовер в генетическом алгоритме

Часть, где я получаю сообщение об ошибке (точнее, когда я получаю всплывающее окно с сообщением об ошибке отладки! Был вызван Abort()), — это часть, в которой я пытаюсь выполнить пересечение.

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

Этого достаточно, чтобы отобразить «тест 0» или «тест 1», но на самом деле он не назначит гены отца/матери новому индивидууму.

Я пытался изменить строку, в которой старые гены присваиваются новому индивидууму, но, что бы я ни пытался, я не могу заставить это работать.

Если бы кто-нибудь мог показать мне, где (или как) я ошибаюсь, я был бы очень благодарен :)

Изменить: пройдя через отладчик, я получаю следующее

http://prnt.sc/b0iprq Необработанное исключение в .... в LearnCPP.exe: Исключение Microsoft C++: std::out_of_range в ячейке памяти.....

Другое редактирование: чтобы было ясно, именно в этой строке происходит прерывание:

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

person Milan    schedule 05.05.2016    source источник
comment
Лучший способ выяснить, что не так, — просмотреть код с помощью отладчика.   -  person πάντα ῥεῖ    schedule 05.05.2016
comment
Я сделал, но это не делает его более ясным для меня: \ prnt.sc/b0iprq получить. В тексте: Необработанное исключение в .... в LearnCPP.exe: Исключение Microsoft C++: std::out_of_range в ячейке памяти .....   -  person Milan    schedule 05.05.2016
comment
Проверьте, содержат ли k и i допустимые значения для доступа к элементам, когда вы достигнете этой строки.   -  person πάντα ῥεῖ    schedule 05.05.2016
comment
Я только что проверил это следующим образом: Которые должны быть действительными значениями. Отец и мать также имеют допустимое значение, я обычно вывожу это, но я обрезал код, прежде чем публиковать его здесь. Я также только что попробовал это, просто заставив его вывести i и k, прежде чем пытаться присвоить значения новому вектору, и он выводит i = 0 и k = 1, что правильно.   -  person Milan    schedule 05.05.2016


Ответы (1)


Я удивлен, что вы получаете "test0" или "test1" без std::endl

Следите за историей new_individuals

Вы выделяете и изменяете его размер с помощью

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

Рядом с этим resize() у вас есть вектор из population_size (5) one_individual элементов, где chromosomes — это std::vector<std::vector<double>> размера 0.

Затем вы изменяете размер chromosomes с помощью

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

На данный момент у вас есть cromosomes размера number_of_variables (7), но что это значит?

Это означает, что каждое cromosomes является std::vector из семи std::vector<double> нулевого размера.

Итак, когда вы получаете доступ

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

с k == 1 (почему 1, а не 0?) и i == 0, new_individual[1].chromosomes[0] существуют, но имеют размер 0, new_individuals[k].chromosomes[0].at(i) проверьте размер chromomoses[0], чтобы увидеть, если хотя бы 1, не удастся и вызовет исключение (std::out_of_range)

Вы намеревались выделить каждому new_individuals[i].chromosomes[j]?

Или вы хотели написать

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

?

p.s.: извините за мой плохой английский.

--- ИЗМЕНИТЬ---

Если вы намерены зарезервировать 7x7 chromosomes, один из способов может быть

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

Даже используя push_back(), я предлагаю вам зарезервировать место

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);
}
person max66    schedule 05.05.2016
comment
new_individuals[k].chromosomes[0].push_back(индивидуалы[отец].chromosomes[0].at(i)); именно то, что мне действительно было нужно! Большое спасибо. Что касается того, почему k == 1, а не 0, то первый вектор (так что k = 0) уже заполнен лучшими генами из последнего поколения, как этакий просто элитизм. Еще один вопрос: как мне изменить размер, если я хочу, чтобы хромосомы были вектором размера 7, а не размера 0? Я думал, что, выполняя хромосомы. resize, я изменяю их размер до 7, но вы говорите, что я не изменяю размер вектора? В любом случае, большое спасибо! - person Milan; 05.05.2016
comment
Еще раз спасибо за ваше редактирование :) Вы были очень полезны, спасибо. - person Milan; 05.05.2016