Двухточечная операция кроссовера
Я пытался написать код для двухточечной операции кроссовера в генетическом алгоритме. Сначала выбирается два случайных генных местоположения. После этого две хромосомы меняют свои гены, которые расположены между случайными числами, называемыми genelocation1 и genelocatıon2.
for example First Gene [0.3,0.2,0.4,0,0.1,0.5,0.7]
Second Gene [0.25,0.6,0.45,0.15,0.80,0.9,0.85]
rndm genelocation1=3
rdnm gnelocation2 =5
child Gene1 [0.3,0.2,0.4,0.15,0.80,0.5,0.7]
Gene2 [0.25, 0.6, 0.45, 0, 0.1,0.9,0.85]
Моя проблема заключается в следующем: так как два числа генерируются случайным образом, я не мог определить массив, как массив [genelocation2-genelocation1].. Как я могу решить проблему. вот мой весь код о двухточечном кроссовере. указатели могут быть решением, но я не очень хорош в указателях.
Вот код:
void Xover (int mother,int father)
{
int tempo;
int Rndmgenelocation1=(rand()%ActivityNumber);
int Rndmgenelocation2=(rand()%ActivityNumber);
if (Rndmgenelocation1>Rndmgenelocation2)//sure that 2>1
{
tempo=Rndmgenelocation1;
Rndmgenelocation1=Rndmgenelocation2;
Rndmgenelocation2=tempo;
}
int size=(Rndmgenelocation2-Rndmgenelocation1);
int Temp1[size];//this makes an error
int ppp=Rndmgenelocation1;
for (int pp=Rndmgenelocation1;pp<Rndmgenelocation2;pp++)
{
Temp1[pp]=Sol_list[father].Chromosome[ppp];
ppp++;
}
int pppx=Rndmgenelocation1;
for (int ppx=Rndmgenelocation1;ppx<Rndmgenelocation2;ppx++)
{
Sol_list[father].Chromosome[ppx]=Sol_list[mother].Chromosome[pppx];
pppx++;
}
int ppplx=Rndmgenelocation1;
for (int pplx=Rndmgenelocation1;pplx<Rndmgenelocation2;pplx++)
{
Sol_list[father].Chromosome[pplx]=Temp1[ppplx];
ppplx++;
}
return;
}
2 ответа
Вы не можете определить массив переменного размера в стеке. Вы могли бы использовать
int *Temp1=new int[size]
Вы тогда не должны забывать звонить
delete[] Temp1;
в конце вашей функции!
редактировать:
Я не тестировал свой код ниже, но следующее должно делать то, что вы хотите, более эффективным (и более понятным) способом:
#include <algorithm>
void Xover (int mother,int father)
{
int Rndmgenelocation1=(rand()%ActivityNumber);
int Rndmgenelocation2=(rand()%ActivityNumber);
if (Rndmgenelocation1>Rndmgenelocation2)//sure that 2>1
{
std::swap(Rndmgenelocation1,Rndmgenelocation2);
}
for (int pp=Rndmgenelocation1;pp<Rndmgenelocation2;pp++)
{
std::swap(Sol_list[father].Chromosome[pp],Sol_list[mother].Chromosome[pp]);
}
return;
}
edit2:
Я только что нашел здесь другой, еще лучший способ - STL реализует готовый к использованию алгоритм кроссовера. Использование:
#include <algorithm>
void Xover (int mother,int father)
{
int Rndmgenelocation1=(rand()%ActivityNumber);
int Rndmgenelocation2=(rand()%ActivityNumber);
if (Rndmgenelocation1>Rndmgenelocation2)//sure that 2>1
{
std::swap(Rndmgenelocation1,Rndmgenelocation2);
}
std::swap_ranges(
Sol_list[father].Chromosome[Rndmgenelocation1],
Sol_list[father].Chromosome[Rndmgenelocation2],
Sol_list[mother].Chromosome[Rndmgenelocation1]
);
return;
}
Я предполагаю, что вы не должны использовать g++
как твой компилятор. Если это так, вы можете использовать std::vector
а не массив. Просто делай
std::vector<int> array(size);
Теперь вы можете рассматривать его как "нормальный" массив, хотя operator[]
синтаксис. Также нет беспокойства по поводу утечек памяти из-за забывчивости delete
на указатель.