类似挖宝,一个人去挖宝,挖到了,告诉其他人也来这里挖,并且他们也可以有自己的想法,最终一起合作去挖出最好的宝贝。
(2,3)也可以有自己的想法,比如rand=0.2移动一段距离再继续。
全局的坐标减去当前的坐标,得到的就是要的α(接下来要走的)
有三项,第一项就表示(现在的速度)惯性。Pij表示的就是个体极值,减去xij就代表的是往他个体极值飞的大小与方向。c2也是系数,pgj说明的就是第t代全局的最优位置在哪,整个就是表示他往全局飞的大小和方向。r1,r2为0-1的随机数.w(惯性权重),c1(个体的学习系数),c2(全局学习系数)才为系数。整个合起来就是影响下一代的飞行方向。
然后当前这一代飞向下一代就变成下一代的位置了
不能飞的太快,所以有0.1-2的Vmax
Step1:挑一些点送上去
Step2:就越是下面的注释1,如果想要一个最大化的函数值(maxf),就是反过来的最小化的-f
Step3:
其实就是这里他的大小跟方向
比如迭代20次之后,可能会陷入一个局部极小值
就是先让w大一点,保证独立的飞行状态,往远处飞一点,
缺点就是容易收敛到局部最优,我们可以怎么办呢?比如迭代到了800代,大多数粒子都收敛到了一个地方了,这个时候怎么办呢,可以给他加一个随机的干扰。变一个位置,可能刚好就会跳出这个局部最优。
还可以让我们前期搜索空间大一些,后期再慢慢压缩。
遗传算法有交叉变异,比如一个点有局部最优,可能突然就跳跃到另一个地方了,可能那个点就比哪个局部最优的好了。
模拟退火的思路就是比如上面的C‘点可能不好,但是我可以拿一定的概率接受你,虽然C’不好,但是他的旁边可能就是好的。
所有的思路就是充分的让粒子布满每一个空间去搜一遍,跳出局部最优。
基于该逻辑有最大的可能性找到最优解,或是能最接近最优解,或是能最快找到相对最优解
这里其实先介绍一下背景更好,主要是有这么几个要素
1.最优解没办法直接解出来,只能通过尝试法去碰运气
2.当前计算机的算力,没办法做到把所有可能情况全部遍历一遍,只能遍历部分
代码来自哔哩哔哩——青青草原灰太郎
(matlab)
%% 初始化种群
clear
%% Sphere
clear
f= @(x) x .* sin(x) .* cos(2 * x) - 2 * x .* sin(3 * x) +3 * x .* sin(4 * x); % 函数表达式 % 求这个函数的最大值
N = 20; % 初始种群个数
d = 1; % 可行解维数
ger = 100; % 最大迭代次数
limit = [0, 50]; % 设置位置参数限制
vlimit = [-10, 10]; % 设置速度限制
w = 0.8; % 惯性权重
c1 = 0.5; % 自我学习因子
c2 = 0.5; % 群体学习因子
figure(1);ezplot(f,[0,0.01,limit(2)]); %曲线
x = limit(1) + ( limit( 2 ) - limit( 1) ) .* rand(N, d);%初始种群的位置
v = rand(N, d); % 初始种群的速度
xm = x; % 每个个体的历史最佳位置
ym = zeros(1, d); % 种群的历史最佳位置
fxm = ones(N, 1)*inf; % 每个个体的历史最佳适应度
fym = inf; % 种群历史最佳适应度
hold on
plot(xm, f(xm), 'ro');title('初始状态图');
figure(2)
%% 群体更新
iter = 1;
% record = zeros(ger, 1); % 记录器
while iter <= ger
fx = f(x) ; % 个体当前适应度
for i = 1:N
if fx(i) <fxm(i)
fxm(i) = fx(i); % 更新个体历史最佳适应度
xm(i,:) = x(i,:); % 更新个体历史最佳位置(取值)
end
end
if min(fxm) < fym
[fym, nmin] = min(fxm); % 更新群体历史最佳适应度
ym = xm(nmin, :); % 更新群体历史最佳位置
end
v = v * w + c1 * rand * (xm - x) + c2 * rand * (repmat(ym, N, 1) - x);% 速度更新
% 边界速度处理
v(v > vlimit(2)) = vlimit(2);
v(v < vlimit(1)) = vlimit(1);
x = x + v;% 位置更新
% 边界位置处理
x(x > limit(2)) = limit(2);
x(x < limit(1)) = limit(1);
record(iter) = fym;%最大值记录
x0 = 0 : 0.01 : limit(2);
subplot(1,2,1)
plot(x0, f(x0), 'b-', x, f(x), 'ro');title('状态位置变化')
subplot(1,2,2);plot(record);title('最优适应度进化过程')
pause(0.01)
iter = iter+1;
end
x0 = 0 : 0.01 : limit(2);
figure(4);plot(x0, f(x0), 'b-', x, f(x), 'ro');title('最终状态位置')
disp(['最大值:',num2str(fym)]);
disp(['变量取值:',num2str(ym)]);
N就是多少个粒子去同时去搜
d=1,这里可以不这么去写,可以改一下,然后下面就都改了
ger=100,就是我们要搜寻100次
limit = [0, 50]把空间设置为0-50
vlimit = [-10, 10]速度就是一次他能飞多少,一次能飞10个单位
w = 0.8;
c1 = 0.5;
c2 = 0.5;
这几个都可以自己改
x = limit(1) + ( limit( 2 ) - limit( 1) ) .* rand(N, d);%初始种群的位置
rand(N, d):根据上面的参数就是生成20行1列,就是有20个元素
xm = x; 记录每个个体的历史最佳位置
ym = zeros(1, d); 记录种群的历史最佳位置
fxm = ones(N, 1)*inf; 记录每个个体的历史最佳适应度
fym = inf; 记录种群历史最佳适应度
下面是对我们函数进行循环
%% 群体更新
iter = 1;
% record = zeros(ger, 1); % 记录器
while iter <= ger
fx = f(x) ; % 个体当前适应度 其实就是函数值
for i = 1:N 判断当前位置最好的一个适应度
if fx(i) <fxm(i)
fxm(i) = fx(i); % 更新个体历史最佳适应度
xm(i,:) = x(i,:); % 更新个体历史最佳位置(取值)
end
end
if min(fxm) < fym 再看看第一代比之前的50个粒子,这50个里面最好的那一个比上一次50个最好的那一个好不好,好的话就更新
[fym, nmin] = min(fxm); % 更新群体历史最佳适应度
ym = xm(nmin, :); % 更新群体历史最佳位置
end
v = v * w + c1 * rand * (xm - x) + c2 * rand * (repmat(ym, N, 1) - x);% 速度更新
% 边界速度处理
v(v > vlimit(2)) = vlimit(2);
v(v < vlimit(1)) = vlimit(1);
x = x + v;% 位置更新
% 边界位置处理
x(x > limit(2)) = limit(2);
x(x < limit(1)) = limit(1);
record(iter) = fym;%最大值记录