2011-08-22 89 views
0

我一直在尝试编写遗传算法中两点交叉操作的代码。首先选择两个随机基因位置。之后,两条染色体交换它们的基因,这些基因位于称为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; 
} 
+0

你能解释你的变量的含义吗?母亲/父亲是价值本身还是某个数组的索引?什么是活动号码? Sol_list的结构是什么? – Heinzi

+0

母亲和父亲是我在开始时说的第一个基因和第二个基因的染色体。我错误地写了“基因”它应该是“染色体”。无论如何,活动数是基因的长度(在这个例子中是7)。 Sol_list []。染色体[]结构是我存储以前人口的数组。 (例如:Sol_list [1]。染色体是先前种群的解决方案,如第一个基因,第二个基因) – furkan

+0

我的代码对你来说可能很陌生。我接受你自己的代码,但是应该包括我在开始时说的相同的操作。两点交叉..谢谢 – furkan

回答

3

不能在堆栈上限定可变大小的阵列。 你可以使用

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:

我刚发现here是另一种更好的方式--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; 
} 
+0

感谢它给没有错误,但没有解决我的问题。如果我将Temp1定义为指针,可以使用Temp1 [0]或Temp1 [1]来存储值吗?或者我应该用什么 – furkan

+0

变量数组的大小可以作为'gcc'和'g ++'的扩展名。 – Jason

+0

您可以通过Temp1 [0]或Temp [1]访问您的代码。只是声明和删除Temp1是不同的。如果你想用临时数组的方法,你也可以考虑使用std :: vector,就像Jason在他的答案中所说的那样。但我会建议你不要使用临时数组并直接交换元素(请参阅我的答案的编辑之一) – Heinzi

0

我猜你一定不能使用g++作为你的编译器。如果是这样,您可以使用std::vector而不是数组。简单地做

std::vector<int> array(size); 

现在,你可以把它像一个“正常”的阵列虽然operator[]语法。也不用担心忘记在指针上调用delete会导致内存泄漏。