//采用了保优的选择遗传算法
//终止条件的判断是:到达一定的代数。可改进为:相邻若干代的种群平均适应值的变化来判断。若相邻若干代的种群平均适应值为变化或者是变化
//小于某一阈值,表示算法已经收敛,则退出算法。
//选择算子:轮盘赌选择;
//交叉算子:单点交叉,随机选择计算此适应度值,若大于当前最佳适应度值则降低交叉概率,否则不变;
//变异算子:模板,对于优势个体,除采用低概率变异外,变异位置应采取权值越大,变异概率越小的原则,而对劣势个体则相反.
#include <stdio.h>
#include "malloc.h"
#include <math.h>
#include <string.h>
#include "stdlib.h"
// 全局变量
struct individual //个体
{
unsigned *chrom; // 染色体
double fitness; // 个体适应度
double varible; // 个体对应的变量值
int xsite; // 交叉位置
int parent[2]; // 父个体
int *utility; // 特定数据指针变量
};
struct bestever // 最佳个体
{
unsigned *chrom; // 最佳个体染色体
double fitness; // 最佳个体适应度
double varible; // 最佳个体对应的变量值
int generation; // 最佳个体生成代
};
struct individual *oldpop; // 当前代种群
struct individual *newpop; // 新一代种群
struct bestever bestfit; // 最佳个体
double sumfitness; // 种群中个体适应度累计
double max; // 种群中个体最大适应度
double avg; // 种群中个体平均适应度
double min; // 种群中个体最小适应度
double pcross; // 交叉概率
double pmutation; // 变异概率
int popsize; // 种群大小
int lchrom; // 染色体长度
int chromsize; // 存储一染色体所需字节数
int gen; // 当前世代数
int maxgen; // 最大世代数
int run; // 当前运行次数
int maxruns; // 总运行次数
int printstrings; // 输出染色体编码的判断,0 -- 不输出, 1 -- 输出
int nmutation; // 当前代变异发生次数
int ncross; // 当前代交叉发生次数
double pc1;
double pc2;
double pm1;
double pm2;
int temp_mate1;
int temp_mate2;
// 随机数发生器使用的静态变量
static double oldrand[55];//存储随机数
static int jrand;
static double rndx2;
static int rndcalcflag;
// 输出文件指针
FILE *outfp ;
// 函数定义
void advance_random();
int flip(double);rnd(int, int);
void randomize();
double randomnormaldeviate();
float randomperc(),rndreal(float,float);
void warmup_random(float);
void initialize(),initdata(),initpop();
void initreport(),generation(),initmalloc();
void freeall(),nomemory(char *),report();
void writepop(),writechrom(unsigned *);
void preselect();
void statistics(struct individual *);
void title(),repchar (FILE *,char *,int);
void skip(FILE *,int);
int select();
void objfunc(struct individual *);
int crossover (unsigned *, unsigned *, unsigned *, unsigned *);
void mutation(unsigned *);
void initialize() // 遗传算法初始化
{
// 键盘输入遗传算法参数
initdata();
// 确定染色体的字节长度
chromsize = (lchrom/(8*sizeof(unsigned)));
if(lchrom%(8*sizeof(unsigned))) chromsize++;//如果还有不到一个字节的分配一字节
//分配给全局数据结构空间
initmalloc();
// 初始化随机数发生器
randomize();
// 初始化全局计数变量和一些数值
nmutation = 0;
ncross = 0;
bestfit.fitness = 0.0;
bestfit.generation = 0;
// 初始化种群,并统计计算结果
initpop();
statistics(oldpop);
initreport();
}
void initdata() // 遗传算法参数输入
{
/* char answer[2];
printf("种群大小(50-200):");
scanf("%d", &popsize);
if((popsize%2) != 0)
{
printf( "种群大小已设置为偶数\n");//只有偶数的个体总数才能完成交叉
popsize++;
}
printf("染色体长度(64-1000):");
scanf("%d", &lchrom);
printf("是否输出染色体编码(y/n):");
printstrings=1; // 输出染色体编码的判断,0 -- 不输出, 1 -- 输出
scanf("%s", answer);
if(strncmp(answer,"n",1) == 0) printstrings = 0;
printf("最大世代数(100-300):");
scanf("%d", &maxgen);
printf("交叉率(0.2-0.99):");
scanf("%f", &pcross);
printf("初始变异率(0.01-0.9):");
scanf("%f", &pmutation);
printf("pc1(0.01-0.9):");
scanf("%lf", &pc1);
printf("pc2(pc2>pc1):");
scanf("%lf", &pc2);
printf("调整变异率pm1(0.01-0.9):");
scanf("%lf", &pm1);
printf("调整变异率pm2(pm2>pm1):");
scanf("%lf", &pm2);
run=nmutation=ncross=gen=0;//各变量的初始化
max=min=avg=0.0;*/
popsize=lchrom=100;
printstrings = 0;
pcross=pmutation=0.5;
maxgen=200;
pc1=0.6;
pc2=0.8;
pm1=0.05;
pm2=0.1;
nmutation=ncross=gen=0;
max=min=avg=0.0;
}
void initpop() // 随机初始化种群
{
int j, j1, k, stop;
unsigned mask = 1;
for(j = 0; j < popsize; j++)
{
for(k = 0; k < chromsize; k++)
{
oldpop[j].chrom[k] = 0;//初始化染色体,因为一个字节可存储8个基因
if(k == (chromsize-1))
stop = lchrom - (k*(8*sizeof(unsigned)));
else
stop =8*sizeof(unsigned);
for(j1 = 1; j1 <= stop; j1++)
{
oldpop[j].chrom[k] = oldpop[j].chrom[k]<<1;//左移一位
if(flip(0.5))
oldpop[j].chrom[k] = oldpop[j].chrom[k]|mask;//按位或,即全部赋值为1
}
}
oldpop[j].parent[0] = 0; // 初始父个体信息
oldpop[j].parent[1] = 0;
oldpop[j].xsite = 0;
objfunc(&(oldpop[j])); // 计算初始适应度
}
}
void initreport() // 初始参数输出
{
// void skip();
skip(outfp,1);
printf(" 基本遗传算法参数\n");
printf(" -------------------------------------------------\n");
printf(" 种群大小(popsize) = %d\n",popsize);
printf(" 染色体长度(lchrom) = %d\n",lchrom);
printf(" 最大进化代数(maxgen) = %d\n",maxgen);
printf(" 交叉概率(pcross) = %f\n", pcross);
printf(" 变异概率(pmutation) = %f\n", pmutation);
printf(" -------------------------------------------------\n");
skip(outfp,1);
fflush(outfp);//清除文件缓冲区,文件以写方式打开时将缓冲区内容写入文件
}
void generation()
{
int mate1, mate2, jcross, j = 0;
// 每代运算前进行预选
preselect();
// 选择, 交叉, 变异
do
{
// 挑选交叉配对
mate1 = select();
temp_mate1=mate1;
mate2 = select();
temp_mate2=mate2;
// 交叉,产生两个子代个体
jcross = crossover(oldpop[mate1].chrom, oldpop[mate2].chrom, newpop[j].chrom, newpop[j+1].chrom);
//变异
// 自适应变异概率
if(gen!=0)
{
if(newpop[j].fitness>=avg) //若新生个体适应度大于前一代平均适应度,则减小变异概率
pmutation = pm1-(pm1-pm2)*(max-newpop[j].fitness)/(max-avg);
else
pmutation = pm1; //否则变异概率不变
}
mutation(newpop[j].chrom);
if(gen!=0)
{
if(newpop[j+1].fitness>=avg)
pmutation = pm1-(pm1-pm2)*(max-newpop[j+1].fitness)/(max-avg);
else
pmutation = pm1;
}
mutation(newpop[j+1].chrom);
// 解码, 计算适应度
objfunc(&(newpop[j]));
//记录亲子关系和交叉位置
newpop[j].parent[0] = mate1+1;
newpop[j].xsite = jcross;
newpop[j].parent[1] = mate2+1;
objfunc(&(newpop[j+1]));
newpop[j+1].parent[0] = mate1+1;
newpop[j+1].xsite = jcross;
newpop[j+1].parent[1] = mate2+1;
j = j + 2;
}
while(j < (popsize-1));
}
void initmalloc() //为全局数据变量分配空间
{
unsigned nbytes;
int j;
// 分配给当前代和新一代种群内存空间
nbytes = popsize*sizeof(struct individual);
if((oldpo
AGA.rar_aga_best fitness_改进遗传算法_轮盘_遗传算法 改进
版权申诉
192 浏览量
2022-09-21
05:26:48
上传
评论
收藏 6KB RAR 举报
我虽横行却不霸道
- 粉丝: 75
- 资源: 1万+
最新资源
- Delphi教程&案例&软件项目管理案例教程(第四版)课后习题答案.pdf
- Nasa高分卫星火点监测数据接入源码
- 基于区块链的图片版权保护系统的设计与实现+详细文档+全部资料(高分毕业设计).zip
- N0100P-VB一款SOT23封装P-Channel场效应MOS管
- 数据分析2024版Tecplot360中文教程最全解析.ppt
- 基于区块链的图片版权保护系统的设计与实现+详细文档+全部资料(高分毕业设计).zip
- 上海大众帕萨特1.8GLI 2005款线路图
- MVSF2N02ELT1G-VB一款SOT23封装N-Channel场效应MOS管
- 基于区块链的图片版权保护系统的设计与实现+详细文档+全部资料(高分毕业设计).zip
- MVGSF1N03LT1G-VB一款SOT23封装N-Channel场效应MOS管
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
评论0