遗传算法,每次结果都是一样的,头疼!!

lixinlu2000 2007-04-13 09:51:11
一个小作业,用c++写的,执行后,每代种群的适应度都是一样的,最大值在第一代就能看到,各位大侠帮我看看,怎么回事?

#include <iostream>
#include <ctime>
#include <cmath>
#include <fstream>
#include <iomanip>
using namespace std;

const int popsize = 20; // 种群大小
const int lchrom = 23; // 染色体长度
const double pi = 3.14159;
const float max = 0; //函数参数上界
const float min = pi; //函数参数下界
int pop[popsize][lchrom]; // 种群
int newpop[popsize][lchrom]; //新种群
double value[popsize]; // 存放函数参数值
double ans[popsize]; //存放函数结果
int crosslchrom; //记录选择出来进行交叉的个体

void init() //采用随机方法初始化群体
{
int i,j;
srand( (unsigned)time( NULL ) );

for(i=0;i<popsize;i++)
{
for(j=0;j<lchrom;j++)
{
pop[i][j]=(rand()%2);
}
}
}

int flip(float prob) /* 以一定概率产生0或1 */
{
srand( (unsigned)time( NULL ) );
if(rand()%100 <= prob*100)
return(1);
else
return(0);
}

void calculate()
{
int i,j;
for(i=0;i<popsize;i++) //把二进值转变成十进制
{
value[i]=0;
for(j=1;j<=lchrom;j++)
value[i] += pop[i][j]*pow(2,(24-j));
}

for (i=0; i<popsize; i++) // 计算参数值
value[i] = min + value[i]*(max - min)/(pow(2,lchrom)-1);

for (i=0; i<popsize; i++) //计算个体适应度
ans[i] = value[i]*sin(value[i])+1;

}

int searchmax() //寻找具有最大适应度的个体
{
int i,t;
double popmax=0;
for(i=0;i<popsize;i++)
{
if(popmax<ans[i])
{
popmax=ans[i];
t=i;
}
}
return t;
}

int select() //赌轮法选择一个适应度高的个体
{
int i = 0;
double anssum = 0;
float jilei[popsize];
float x ;
crosslchrom = 0;
srand( (unsigned)time( NULL ) );
x = rand()%100;
for (i=0; i< popsize; i++)
anssum = anssum + ans[i]; //计算总适应度

for (i = 0; i < popsize; i++) //计算适应度比例
jilei[i] = ans[i]/anssum;

for (i = 1; i< popsize; i++) //计算积累概率
jilei[i] = (jilei[i]+jilei[i-1])*100;

if (x>jilei[crosslchrom]&&(crosslchrom<popsize))
crosslchrom++;

return crosslchrom;
}


void genertic(float crossover,float mutation,int generation)
// 产生新种群
{
int i ,j;
int cross1,cross2;
int crosspoint,crosssum,mutationpoint;
int temp[lchrom];
for (i=0;i<popsize; i++) //复制种群
for (j=0;j<lchrom;j++)
newpop[i][j] = pop[i][j];

/**************************交叉****************************/
for (crosssum=0; crosssum<(popsize/2); crosssum++)
{
if(flip(crossover))
{
cross1 = select(); //选择一个适应度高的个体
cross2 = select(); //选择另一个适应度高的个体
srand( (unsigned)time( NULL ) );
crosspoint = rand()%(lchrom-1); //随机生成交叉点

for (i=crosspoint;i<lchrom;i++) //交叉
{
newpop[cross1][i] = temp[i];
newpop[cross1][i] = newpop[cross2][i];
newpop[cross2][i] = temp[i];
}
}
}
/***********************交叉结束****************************/

/*************************变异*******************************/
for (i=0; i<popsize; i++)
{
if (flip(mutation))
{
srand( (unsigned)time( NULL ) );
mutationpoint = rand()%(lchrom-1);
newpop[i][mutationpoint] = (newpop[i][mutationpoint] + 1)%2;
}
}
/***********************变异结束****************************/
for (i=0; i<popsize; i++)
for (j=0; j<lchrom; j++)
pop[i][j] = newpop[i][j];

}


int main()
{
float crossover,mutation;//分别代表交叉,变异的概率,值小于1
int generation;//要运行的代数
int maxchrom; //最大的染色体

cout<<"本程序通过计算f(x)=x*sin(x)+1的最大值,\n其中x取[0,Pi]中的等数,\nSGA的当前运行参数是\n种群大小为:"
<<popsize<<"\n染色体长度为:"
<<lchrom<<endl;
cout<<"请输入交叉和变异选择的概率,他们的概率之和必须小于1.\n交叉:";
cin>>crossover;
cout<<"\n变异:";
cin>>mutation;
cout<<"\n请输入要运行的代数:";
cin>>generation;
cout<<endl;
init();//创建初始群体

for(int i = 0; i<generation; i++)
{
genertic(crossover, mutation, generation); //产生新种群
calculate(); //计算适应度
maxchrom = searchmax(); //寻找适应度最大的个体

/*******************输出结果**********************/

cout << "\n第" <<i+1 <<"代种群情况:\n" ;
cout << "-------染色体-------" << "-------适应度-------" << endl;
for (int j=0; j<popsize; j++)
cout <<" "<< value[j]<<" " << ans[j] << endl;

cout << "第" <<i+1<<"代种群中适应度最大个体为:"
<< ans[maxchrom] << " 对应的染色体为:"
<< value[maxchrom] << endl;



}
return 0;
}


...全文
1297 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
sml001 2007-05-08
  • 打赏
  • 举报
回复
。。。。。。你一直都算的同一个函数,结果当然一样。你把函数换换试试
freshui 2007-04-13
  • 打赏
  • 举报
回复
遗传算法拳忘了啊
lixinlu2000 2007-04-13
  • 打赏
  • 举报
回复
变异概率和代数是每次运行的时候输入的,一般都比较大。
现在的问题是:输入了这些参数后,结果应该是每一代的情况,但是输出结果却都一样,每一代的最大值都一样。
看起来就象是没有迭代一样。
pubb1986 2007-04-13
  • 打赏
  • 举报
回复
把变异率调高点
调到0.8--0.9

要不就把那代数调大点试下先
lixinlu2000 2007-04-13
  • 打赏
  • 举报
回复
懂的来看一下吧!!
帮帮忙!!!

64,685

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧