% 参数初始化 交叉变异选择赋予随机性能够寻解和防止局部最优解 让随机选择让随机数据收敛能够找到最优解
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