遗传算法是一种仿生算法,用于获得一些问题的满意解,自己感觉这种算法很有意思,就写了这个程序(后来交了大作业)。
源代码:http://pan.baidu.com/s/1bosWRIf
下面抄自百度百科:
遗传算法(Genetic Algorithm)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。遗传算法是从代表问题可能潜在的解集的一个种群(population)开始的,而一个种群则由经过基因(gene)编码的一定数目的个体(individual)组成。每个个体实际上是染色体(chromosome)带有特征的实体。染色体作为遗传物质的主要载体,即多个基因的集合,其内部表现(即基因型)是某种基因组合,它决定了个体的形状的外部表现,如黑头发的特征是由染色体中控制这一特征的某种基因组合决定的。因此,在一开始需要实现从表现型到基因型的映射即编码工作。由于仿照基因编码的工作很复杂,我们往往进行简化,如二进制编码,初代种群产生之后,按照适者生存和优胜劣汰的原理,逐代(generation)演化产生出越来越好的近似解,在每一代,根据问题域中个体的适应度(fitness)大小选择(selection)个体,并借助于自然遗传学的遗传算子(genetic operators)进行组合交叉(crossover)和变异(mutation),产生出代表新的解集的种群。这个过程将导致种群像自然进化一样的后生代种群比前代更加适应于环境,末代种群中的最优个体经过解码(decoding),可以作为问题近似最优解。
在优选的过程中我选择了轮盘赌:
int Group::Select() //轮赌盘选择法
{
int P,i;
double FitAdd=0,Sum=FitSum;
P = RandIs();
for (i = 0;i < GROUP_NUM;i++)
{
FitAdd += Group[i].Fitness;
if ((FitAdd * 100.0 / Sum) > P)
return i;
}
return i;
}
下面是变异过程的代码:
void Group::AcrossAndVariation() //负责传代时的交叉和变异
{
int AcrossNum1,AcrossNum2,i;
for (i=0;i<GROUP_NUM-1;i+=2)
{
AcrossNum1=Select();
AcrossNum2=Select();
if(RandIs() > P_Across)
{
int Pos = RandPos();
memcpy(GroupNext[i].DNA,Group[AcrossNum1].DNA,Pos*sizeof(int));
memcpy(GroupNext[i].DNA+Pos,Group[AcrossNum2].DNA,DNA_LEN*sizeof(int));
Point.Del(Pos,GroupNext[i].DNA);
memcpy(GroupNext[i+1].DNA,Group[AcrossNum2].DNA,Pos*sizeof(int));
memcpy(GroupNext[i+1].DNA+Pos,Group[AcrossNum1].DNA,DNA_LEN*sizeof(int));
Point.Del(Pos,GroupNext[i+1].DNA);
}
else
{
memcpy(GroupNext[i].DNA,Group[AcrossNum1].DNA,DNA_LEN*sizeof(int));
memcpy(GroupNext[i+1].DNA,Group[AcrossNum2].DNA,DNA_LEN*sizeof(int));
}
if(RandIs() > P_Variation)
{
int Pos1 = RandPos(),Pos2 = RandPos(),Temp;
Temp = GroupNext[i].DNA[Pos1];
GroupNext[i].DNA[Pos1] = GroupNext[i].DNA[Pos2];
GroupNext[i].DNA[Pos2] = Temp;
Pos1 = RandPos();
Pos2 = RandPos();
Temp = GroupNext[i+1].DNA[Pos1];
GroupNext[i+1].DNA[Pos1] = GroupNext[i+1].DNA[Pos2];
GroupNext[i+1].DNA[Pos2] = Temp;
}
}
memcpy(Group,GroupNext,sizeof(Group));
}
程序截图:
自我感觉遗传算法可能不是很快速的算法,但是它的普适性很强。