正弦余弦算法(SCA)是一种基于正弦和余弦函数的群体优化算法。 发表于中国科学院一区顶级期刊《知识系统》。 SCA是一种新颖的随机优化算法,该算法最显著的特点是它以简洁明了的形式完成了智能优化算法的必要要素,仅以正弦和余弦函数的波动性和周期性为设计目标,实现算子搜索和迭代最优解。 与遗传算法、粒子群优化算法等众多智能优化算法相比,正弦余弦算法具有参数少、结构简单、实现方便、收敛速度快等优点,在实际应用中具有更好的性能。
正弦余弦算法(SCA)总结和吸收了一些群智能优化算法的迭代策略,将包含特定数量随机解的集合作为算法的初始解集,通过目标函数反复评估解的适应度,并根据具体的更新策略随机迭代解集, 最后得到最优解或满足适应度要求的满意解。与大多数群体智能优化算法一样,SCA依靠迭代策略来实现解空间的随机搜索,这并不能保证一次操作就能找到最优解,但是当初始解集大小和迭代次数足够大时,找到最优解的概率大大提高。
SCA拥有独特的数学模型和极具竞争力的结果,对许多问题具有快速收敛性,尤其是对于真实世界的案例,已被广泛使用,并被引用2300+次。
SCA 将迭代策略分为两条主线:全局搜索和本地开发。 在全局搜索线程中,将较大的随机波动应用于当前解决方案集中的解决方案,以搜索解决方案空间中的未知区域。 在局部开发线程中,对解集施加弱随机扰动,以完全搜索当前解的邻域。
SCA利用正弦和余弦函数的周期性波动性构造了一个实现全局搜索和局部发展功能的迭代方程,并使用简洁的更新迭代方程来应用扰动和更新解集,具体迭代方程分为以下两种:正弦迭代或余弦迭代方程:
式中表示当前迭代次数,表示迭代时单个 i 在 j 维中的位置分量,R1、R2、R3 为随机参数,R1 由更新函数确定,R2 u [ 0 , 2 R3 0 ,表示第一次迭代中 j 维中候选解集的最优候选解的分量。
为了消除迭代步长与方向之间的相关性,将上述两个迭代方程通过紧接参数 r4 u [ 0 , 1 ] 组合成完整的迭代方程。
R1 控制算法从全局搜索到本地开发的转换。 当 r1 的值较大时,算法倾向于全局搜索; 当 r1 的值较小时,算法偏向于局部开发。
R2 描述了当前解在更新时向当前最优解移动的方向,以及可以达到的迭代步长的极值,这会影响更新后的解是在当前解和最优解之间的解空间内还是在空间之外。
R3 给出了最优解的随机权重,即在定义候选解行进的距离时,随机强调 ( R3 1 或忽略 ( R3 1 ) 最优解的影响。
R4 描述了正弦和余弦更新之间的随机性,并打算消除迭代步长和方向之间可能的相关性。
以二维随机变量为例:
当 r1sin( r2 ) 或 r1cos( r2 ) 的值介于 -1 和 1 之间时,迭代应用局部开发策略,算法搜索候选解与当前最优解之间的解空间,即候选解的某个邻域。 如果 r1sin( r2 ) 或 r1cos( r2 ) 的值> 1 或 < 1,则应用全局开发策略。 这就是 SCA 如何实现解决方案空间的全局搜索和本地开发。
考虑到全局搜索和局部开发两个过程之间的平衡,以及算法收敛到全局最优解的必要性,r1:1=随着迭代的进行自适应调整
a 是一个常量; t 是当前的迭代次数; t 是最大迭代次数; 由于 r1 的值随着迭代次数的增加而逐渐减小,因此算法在局部和全局发展的能力是平衡的。 当 a = 2 设置时,如下图所示,r1sin(r 2) 和 r1cos(r 2)(正弦和余弦参数部分)的波动幅度随着迭代次数的增加而逐渐衰减,其值在 ( 1 , 2 ] 和 [ 2 , 1 ) 的范围内,算法进行全局搜索并在 [ 1 , 1 , 之间局部发展 1 ] .
初始化迭代次数t = 0,初始候选解集m,候选解的随机位置,以及迭代更新方程的r1、r2等参数;
计算每个候选解的拟合度,确定并保留当前最优候选解 p(t)。 根据迭代方程更新候选解集;
根据公式和参数的概率分布规律,迭代更新方程的r1、r2等参数。
终止检查。 判断是否满足终止条件,如果满足迭代次数或求解条件,则输出p(t); 如果没有,请返回步骤 2。
SCA的性能在三个测试阶段进行基准测试。 首先,利用单峰函数、多模态函数和组合函数等一组众所周知的测试用例来测试SCA的探索、利用、局部最优规避和收敛性; 其次,使用多个性能指标(搜索历史、轨迹、求解的平均拟合度、优化过程中的最佳求解)定性观察和确认SCA在移位二维测试函数上的性能;
sine cosine algorithm (sca)
source codes demo version 1.0
developed in matlab r2011b(7.13)
author and programmer: seyedali mirjalili
e-mail: [email protected]
homepage:
main **
s. mirjalili, sca: a sine cosine algorithm for solving optimization problems
knowledge-based systems, doi:
you can simply define your cost function in a seperate file and load its handle to fobj
the initial parameters that you need are:
fobj = @yourcostfunction
dim = number of your variables
max_iteration = maximum number of iterations
searchagents_no = number of search agents
lb=[lb1,lb2,..lbn] where lbn is the lower bound of variable n
ub=[ub1,ub2,..ubn] where ubn is the upper bound of variable n
if all the variables h**e equal lower bound you can just
define lb and ub as two single numbers
to run sca: [best_score,best_pos,cg_curve]=sca(searchagents_no,max_iteration,lb,ub,dim,fobj)
function [destination_fitness,destination_position,convergence_curve]=sca(n,max_iteration,lb,ub,dim,fobj)
display('sca is optimizing your problem');
initialize the set of random solutions
x=initialization(n,dim,ub,lb);
destination_position=zeros(1,dim);
destination_fitness=inf;
convergence_curve=zeros(1,max_iteration);
objective_values = zeros(1,size(x,1));
calculate the fitness of the first set and find the best one
for i=1:size(x,1)
objective_values(1,i)=fobj(x(i,:)
if i==1
destination_position=x(i,:)
destination_fitness=objective_values(1,i);
elseif objective_values(1,i)destination_position=x(i,:)
destination_fitness=objective_values(1,i);
endall_objective_values(1,i)=objective_values(1,i);
endmain loop
t=2; %start from the second iteration since the first iteration was dedicated to calculating the fitness
while t<=max_iteration
eq. (3.4)
a = 2;
max_iteration = max_iteration;
r1=a-t*((a)/max_iteration); r1 decreases linearly from a to 0
update the position of solutions with respect to destination
for i=1:size(x,1) %in i-th solution
for j=1:size(x,2) %in j-th dimension
update r2, r3, and r4 for eq. (3.3)
r2=(2*pi)*rand();
r3=2*rand;
r4=rand();
eq. (3.3)
if r4<0.5
eq. (3.1)
x(i,j)= x(i,j)+(r1*sin(r2)*abs(r3*destination_position(j)-x(i,j)))
else eq. (3.2)
x(i,j)= x(i,j)+(r1*cos(r2)*abs(r3*destination_position(j)-x(i,j)))
endend
endfor i=1:size(x,1)
check if solutions go outside the search spaceand bring them back
flag4ub=x(i,:)ub;
flag4lb=x(i,:)x(i,:)=(x(i,:)flag4ub+flag4lb)))ub.*flag4ub+lb.*flag4lb;
calculate the objective values
objective_values(1,i)=fobj(x(i,:)
update the destination if there is a better solution
if objective_values(1,i)destination_position=x(i,:)
destination_fitness=objective_values(1,i);
endend
convergence_curve(t)=destination_fitness;
display the iteration and best optimum obtained so far
if mod(t,50)==0
display(['at iteration ', num2str(t), ' the optimum is ', num2str(destination_fitness)])
end increase the iteration counter
t=t+1;
end