遗传算法 matlab (二进制)

% 参数初始化  交叉变异选择赋予随机性能够寻解和防止局部最优解   让随机选择让随机数据收敛能够找到最优解  
clear
clc
close all
 
f = @(x) (sin(3*x)+x.*cos(2*x)) ;%函数表达式
ezplot(f, [0, 4*pi])             % 画出函数图像

ger =60; % 迭代次数
pc = 0.9; %交叉概率 增大之后可以扩大随机性
pm = 0.9;% 变异概率 增大之后可以扩大随机性

% 数据编码 此处二进制  不确定是否有误
% 二进制感觉不如十进制,十进制参考连接(https://blog.csdn.net/nightmare_dimple/article/details/74355510)
N = 5;  %种群上限 解的个数   ,这次一维数据解,如果是多维,则应该是多个种群,由于采用的是编码方式,不能够一个种群对应一个多维解
xmax = 4*pi;% 解的取值范围上限
xmin = 0;% 解的取值范围下限
xlim([xmin,xmax])
n = 100;% 精度 
L = length(tentotwo(xmax*n)); % 对解进行编码后的长度,最大值对应的编码
dna = tentotwo(floor((rand(N,1)*(xmax-xmin)+xmin)*n)); % 生成N 个符合要求的解,(没考虑负数,负数会出错,负数只能额外加一列,表示编码的正负号)
x = twototen(dna)/n;
xf = find(x>xmax);
x(xf,:) =[];
dna(xf,:) = [];
% 画图
hold on
plot(x, f(x),'ko','linewidth',1) % 画出初始解的位置,黑圈

%(交叉 ,变异) 排序选择 
dna1 =zeros(size(dna));
dna2 =dna1;
dna3 =dna1;

for j=1:ger
    %交叉 交换编码后的 部分数据
    for i = 1:N
        if rand <pc 
            t2 = randi(N); % 随机一个交叉个体
            t1 = randi(L);% 随机截取一个交叉点 
            dna1(i,t1:end) = dna(t2,t1:end); % 随机个体部分信息交换给当前个体
            dna2(t2,t1:end) = dna(i,t1:end);%当前个体 部分信息  交换给随机个体
        end
    end
    %变异
    dna3 = dna; %对交叉后的新种群进行变异
    for i=1:N
        if rand<pm %变异
            dna3(i,randi(L)) =randi([0,1]);
        end
    end
    [~,dl] = size(dna);

    %下边就是多次变异,增加新解随机性,
    dna3 = dna; %对交叉后的新种群进行变异
    for i=1:N
        if rand<pm %变异
            dna3(i,randi(dl)) =randi([0,1]);
        end
    end
        dna3 = dna; %对交叉后的新种群进行变异
    for i=1:N
        if rand<pm %变异
            dna3(i,randi(dl)) =randi([0,1]);
        end
    end
        dna3 = dna; %对交叉后的新种群进行变异
    for i=1:N
        if rand<pm %变异
            dna3(i,randi(dl)) =randi([0,1]);
        end
    end


    %计算适应度
    dna = [dna;dna1;dna2;dna3];%把所有随机出来的所有解放一起。
    x =  twototen(dna)/n;%转回十进制,用于带入目标函数,计算结果。
    xf = find(x>xmax);%用二进制 编码 随机后会超范围  实数编码不会
    x(xf,:) =[];
    dna(xf,:) = [];
    
    ff = f(x);%计算适应度 
%     ff = mapminmax(ff',0,1)';
    dt = [dna ff];
    [~,Lt] = size(dt);
    dna = flipud(sortrows( [dna ff],Lt));%把解和适应度放一起,按照适应度进行排序
%     sortrows可以按合并后的L+1列进行排序,flipud 可以把矩阵按行进行翻转

% 直接截取 前N个适应度的值
    dna(N+1:end,:)=[];
    dna(:,Lt)=[];
    % 也可采用随机选择的方法 选择前N个适应度的值


    best_x=twototen(dna(1,:))/n;
    best_f=f(best_x);

    hold on
    plot(x, ff,'r.','linewidth',3)           % 画出求解过程中解集的位置,红点
    pause(0.1)
%     h = get(gca,'children');
%     delete(h(1));% 如果注释掉,则显示所有解集的历史轨迹,不在仅表示单次解集轨迹
end
hold on 
plot(x,f(x),'b*','linewidth',1);% 画出最终解集的位置,蓝星
hold on 
plot(best_x,best_f,'g*','linewidth',1);% 画出最优解的位置,绿星
best_x
best_f

% 二进制转十进制 二进制矩阵转十进制
function [b] = twototen(a)
for i=1:size(a,1)
        b(i) = twototen1(a(i,:));
end
b=b';
end
% 二进制转十进制 单个二进制转十进制
function [b] = twototen1(a)
b=0;
for i=1:length(a)
    b = a(i)*2^(length(a)-i)+b;
end
end
% 十进制转二进制 十进制矩阵转二进制
function [temp] = tentotwo(a)
[m,n]=size(a);
mn = m*n;
atemp = reshape(a,1,mn);
temp = zeros(mn,length(tentotwo1(max(atemp))));
for i=1:mn
    tt = tentotwo1(atemp(i));
    temp(i,end-length(tt)+1:end) = tt;
end
end
% 十进制转二进制 单个十进制转二进制
function [b] = tentotwo1(a)
t=1;
while(1)   
    b(t) = mod(a,2);
    a = floor(a/2);
    if a==0 
        break
    end
    t=t+1;
end
b=b(:,end:-1:1);
end

![在这里插入图片描述](https://img-blog.csdnimg.cn/1355b46c96d044afa26a3afcd3e94385.png在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值