正弦余弦演算法(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