QQ登录

只需一步,快速开始

快捷登录

登录 或者 注册 请先

UG爱好者

查看: 4267|回复: 15
打印 上一主题 下一主题

[原创] 一个用MATLAB编写的基于遗传算法的求一元函数最大值的程序

[复制链接]

二级士官

Rank: 2

173

主题

245

帖子

437

积分
跳转到指定楼层
楼主
发表于 2016-2-29 16:37:37 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
        最近在狂看遗传算法,这是一种经典的优化算法,我们可以把实际工程问题抽象成数学问题,变成一个含有若干未知数的函数,以及相应的约束,然后就变成了在这些约束下求这个函数的最大值或最小值的问题了,而求最大值或最小值需要用到一些优化算法,这些算法包括遗传算法,粒子群算法,蚁群算法,模拟退火算法等等等等,比如说机械中的装配线布局问题,在知道产品生产节拍,产品种类,每种产品装配工序及先后顺序,每个装配工序的运行时间的前提下,如果使得工作站的数量最少呢,工作站的数量最少也就意味着占地面积最少,投入成本最少,车间能耗最少,这个问题就可以根据产品的装配要求来把这些信息抽象成数学模型,在这个数学模型中把工作站数量设定为未知数,然后用遗传算法求这个数学模型的最小值。        这次我们用遗传算法来算一下一个函数的最大值,网上有一些类似的例子,但是经过我的查看和调试,都有些或多或少的逻辑或语法错误,经过我的不断地修改和调试,我终于调通了,下面上代码!

f(x)=10sin(5x) 7cos(4x), 其中 x∈[0,10] .rar (1.6 KB, 下载次数: 3)
        这个压缩文件,是下面的函数txt文本模式,由于最后3快函数,放在论坛上面,会出现表情符号。在这里我就上传到论坛。


题目:求下列函数的最大值,        f(x)=10*sin(5x)+7*cos(4x),  其中 x∈[0,10] 。

%Name:main.m
%主函数
clear
clf
popsize=20; %群体大小
chromlength=10; %字符串长度(个体长度)
pc=0.6; %交叉概率
pm=0.001; %变异概率

pop=initpop(popsize,chromlength); %随机产生初始群体
for i=1:20 %20为迭代次数
    [objvalue]=calobjvalue(pop); %计算目标函数
    fitvalue=calfitvalue(objvalue); %计算群体中每个个体的适应度
    [newpop]=selection(pop,fitvalue); %复制
    [newpop]=crossover(pop,pc); %交叉
    [newpop]=mutation(pop,pm); %变异
    [bestindividual,bestfit]=best(pop,fitvalue); %求出群体中适应值最大的个体及其适应值
    y(i)=max(bestfit);
    n(i)=i;
    pop5=bestindividual;
    x(i)=decodechrom(pop5,1,chromlength)*10/1023; %转十进制
    pop=newpop;
end

fplot('10*sin(5*x)+7*cos(4*x)',[0 10])
hold on
plot(x,y,'r*')
hold off

[z index]=max(y); %计算最大值及其位置
x5=x(index)%计算最大值对应的x值
y=z

%Name: initpop.m
%初始化
function pop=initpop(popsize,chromlength)
pop=round(rand(popsize,chromlength)); % rand随机产生每个单元为 {0,1} 行数为popsize,列数为chromlength的矩阵,
% round对矩阵的每个单元进行圆整。这样产生的初始种群。

%Name: decodechrom.m
%将二进制编码转换成十进制之前对二进制位的截取,其实等你看懂这个题目时会发现对于这个例题,这个函数的功能完全可以略过
function pop2=decodechrom(pop,spoint,length)
pop1=pop(:,spoint:spoint+length-1);
pop2=decodebinary(pop1);

%Name: decodebinary.m
%将二进制转化为十进制
function pop2=decodebinary(pop)
[px,py]=size(pop); %求pop行和列数
for i=1:py
pop1(:,i)=2.^(py-i).*pop(:,i);
end
pop2=sum(pop1,2); %求pop1的每行之和

%Name: calobjvalue.m
%实现目标函数的计算
function [objvalue]=calobjvalue(pop)
temp1=decodechrom(pop,1,10); %将pop每行转化成十进制数
x=temp1*10/1023; %将二值域 中的数转化为变量域 的数
objvalue=10*sin(5*x)+7*cos(4*x); %计算目标函数值




%Name:calfitvalue.m
%计算个体的适应值
function fitvalue=calfitvalue(objvalue)
[px,py]=size(objvalue);
for i=1:px
    if objvalue(i)>0
        temp=objvalue(i);
    else
        temp=0.0;
    end
    fitvalue(i)=temp;
end
fitvalue=fitvalue';

%Name: selection.m
%选择复制
function [newpop]=selection(pop,fitvalue)
totalfit=sum(fitvalue); %求适应值之和
fitvalue=fitvalue/totalfit; %单个个体被选择的概率
fitvalue=cumsum(fitvalue); %如 fitvalue=[1 2 3 4],则 cumsum(fitvalue)=[1 3 6 10]
[px,py]=size(pop);
ms=sort(rand(px,1)); %从小到大排列
fitin=1;
newin=1;
while newin<=px
    if(ms(newin))<fitvalue(fitin)
        newpop(newin)=pop(fitin);
        newin=newin+1;
    else
        fitin=fitin+1;
    end
end
















        以上就是这个题目用遗传算法的解题代码了,绝对能够调试通过,只不过遗传算法是一种激励式的算法,它只有在一定概率的情况下能求得全局最优解,一般是求得局部最优解,所以这种算法的最终结果只是个参考的解,如何提高解的最优性,是无数专家学者研究的热点,对于这里例题,大家可以通过增加繁殖的代数来缓解这个问题,这个代码中只繁衍了20代,我亲自试过了,如果繁衍200代,或者2000代,甚至20000代,精度会有一定提高的。
这个代码可以适用于几乎所有一元函数的求最大值和最小值问题,这是将几个关键的地方修改一下就可以,如果是二元函数或者是多元函数的话,则需要改动的大一些,但是大部分代码都是可以直接用的,尤其是遗传过程中的,选择、交叉、变异过程,在这里代码逻辑很精彩。读者可以细细品味。


下面给大家截个最后结果图吧:

有兴趣的找我讨论啊!我们共同进步!


版权声明  
本人声明此帖为本人原创帖,未经允许,不得转载!

有奖推广贴子: 

回复

使用道具 举报

二级士官

Rank: 2

165

主题

264

帖子

438

积分
沙发
发表于 2016-2-29 16:57:47 | 只看该作者
董哥学习MATLAB了啊,这个软件厉害,仿真和矩阵计算都是它:)
回复 支持 反对

使用道具 举报

上尉

Rank: 6Rank: 6

861

主题

1876

帖子

5423

积分
板凳
发表于 2016-2-29 16:58:53 | 只看该作者
:)默默的帮董哥加油,函数我还是懂一点的
回复 支持 反对

使用道具 举报

二级士官

Rank: 2

173

主题

245

帖子

437

积分
地板
 楼主| 发表于 2016-2-29 17:02:12 | 只看该作者
王绍昶 发表于 2016-2-29 16:57
董哥学习MATLAB了啊,这个软件厉害,仿真和矩阵计算都是它

是的,我准备SCI就用MATLAB处理数据。一切都是被逼的。
回复 支持 反对

使用道具 举报

二级士官

Rank: 2

173

主题

245

帖子

437

积分
5#
 楼主| 发表于 2016-2-29 17:02:51 | 只看该作者
大师兄 发表于 2016-2-29 16:58
默默的帮董哥加油,函数我还是懂一点的

谢谢大师兄一路以来的默默支持,希望把这个帖子推广一下,让我的版块人气旺起来,谢谢啦
回复 支持 反对

使用道具 举报

二级士官

Rank: 2

165

主题

264

帖子

438

积分
6#
发表于 2016-2-29 17:20:54 | 只看该作者
董垚 发表于 2016-2-29 17:02
是的,我准备SCI就用MATLAB处理数据。一切都是被逼的。

有压力才有动力,人的潜能的释放需要压力,加油
回复 支持 反对

使用道具 举报

等待验证会员

191

主题

1387

帖子

1704

积分
7#
发表于 2016-2-29 17:27:19 | 只看该作者
看不懂啊:'(
回复 支持 反对

使用道具 举报

二级士官

Rank: 2

173

主题

245

帖子

437

积分
8#
 楼主| 发表于 2016-2-29 18:47:40 | 只看该作者

其实如果能找到看的懂得一帮人来这里,就火了。
回复 支持 反对

使用道具 举报

列兵

Rank: 1

0

主题

3

帖子

18

积分
9#
发表于 2016-2-29 19:02:44 | 只看该作者
注释很清楚明白,程序写的也比较易懂,适合学习!
回复 支持 反对

使用道具 举报

二级士官

Rank: 2

173

主题

245

帖子

437

积分
10#
 楼主| 发表于 2016-3-1 11:02:29 | 只看该作者
ainstudy 发表于 2016-2-29 19:02
注释很清楚明白,程序写的也比较易懂,适合学习!

希望以后多交流啊
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

 
 
QQ:1359218528
工作时间:
9:00-17:00
 
微信公众号
手机APP
机械社区
微信小程序

手机版|UG爱好者论坛 ( 京ICP备10217105号-2 )    论坛管理员QQ:1359218528

本站信息均由会员发表,不代表本网站立场,如侵犯了您的权利请联系管理员,邮箱:1359218528@qq.com  

Powered by UG爱好者 X3.2  © 2001-2014 Comsenz Inc. GMT+8, 2024-12-2 22:43

返回顶部