function selected =selection (pop , popsize , stringlength , dimension) //选择算子,其中参数pop表示种群,popsize表示种群规模,stringlength表示染色体的长度,dimension表示维数
popsize-new =size(pop , 1); //popsize-new表示pop种群的列数
r =rand(1 , popsize); //r是一个随机数,大小介于1和popsize之间
fitness =pop(:, dimension *stringlength +1);//fitness是适应度,接下来的两行代码来求pop种群的染色体平均适应度
fitness =fitness/sum(fitness);
fitness =cumsum(fitness);
for i =1 :popsize //每一行
for j =1 :popsize-new//每一列
if r(i)<=fitness(j) //如果平均适应度大于随机数
selected(i , :)=pop(j , :); //那么就选中这个个体
break ;
end
end
end
每一代群体中每一个个体的适应度都必须算出来对吧,把它存在一个向量里面,然后将每一代中适应度最大的max()和平均值mean()取出来放在一个向量里面,当进化完毕的时候画出这个向量就行了
1楼的不是遗传算法吧!
刚好做过这个遗传算法解背包问题的论文,给你回答啦~~独家哦,分数要给偶~~
1、程序开发环境
开发环境:Visual C++60 (把Fortran程序改为VC)
*** 作系统:Windows 2003 Professional
2、程序性能对比
运行时间与加速比(如表1所示)
进程数p(个) 1 2 4
运行时间t(秒) 129s 78s 38s
加速比s 165 338
表1、运行时间与加速比
3、程序运行结果:
实例数据:
假设物体的重量Weight、物体的收益Profit和背包的容量Contain 分别为:
Weight={ 80,82,85,70,72, 70,66,50,55,25 ,
50,55,40,48,50, 32,22,60,30,32 ,
40,38,35,32,25, 28,30,22,50,30 ,
45,30,60,50,20 , 65,20,25,30,10 ,
20,25,15,10,10 , 10,4, 4, 2, 1 }
Profit={ 220,208,198,192,180, 180,165,162,160,158,
155,130,125,122,120 , 118,115,110,105,101,
100,100,98, 96, 95, 90, 88, 82, 80, 77 ,
75, 73, 72, 70, 69, 66, 65, 63, 60, 58,
56, 50, 30, 20, 15, 10, 8, 5, 3, 1}
Contain=1000,
如何选择哪些物品装入该背包可使得在背包的容量约束限制之内所装物品的总价值最大
传统的算法(动态规划、递归回溯法和贪心算法所得结果:
总价值为3077 , 总重量为999。
2001年张铃,张钹教授在计算机学报上发表的《佳点集遗传算法》所得结果
总价值为3103, 总重量为1000。
我们算法所得结果: 总价值为3103, 总重量为1000。
我们所求得最优解的个体分配情况为:
11010 10111 10110 11011 01111 11101 00001 01001 10000
01000
算法 最大迭代次数 总价值为 总重量为
传统的算法 400 3077 999
佳点集算法 70 3103 1000
遗传算法 75 3103 1000
// knapsackcpp : Defines the entry point for the console application
//
#include "stdafxh"
#include <AfxWinh>
#include <stdlibh>
#include <mathh>
#include <timeh>
#include <conioh>
#include <stdioh>
// 重要常量参数
#define popsize 200 //种群的规模
#define pc 0618 //杂交概率
#define pm 003 //变异概率
#define lchrom 50 //染色体长度
#define maxgen 1000 //最大进化代数
struct population
{
unsigned int chrom[lchrom]; //染色体
double weight; //背包重量
double fitness; //适应度
unsigned int parent1,parent2,cross; //双亲、交叉点
};
//新生代种群、父代种群
struct population oldpop[popsize],newpop[popsize];
//背包问题中物体重量、收益、背包容量
int weight[lchrom],profit[lchrom],contain;
//种群的总适应度、最小、最大、平均适应度
double sumfitness,minfitness,maxfitness,avgfitness;
//计算适应度时使用的 惩罚函数系数
double alpha;
//一个种群中最大和最小适应度的个体
int minpop,maxpop;
/ 读入背包信息,并且计算惩罚函数系数 /
void read_infor()
{
FILE fp;
int j;
//获取背包问题信息文件
if ((fp=fopen("knapsacktxt","r"))==NULL)
{
//读取文件失败
AfxMessageBox("The file is not found",MB_OK,NULL);
return;
}
//读入物体收益信息
for (j=0;j<lchrom;j++)
{
fscanf(fp,"%d",&profit[j]);
}
//读入物体重量信息
for (j=0;j<lchrom;j++)
{
fscanf(fp,"%d",&weight[j]);
}
//读入背包容量
fscanf(fp,"%d",&contain);
fclose(fp);
}
//根据计算的个体重量,判断此个体是否该留在群体中
double cal_weight(unsigned int chr)
{
int j;
double pop_weight;//背包重量
pop_weight=0;
for (j=0;j<lchrom;j++)
{
pop_weight=pop_weight+(chr)weight[j];
chr++;
}
return pop_weight;
}
/ 种群中个体适应度计算/
double cal_fit(unsigned int chr)
{
int j;
double pop_profit;//适应度
pop_profit=0;
// pop_weight=0;
for (j=0;j<lchrom;j++)
{
pop_profit=pop_profit+(chr)profit[j];
// pop_weight=pop_weight+(chr)weight[j];
chr++;
}
return pop_profit;
}
/ 群体适应度的最大最小值以及其他信息 /
void statistics(struct population pop)
{
int i;
double tmp_fit;
sumfitness=pop[0]fitness;
minfitness=pop[0]fitness;
minpop=0;
maxfitness=pop[0]fitness;
maxpop=0;
for (i=1;i<popsize;i++)
{
//计算种群的总适应度
sumfitness=sumfitness+pop[i]fitness;
tmp_fit=pop[i]fitness;
//选择种群中最大适应度的个体
if ((tmp_fit>maxfitness)&&((int)(tmp_fit10)%10==0))
{
maxfitness=pop[i]fitness;
maxpop=i;
}
//选择种群中最小适应度的个体
if (tmp_fit<minfitness)
{
minfitness=pop[i]fitness;
minpop=i;
}
//计算平均适应度
avgfitness=sumfitness/(float)popsize;
}
// printf("\nthe max pop = %d;",maxpop);
// printf("\nthe min pop = %d;",minpop);
// printf("\nthe sumfitness = %f\n",sumfitness);
}
//报告种群信息
void report(struct population pop,int gen)
{
int j;
int pop_weight=0;
printf("the generation is %d\n",gen); //输出种群的代数
//输出种群中最大适应度个体的染色体信息
printf("The population's chrom is: \n");
for (j=0;j<lchrom;j++)
{
if (j%5==0)
{ printf(" ");}
printf("%1d",pop[maxpop]chrom[j]);
}
//输出群体中最大适应度
printf("\nThe population's max fitness is %d",(int)pop[maxpop]fitness);
printf("\nThe knapsack weight is %d\n\n",(int)pop[maxpop]weight);
}
/ 生成初始种群 /
void initpop()
{
int i,j,ispop;
double tmpWeight;
//变量用于判断是否为满足条件的个体
ispop=false;
//生成popsize个种群个体
for(i=0;i<popsize;i++)
{
while (!ispop)
{
for(j=0;j<lchrom;j++)
{
oldpop[i]chrom[j]=rand()%2; //随机生成个体的染色体
oldpop[i]parent1=0; //双亲
oldpop[i]parent2=0;
oldpop[i]cross=0; //交叉点
}
//选择重量小于背包容量的个体,即满足条件
tmpWeight=cal_weight(oldpop[i]chrom);
if (tmpWeight<=contain)
{
oldpop[i]fitness=cal_fit(oldpop[i]chrom);
oldpop[i]weight=tmpWeight;
oldpop[i]parent1=0;
oldpop[i]parent2=0;
oldpop[i]cross=0;
ispop=true;
}
}
//此个体可以加入到种群中
ispop=false;
}
}
/ 遗传 *** 作 /
//概率选择试验
int execise(double probability)
{
double pp;
//如果生成随机数大于相应的概率则返回真,否则试验不成功
pp=(double)(rand()%20001/200000);
if (pp<=probability) return 1;
return 0;
}
// 选择进行交叉 *** 作的个体
int selection(int pop)
{
double wheel_pos,rand_Number,partsum;
int parent;
//赌轮法选择
rand_Number=(rand()%2001)/20000;
wheel_pos=rand_Numbersumfitness; //赌轮大小
partsum=0;
parent=0;
do{
partsum=partsum+oldpop[parent]fitness;
parent=parent+1;
} while (partsum<wheel_pos && parent<popsize);
return parent-1;
}
/ 交叉 *** 作 /
int crossover(unsigned int parent1,unsigned int parent2,int i)
{
int j,cross_pos;
if (execise(pc))
{
//生成交叉位置0,1,(lchrom-2)
cross_pos=rand()%(lchrom-1);
}
else cross_pos=lchrom-1;
for (j=0;j<=cross_pos;j++)
{ //保留复制;
//包括在概率选择不成功时,父体完全保留
newpop[i]chrom[j]=parent1[j];
}
for(j=cross_pos+1;j<=(lchrom-1);j++)
{
//从交叉点开始交叉
newpop[i]chrom[j]=parent2[j];
}
//记录交叉位置
newpop[i]cross=cross_pos;
return 1;
}
/ 变异 *** 作 /
int mutation(unsigned int alleles)
{
if (execise(pm))
{
if (alleles)
alleles=0;
else alleles=1;
}
//返回变异值,或者返回原值
return alleles;
}
/ 群体更新 /
void generation()
{
unsigned int i,j,mate1,mate2;
double tmpWeight;
int ispop;//记录是否是符合条件的个体
i=0;
while (i<popsize)
{
ispop=false;
while (!ispop)
{
//选择
mate1=selection(i);
mate2=selection(i+1);
//交叉
crossover(oldpop[mate1]chrom,oldpop[mate2]chrom,i);
//变异
for (j=0;j<lchrom;j++)
{
newpop[i]chrom[j]=mutation(newpop[i]chrom[j]);
}
//选择重量小于背包容量的个体,即满足条件
tmpWeight=cal_weight(newpop[i]chrom);
if (tmpWeight<=contain)
{
newpop[i]fitness=cal_fit(newpop[i]chrom);
newpop[i]weight=tmpWeight;
newpop[i]parent1=mate1;
newpop[i]parent2=mate2;
ispop=true;
}
}
//此个体可以加入到种群中
i=i+1;
}
}
void main(int argc, char argv[])
{
int gen,oldmaxpop,k;
double oldmax;
read_infor();//读入背包信息
gen=0;
srand( (unsigned)time( NULL ) );//置随机种子
initpop();
memcpy(&newpop,&oldpop,popsizesizeof(struct population));
statistics(newpop);//统计新生种群的信息
report(newpop,gen);
while(gen<maxgen)
{
gen=gen+1;
if (gen%100==0)
{
srand( (unsigned)time( NULL ) );//置随机种子
}
oldmax=maxfitness;
oldmaxpop=maxpop;
generation();
statistics(newpop); //统计新生代种群信息
//如果新生代种群中个体的最大适应度小于老一代种群
//个体的最大适应度,则保存老一代种群个体的最大适应度
//否则报告新生代的最大适应度
if (maxfitness<oldmax)
{
for(k=0;k<lchrom;k++)
newpop[minpop]chrom[k]=oldpop[oldmaxpop]chrom[k];
newpop[minpop]fitness=oldpop[oldmaxpop]fitness;
newpop[minpop]parent1=oldpop[oldmaxpop]parent1;
newpop[minpop]parent2=oldpop[oldmaxpop]parent2;
newpop[minpop]cross=oldpop[oldmaxpop]cross;
statistics(newpop);
}
else if (maxfitness>oldmax)
{
report(newpop,gen);
}
//保存新生代种群的信息到老一代种群信息空间
memcpy(&oldpop,&newpop,popsizesizeof(struct population));
}
printf("It is over");
getch();
}
function main()
clc;clear all;close all;
tic; %程序运行计时
E0=0001; %允许误差
MaxNum=100; %粒子最大迭代次数
narvs=1; %目标函数的自变量个数
particlesize=30; %粒子群规模
c1=2; %每个粒子的个体学习因子,也称为加速常数
c2=2; %每个粒子的社会学习因子,也称为加速常数
w=06; %惯性因子
vmax=08; %粒子的最大飞翔速度
x=-5+10rand(particlesize,narvs); %粒子所在的位置
v=2rand(particlesize,narvs); %粒子的飞翔速度
%用inline定义适应度函数以便将子函数文件与主程序文件放在一起,
%目标函数是:y=1+(21(1-x+2x^2)exp(-x^2/2))
%inline命令定义适应度函数如下:
fitness=inline('1/(1+(21(1-x+2x^2)exp(-x^2/2)))','x');
%inline定义的适应度函数会使程序运行速度大大降低
for i=1:particlesize
for j=1:narvs
f(i)=fitness(x(i,j));
end
end
personalbest_x=x;
首先我想说的是,matlab跟其他语言不一样(我用的比较多的编程语言,除了matlab就
应该是c或c++了,VB和Delphi也接触过,我想版面(matlab版)大部分人也差不多),
如果你抱着“把其他语言的思想运用在matlab里面”的话,那么我想,即使程序运行不
出错,也很难把握matlab的精髓,也就很难发挥matlab的作用了。所以,如果你是希望
掌握一门语言、一个工具,使它更有效为你服务的话,那么,希望本文对你有所帮助,
请精读;如果你是希望matlab作为VC的附属品,即你不想在matlab上面花太多功夫,只
纯粹想用matlab来完成VC做不了或很难做成的任务的话,那么,本文你也应该至少浏览
一下。
Matlab是一个基于矩阵运算的软件,这恐怕是众所周知的事情了,但是,真正在运用的
时候(就是在编程的时候),许多人(特别是初学者)往往没有注意到这个问题,因此
,for循环(包括while循环)满天飞…………这不仅是暴殄天物(没有发挥matlab所
长),还浪费了你宝贵的时间。对此,版友MVH在他的“MATLAB 小技巧”一文中也有所
涉及,雷同的东西我也就不重复了,matlab的“帮助”里面也有相关的指示。我这里想
说的一点是,初学者往往在初始化矩阵的时候注意到这个问题,懂得了使用矩阵而不是
循环来赋值,但是,在其他环节上,就很容易疏忽,或者说,仍然没有摆脱C++的思想
。举个例子吧,下面的代码是我的一个师弟写的,我想他接触matlab也有2、3年时间了
(在此说明一下,接触2、3年并不是表示每天都会跟matlab打交道,我本人也不是,只
是在一年某几个时间段里面连续使用),但是仍然会出现类似的问题:
J = 0;
lt = size(imf1,2);
for (i = 1:lt)
if (abs(imf1(i)) 1)
J = 1;
break
end
end
上面的代码实现了一个目的――检查信号imf1(一个向量)是否存在绝对值大于1的点,
这显然是基于C++的思想写出来的。如果在matlab下面,其实用两个语句就足够了(当
然,可以合并为一个):
q = find(imf11);
J = ~isempty(q);
这样的修改带来的好处是很可观的。
又如:
for j = 1:num
imf1(start1+j) = 2li1(j+1) - imf1(start1+j);
end
这是一个对称翻折的问题,它完全可以用以下这个语句简洁表示:
imf1(start1+1:start1+num) = 2li1(2:num+1) - imf1(start1+1:start1+num);
因此,如果是新手,可以先用循环(基于C++的思想)来编写代码,然后看看能否用ma
tlab的语言(基于矩阵的思想)来改进。当然,这样做的前提是你对matlab提供的一些
函数比较熟悉才行,这些函数在matlab的“帮助”那里搜索“Functions Used in
Vectorizing”就可以找到一些,其他的也可以找相关的书籍(没找到?不可能,电子版
总可以下载到的)
对提高matlab编程能力的方法,我想主要有以下三个:
1 查help
2 多上上论坛,搜索帖子、发帖子问人
3 阅读别人、特别是牛人的程序
当然了,正如所有的程序语言一样,“3分课本7分上机”,一定要动手才行,不能光看
。多想、多思考、多尝试,才是正路。以下技巧就是平日动手编程、阅读别人的帖子后
整理出来的(不断添加中):
1 matlab的运算是基于矩阵的,但是也提供了对应元素的运算,即在运算符前面加上“
点”。例如:
a = [1,2;3,4]
a =
1 2
3 4
b = [-1,-2;-3,0]
b =
-1 -2
-3 0
a b
ans =
-7 -2
-15 -6
a b
ans =
-1 -4
-9 0
%% fitness(i)=fitness(pop(i,:)); %染色体的适应度
这个函数是需要你根据你的实际问题来编写的。
图像显示问题自行百度imshow函数。
以上就是关于怎么解释遗传算法matlab程序 以下程序至少解释三行,for、end、if function语句就不用了,谢谢。全部的内容,包括:怎么解释遗传算法matlab程序 以下程序至少解释三行,for、end、if function语句就不用了,谢谢。、MATLAB中的遗传算法最佳适应度值和平均适应度曲线怎么描绘、遗传算法求解背包问题的程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)