和声搜索算法
前言
最近需要使用智能算法求解组合优化问题,希望也尝试一下和声搜索算法,然在网上只找到了主要是介绍原理的论文和博文,源码甚少,只得自己照着书上的原理摸索着敲了敲,感觉效果不错,如有错误恳请大佬指正,如有帮到一些朋友望不吝点个赞再走,谢谢。
原理
和声搜索算法模拟音乐演奏寻找一个极好的和声过程,类同于优化算法寻找目标函数值的最优状态。
在和声搜索算法中,一个解对应一个和声,和声的分量对应一个乐器的音调,即一个和声由若干个音调组成。
和声搜索算法首先初始化生成和声记忆库;其次基于某种策略产生一个新和声;再次计算新和声的适应度,并基于更新策略更新和声记忆库;最后迭代这个过程,直到产生一个满足条件的和声为止。
测试例子
求 f
(
x
)
=
(
x
1
−
2
)
2
+
(
x
2
−
3
)
4
+
(
x
3
−
1
)
2
+
3
f(x) = (x_1-2)^2+(x_2-3)^4+(x_3-1)^2+3f(x)=(x1−2)2+(x2−3)4+(x3−1)2+3 的最小值,理论上 f
(
x
)
f(x)f(x)的最小值为3。
下面通过使用matlab编写和声搜索算法来求解此问题。
主程序
%%%实值和声搜索算法求函数极值%%%
% 初始化
clear all; %清除所有变量
close all; %清图
clc; %清屏
HMS=3; %和声库的大小
HMCR=0.95; %记忆库取值概率
PAR=0.1; %微调概率
bw=1; %音调微调带宽
Tmax=200; %创作的次数
M=3; %乐器(变量)个数
Mmin=[-5 -5 -5]; %乐器的音调下限
Mmax=[5 5 5]; %乐器的音调上限
% 和声记忆库初始化
X=zeros(HMS,M);
% 随机产生和声记忆库
for i=1:HMS
for j=1:M
X(i,j)=rand()*(Mmax(j)-Mmin(j))+Mmin(j);
end
end
% 初始化新的乐器组合
xnew=zeros(1,M);
% 初始化最优解为第一个乐器组合
yBest=func(X(1,:));
xBest=X(1,:);
% 迭代周期为Tmax
for iter=1:Tmax
iter;
% 以概率HMCR在和声库中随机选取
if rand()
xnew=X(round(rand()*(HMS-1))+1,:);
% 以概率1-HMCR在乐器音调范围内随机产生
else
for j=1:M
xnew(j)=rand()*(Mmax(j)-Mmin(j))+Mmin(j);
end
end
% 以概率PAR进行扰动
if rand()
for j=1:M
xnew(j)=xnew(j)+2*bw*rand()-bw;
end
end
% 计算新乐器组合的和声为ynew
ynew=func(xnew);
% 更新和声库,判断新解是否比和声库中最差的解更好,是则替换
for j=1:HMS
if ynew
X(j,:)=xnew;
break;
end
% 记录最美的和声
if yBest>func(X(j,:))
yBest=func(X(j,:));
xBest=X(j,:);
end
end
% 记录每个周期的最美和声
trace(iter)=yBest;
tracef(iter,:)=xBest;
end
% 绘制结果
xBest %最好和声组合
trace(end) %最好和声
figure
plot(trace)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')
目标函数
%适应度函数:和声效果%
function result = func(x)
result = (x(1)-2).^2+(x(2)-3).^4+(x(3)-1).^2+3;
测试结果图
由上图可以看出,和声搜索算法能够较快收敛到最优解3附近,效果不错。
参考文献
[1] 智能优化算法与涌现计算/李士勇,李研,林永茂编著.—北京:清华大学出版社,2019.