和声搜索算法是一种智能优化算法,用于求目标的最值。算法的简介和具体原理见链接如下:
https://blog.youkuaiyun.com/u013236946/article/details/72722455
这里用Matlab简单实现一下经典的和声搜索算法。测试函数是一个曲面,该曲面在变量空间内只有一个极值点也就是在[0,0]处,曲面值最小取0。曲面函数为:,曲面的图像如下:
Matlab代码如下:
clear
clc
%% 设置参数,初始化
N=3; %和声记忆库的大小HMS
dim=2; %乐队的成员数
hmcr=0.95; %从和声库拿出一个和声的概率
par=0.1; %对拿出的和声进行微调的概率
bw=1; %微调的幅度
Tmax=1000; %迭代的最大次数
ub=10; %边界上限
lb=-10; %边界下限
a=[-1,1];
% 设置函数
f=@(x) sum(x.^2);
x=lb+rand(N,dim).*(ub-lb); %初始化和声记忆库
for i = 1:N
fitness_x(i) = f(x(i,:)); %计算记忆库中和声的适应度值
end
[best_fitness,index] = min(fitness_x); % 求出初始状态下的最优适应度;
best_fitness(1)=best_fitness;
best_x(1,:) = x(index,:); % 最优和声;
%% 迭代更新
for i=1:Tmax
for j=1:dim
r1=rand;
if r1<hmcr %从和声记忆库中选取一个和声
x_new(j)=x(floor(rand*(N-1))+1,j);
r2=rand;
if r2<par %对从和声记忆库中选的和声进行微调
x_new(j)=x_new(j)+a(round(rand)+1)*rand*bw;
% 边界判断
ub_flag=x_new(j)>ub;
lb_flag=x_new(j)<lb;
x_new(j)=(x_new(j).*(~(ub_flag+lb_flag)))+ub.*ub_flag+lb.*lb_flag;
end
else %在变量空间内随机生成一个新和声
x_new(j)=lb+rand.*(ub-lb);
end
end
fitness_x_new=f(x_new); %评估新和声的适应度值
[x_worst,I]=max(fitness_x); %找出当前记忆库最差的和声
if fitness_x_new<x_worst %如果新和声的值比记忆库最差的和声要好,更新记忆库
x(I,:)=x_new;
end
for j = 1:N %重新计算记忆库中的和声值
fitness_x(j) = f(x(j,:));
end
[best_fitness(i+1),index]=min(fitness_x); %找出记忆库中最好的和声
best_x(i+1,:)=x(index,:);
end
%% 输出
display(['最优值是:',num2str(best_fitness(end)),'最优和声:',num2str(best_x(end,:))]);
figure(1)
plot(best_fitness);
figure(2)
[X,Y]=meshgrid(-10:0.1:10);
Z=X.^2+Y.^2;
mesh(X,Y,Z);
hold on
scatter(best_x(:,1),best_x(:,2),'filled')
结果如下:
和声搜索算法的参数设置对算法的收敛结果有着巨大的影响,设置一个合理的算法参数值有利于算法向最优解收敛,同时也能加快算法的收敛速度。由于经典的和声搜素算法的参数都是人为设置固定的值,因此后面一些对和声搜索算法的优化则考虑了一些参数可以随迭代进行而自适应的变化。