【優化求解】基於matlab禁忌搜索算法求解函數極值問題【含Matlab源碼 1204期】

1、禁忌搜索算法簡介

1 引言
一個問題的求解過程就是搜索,它是人工智能的一個基本問題,而人工智能在各應用領域中被普遍地使用。如今搜索技術***在各類人工智能系統中,能夠說沒有哪種人工智能的應用不用搜索方法。
禁忌搜索算法(Tabu Search or Taboo Search, TS) 的思想最先由美國工程院院士Glover教授於1986年提出[] , 並在1989年和1990年對該方法作出了進一步的定義和發展[2-4]。在天然計算的研究領域
中,禁忌搜索算法以其靈活的存儲結構和相應的禁忌準則來避免迂迴搜索,在智能算法中獨樹一幟,成爲一個研究熱點,受到了國內外學者的普遍關注。迄今爲止,禁忌搜索算法在組合優化、生產調度、機器學習、電路設計和神經網絡等領域取得了很大的成功,近年來又在函數全局優化方面獲得較多的研究,並有迅速發展的趨勢[5-8].
所謂禁忌,就是禁止重複前面的操做。爲了改進局部鄰域搜索容易陷入局部最優勢的不足,禁忌搜索算法引入一個禁忌表,記錄下已經搜索過的局部最優勢,在下一次搜索中,對禁忌表中的信息再也不搜索或有選擇地搜索,以此來跳出局部最優勢,從而最終實現全局優化。禁忌搜索算法是對局部鄰域搜索的一種擴展,是一種全局鄰域搜索、逐步尋優的算法。
禁忌搜索算法是一種迭代搜索算法,它區別於其餘現代啓發式算法的顯著特色,是利用記憶來引導算法的搜索過程;它是對人類智力過程的一種模擬,是人工智能的一種體現。禁忌搜索算法涉及鄰域、
禁忌表、禁忌長度、候選解、藐視準則等概念,在鄰域搜索的基礎上,經過禁忌準則來避免重複搜索,並經過藐視準則來赦免一些被禁忌的優良狀態,進而保證多樣化的有效搜索來最終實現全局優化。算法

2禁忌搜索算法理論
2.1局部鄰域搜索
局部鄰域搜索是基於貪婪準則持續地在當前的鄰域中進行搜索,雖然其算法通用,易於實現,且容易理解,但其搜索性能徹底依賴於鄰域結構和初始解,尤爲容易陷入局部極小值而沒法保證全局優化。
局部搜索的算法能夠描述爲:
在這裏插入圖片描述
在這裏插入圖片描述
這種鄰域搜索方法易於理解,易於實現,並且具備很好的通用性,可是搜索結果的好壞徹底依賴於初始解和鄰域的結構。若鄰域結構設置不當,或初始解選擇不合適,則搜索結果會不好,可能只會搜
索到局部最優解,即算法在搜索過程當中容易陷入局部極小值。所以,若不在搜索策略上進行改進,要實現全局優化,局部鄰域搜索算法採用的鄰域函數就必須是「徹底」的,即鄰域函數將致使解的徹底枚
舉。而這在大多數狀況下是沒法實現的,並且窮舉的方法對於大規模問題在搜索時間上也是不容許的。爲了實現全局搜索,禁忌搜索採用容許接受劣質解的策略來避免局部最優解。
2.2禁忌搜索
禁忌搜索算法是模擬人的思惟的一種智能搜索算法,即人們對已搜索的地方不會再當即去搜索,而是去對其餘地方進行搜索,若沒有找到,可再搜索已去過的地方。禁忌搜索算法從一個初始可行解出
發,選擇一系列的特定搜索方向(或稱爲「移動」)做爲試探,選擇使目標函數值減少最多的移動。爲了不陷入局部最優解,禁忌搜索中採用了一種靈活的「記憶」技術,即對已經進行的優化過程進行記錄,指導下一步的搜索方向,這就是禁忌表的創建。禁忌表中保存了最近若干次迭代過程當中所實現的移動,凡是處於禁忌表中的移動,在當前迭代過程當中是禁忌進行的,這樣能夠避免算法從新訪問在最近若
幹次迭代過程當中已經訪問過的解,從而防止了循環,幫助算法擺脫局部最優解。另外,爲了儘量不錯過產生最優解的「移動」,禁忌搜索還採用「特赦準則」的策略。
對一個初始解,在一種鄰域範圍內對其進行一系列變化,從而獲得許多候選解。從這些候選解中選出最優候選解,將候選解對應的目標值與「best so far」狀態進行比較。若其目標值優於「best sofar」狀態, 就將該候選解解禁, 用來替代當前最優解及其「best sofar」狀態, 而後將其加入禁忌表, 再將禁忌表中相應對象的禁忌長度改變:若是全部的候選解中所對應的目標值都不存在優於「best sofar」狀態, 就從這些候選解中選出不屬於禁忌對象的最佳狀態, 並將其做爲新的當前解,不用與當前最優解進行比較,直接將其所對應的對象做爲禁忌對象,並將禁忌表中相應對象的禁忌長度進行修改。
2.3禁忌搜索算法的特色
禁忌搜索算法是在鄰域搜索的基礎上,經過設置禁忌表來禁忌一些已經進行過的操做,並利用藐視準則來獎勵一些優良狀態,其中鄰域結構、候選解、禁忌長度、禁忌對象、藐視準則、終止準則等是影
響禁忌搜索算法性能的關鍵。鄰域函數沿用局部鄰域搜索的思想,用於實現鄰域搜索;禁忌表和禁忌對象的設置,體現了算法避免迂迴搜索的特色:藐視準則,則是對優良狀態的獎勵,它是對禁忌策略的一種放鬆。
與傳統的優化算法相比,禁忌搜索算法的主要特色是:
(1)禁忌搜索算法的新解不是在當前解的鄰域中隨機產生,它要麼是優於「best so far」的解, 要麼是非禁忌的最佳解, 所以選取優良解的機率遠遠大於其餘劣質解的機率。
(2)因爲禁忌搜索算法具備靈活的記憶功能和藐視準則,而且在搜索過程當中能夠接受劣質解,因此具備較強的「登山」能力,搜索時可以跳出局部最優解,轉向解空間的其餘區域,從而增大得到更好的全局最優解的機率。所以,禁忌搜索算法是一種局部搜索能力很強的全局迭代尋優算法。markdown

2.4禁忌搜索算法的改進方向
禁忌搜索是著名的啓發式搜索算法,可是禁忌搜索也有明顯的不足,即在如下方面須要改進:
(1)對初始解有較強的依賴性,好的初始解可以使禁忌搜索算法在解空間中搜索到好的解,而較差的初始解則會下降禁忌搜索的收斂速度。所以能夠與遺傳算法、模擬退火算法等優化算法結合,先產生較好的初始解,再用禁忌搜索算法進行搜索優化。
(2)迭代搜索過程是串行的,僅是單一狀態的移動,而非並行搜索。爲了進一步改善禁忌搜索的性能,一方面能夠對禁忌搜索算法自己的操做和參數選取進行改進,對算法的初始化、參數設置等方面實
施並行策略,獲得各類不一樣類型的並行禁忌搜索算法[9]:另外一方面則能夠與遺傳算法、神經網絡算法以及基於問題信息的局部搜索相結合。
(3)在集中性與多樣性搜索並重的狀況下,多樣性不足。集中性搜索策略用於增強對當前搜索的優良解的鄰域作進一步更爲充分的搜索,以期找到全局最優解。多樣性搜索策略則用於拓寬搜索區域,尤
其是未知區域,當搜索陷入局部最優時,多樣性搜索可改變搜索方向,跳出局部最優,從而實現全局最優。增長多樣性策略的簡單處理手段是對算法的從新隨機初始化,或者根據頻率信息對一些已知對象進行懲罰。網絡

3 禁忌搜索算法流程
簡單禁忌搜索算法的基本思想是:給定一個當前解(初始解)和一種鄰域,而後在當前解的鄰域中肯定若干候選解;若最佳候選解對應的目標值優於「best so far」狀態, 則忽視其禁忌特性, 用它替代當前解和「best so far」狀態, 並將相應的對象加入禁忌表, 同時修改禁忌表中各對象的任期:若不存在上述候選解,則在候選解中選擇非禁忌的最佳狀態爲新的當前解,而無視它與當前解的優劣,同時將相應的對象加入禁忌表,並修改禁忌表中各對象的任期。如此重複上述迭代搜索過程,直至知足中止準則。其算法步驟可描述以下:
(1)給定禁忌搜索算法參數,隨機產生初始解x,置禁忌表爲空。
(2)判斷算法終止條件是否知足:如果,則結束算法並輸出優化結果:不然,繼續如下步驟。
(3)利用當前解的鄰域函數產生其全部(或若干)鄰域解,並從中肯定若干候選解。
(4)對候選解判斷藐視準則是否知足:若知足,則用知足藐視準則的最佳狀態y替代x成爲新的當前解,即x=y,並用與y對應的禁忌對象替換最先進入禁忌表的禁忌對象, 同時用y替換「best so far」狀態,而後轉步驟(6):不然,繼續如下步驟。
(5)判斷候選解對應的各對象的禁忌屬性,選擇候選解集中非禁忌對象對應的最佳狀態爲新的當前解,同時用與之對應的禁忌對象替換最先進入禁忌表的禁忌對象。
(6)判斷算法終止條件是否知足:如果,則結束算法並輸出優化結果:不然,轉步驟(3)。
禁忌搜索算法的運算流程如圖8.1所示。
在這裏插入圖片描述
4 關鍵參數說明
通常而言,要設計一個禁忌搜索算法,須要肯定算法的如下環節:初始解、適配值函數、鄰域結構、禁忌對象、候選解選擇、禁忌表、禁忌長度、藐視準則、搜索策略、終止準則[10,11]。面對如此衆
多的參數,針對不一樣鄰域的具體問題,很難有一套比較完善的或很是嚴格的步驟來肯定這些參數。
初始解
禁忌搜索算法能夠隨機給出初始解,也能夠事先使用其餘啓發式算法等給出一個較好的初始解。因爲禁忌搜索算法主要是基於鄰域搜索的,初始解的好壞對搜索的性能影響很大。尤爲是一些帶有很複雜
約束的優化問題,若是隨機給出的初始解不好,甚至經過多步搜索也很難找到一個可行解,這時應該針對特定的複雜約束,採用啓發式方法或其餘方法找出一個可行解做爲初始解;再用禁忌搜索算法求解,以提升搜索的質量和效率。也能夠採用必定的策略來下降禁忌搜索對初始解的敏感性。
適配值函數
禁忌搜索的適配值函數用於對搜索進行評價,進而結合禁忌準則和特赦準則來選取新的當前狀態。目標函數值和它的任何變形均可以做爲適配值函數。若目標函數的計算比較困難或耗時較長,此時可採
用反映問題目標的某些特徵值來做爲適配值,進而改善算法的時間性能。選取何種特徵值要視具體問題而定,但必須保證特徵值的最佳性與目標函數的最優性一致。適配值函數的選擇主要考慮提升算法的效率、便於搜索的進行等因素。
鄰域結構
所謂鄰域結構,是指從一個解(當前解)經過「移動」產生另外一個解(新解)的途徑,它是保證搜索產生優良解和影響算法搜索速度的重要因素之一。鄰域結構的設計一般與問題相關。鄰域結構的設計方法不少,對不一樣的問題應採用不一樣的設計方法,經常使用設計方法包括互換、插值、逆序等。不一樣的「移動」方式將致使鄰域解個數及其變化狀況的不一樣,對搜索質量和效率有必定影響。數據結構

經過移動,目標函數值將產生變化,移動先後的目標函數值之差,稱之爲移動值。若是移動值是非負的,則稱此移動爲改進移動:不然,稱之爲非改進移動。最好的移動不必定是改進移動,也多是
非改進移動,這一點能保證在搜索陷入局部最優時,禁忌搜索算法能自動把它跳出局部最優。機器學習

禁忌對象
所謂禁忌對象,就是被置入禁忌表中的那些變化元素。禁忌的目的則是爲了儘可能避免迂迴搜索而多搜索一些解空間中的其餘地方。概括而言,禁忌對象一般可選取狀態自己或狀態份量等。ide

候選解選擇
候選解一般在當前狀態的鄰域中擇優選取,若選取過多將形成較大的計算量,而選取較少則容易「早熟」收斂,但要作到整個鄰域的擇優每每須要大量的計算,所以能夠肯定性地或隨機性地在部分鄰域中選取候選解,具體數據大小則可視問題特徵和對算法的要求而定。
禁忌表
不容許恢復(即被禁止) 的性質稱做禁忌(Tabu) 。禁忌表的主要目的是阻止搜索過程當中出現循環和避免陷入局部最優,它一般記錄前若干次的移動,禁止這些移動在近期內返回。在迭代固定次數後,
禁忌表釋放這些移動,從新參加運算,所以它是一個循環表,每迭代一次,就將最近的一次移動放在禁忌表的末端,而它的最先的一個移動就從禁忌表中釋放出來。
從數據結構上講,禁忌表是具備必定長度的先進先出的隊列。禁忌搜索算法使用禁忌表禁止搜索曾經訪問過的解,從而禁止搜索中的局部循環。禁忌表可使用兩種記憶方式:明晰記憶和屬性記憶。明
晰記憶是指禁忌表中的元素是一個完整的解,消耗較多的內存和時間:屬性記憶是指禁忌表中的元素記錄當前解移動的信息,如當前解移動的方向等。函數

禁忌長度
所謂禁忌長度,是指禁忌對象在不考慮特赦準則的狀況下不容許被選取的最大次數。通俗地講,禁忌長度可視爲禁忌對象在禁忌表中的任期。禁忌對象只有當其任期爲0時才能被解禁。在算法的設計和構
造過程當中,通常要求計算量和存儲量儘可能小,這就要求禁忌長度儘可能小。可是,禁忌長度太小將形成搜索的循環。禁忌長度的選取與問題特徵相關,它在很大程度上決定了算法的計算複雜性。
一方面,禁忌長度能夠是一個固定常數(如t=c,c爲一常數),或者固定爲與問題規模相關的一個量(如t=√n,n爲問題維數或規模),如此實現起來方便、簡單,也頗有效:另外一方面,禁忌長度也能夠是動態變化的,如根據搜索性能和問題特徵設定禁忌長度的變化區間,而禁忌長度則可按某種規則或公式在這個區間內變化。性能

藐視準則
在禁忌搜索算法中,可能會出現候選解所有被禁忌,或者存在一個優於「best so far」狀態的禁忌候選解, 此時特赦準則將某些狀態解禁,以實現更高效的優化性能。特赦準則的經常使用方式有:
(1) 基於適配值的原則:某個禁忌候選解的適配值優於「bestso far」狀態, 則解禁此候選解爲當前狀態和新的「best so far」狀態。
(2)基於搜索方向的準則:若禁忌對象上次被禁忌時使得適配值有所改善,而且目前該禁忌對象對應的候選解的適配值優於當前解,則對該禁忌對象解禁。學習

搜索策略
搜索策略分爲集中性搜索策略和多樣性搜索策略。集中性搜索策略用於增強對優良解的鄰域的進一步搜索。其簡單的處理手段能夠是在必定步數的迭代後基於最佳狀態從新進行初始化,並對其鄰域進行再次搜索。在大多數狀況下,從新初始化後的鄰域空間與上一次的鄰域空間是不同的,固然也就有一部分鄰域空間多是重疊的。多樣性搜索策略則用於拓寬搜索區域,尤爲是未知區域。其簡單的處理手段能夠是對算法的從新隨機初始化,或者根據頻率信息對一些已知對象進行懲罰。優化

終止準則
禁忌搜索算法須要一個終止準則來結束算法的搜索進程,而嚴格理論意義上的收斂條件,即在禁忌長度充分大的條件下實現狀態空間的遍歷,這顯然是不可能實現的。所以,在實際設計算法時一般採用
近似的收斂準則。經常使用的方法有:
(1)給定最大迭代步數。當禁忌搜索算法運行到指定的迭代步數以後,則終止搜索。
(2)設定某個對象的最大禁忌頻率。若某個狀態、適配值或對換等對象的禁忌頻率超過某一閾值,或最佳適配值連續若干步保持不變,則終止算法。
(3)設定適配值的偏離閾值。首先估計問題的下界,一旦算法中最佳適配值與下界的偏離值小於某規定閾值,則終止搜索。

2、案例及完整源代碼

1 案例
在這裏插入圖片描述

2 完整代碼

%%%%%%%%%%%%%%%%禁忌搜索算法求函數極值問題%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%初始化%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear all;                        %清除全部變量
close all;                        %清圖
clc;                              %清屏
xu=5;                             %上界
xl=-5;                            %下界
L=randi([5 11],1,1);            %禁忌長度取5,11之間的隨機數
Ca=5;                             %鄰域解個數
Gmax=200;                         %禁忌算法的最大迭代次數;
w=1;                              %自適應權重係數
tabu=[];                          %禁忌表
x0=rand(1,2)*(xu-xl)+xl;          %隨機產生初始解
bestsofar.key=x0;                 %最優解
xnow(1).key=x0;                   %當前解
%%%%%%%%%%%%%%%%最優解函數值,當前解函數值%%%%%%%%%%%%%%%%%
bestsofar.value=func2(bestsofar.key);  
xnow(1).value=func2(xnow(1).key);
g=1;
while g<Gmax
    x_near=[];                     %鄰域解
    w=w*0.998;
    for i=1:Ca
        %%%%%%%%%%%%%%%%%%%%%產生鄰域解%%%%%%%%%%%%%%%%%%%%
        x_temp=xnow(g).key;
        x1=x_temp(1);
        x2=x_temp(2);
        x_near(i,1)=x1+(2*rand-1)*w*(xu-xl);
           %%%%%%%%%%%%%%%%%邊界條件處理%%%%%%%%%%%%%%%%%%%
           %%%%%%%%%%%%%%%%%%%邊界吸取%%%%%%%%%%%%%%%%%%%%%
        if x_near(i,1)<xl
            x_near(i,1)=xl;
        end
        if x_near(i,1)>xu
            x_near(i,1)=xu;
        end
        x_near(i,2)=x2+(2*rand-1)*w*(xu-xl);
           %%%%%%%%%%%%%%%%%邊界條件處理%%%%%%%%%%%%%%%%%%%
           %%%%%%%%%%%%%%%%%%%邊界吸取%%%%%%%%%%%%%%%%%%%%%
        if x_near(i,2)<xl
            x_near(i,2)=xl;
        end
        if x_near(i,2)>xu
            x_near(i,2)=xu;
        end
        %%%%%%%%%%%%%%計算鄰域解點的函數值%%%%%%%%%%%%%%%%%%%
        fitvalue_near(i)=func2(x_near(i,:)); 
    end
    %%%%%%%%%%%%%%%%%%%%最優鄰域解爲候選解%%%%%%%%%%%%%%%%%%%
    temp=find(fitvalue_near==max(fitvalue_near));
    candidate(g).key=x_near(temp,:);
    candidate(g).value=func2(candidate(g).key);
    %%%%%%%%%%%%%%候選解和當前解的評價函數差%%%%%%%%%%%%%%%%%%
    delta1=candidate(g).value-xnow(g).value; 
    %%%%%%%%%%%%%%候選解和目前最優解的評價函數差%%%%%%%%%%%%%%%
    delta2=candidate(g).value-bestsofar.value;    
    %%%%%候選解並無改進解,把候選解賦給下一次迭代的當前解%%%%%%
    if delta1<=0   
        xnow(g+1).key=candidate(g).key;
        xnow(g+1).value=func2(xnow(g).key);
        %%%%%%%%%%%%%%%%%%%%%更新禁忌表%%%%%%%%%%%%%%%%%%%%%%%
        tabu=[tabu;xnow(g+1).key];
        if size(tabu,1)>L  
            tabu(1,:)=[];
        end
        g=g+1;                 %更新禁忌表後,迭代次數自增1
    %%%%%%%若是相對於當前解有改進,則應與目前最優解比較%%%%%%%%%%
    else
        if delta2>0            %候選解比目前最優解優
            %%%%%%%%%%把改進解賦給下一次迭代的當前解%%%%%%%%%%%%
            xnow(g+1).key=candidate(g).key;
            xnow(g+1).value=func2(xnow(g+1).key);
            %%%%%%%%%%%%%%%%%%%%更新禁忌表%%%%%%%%%%%%%%%%%%%%%
            tabu=[tabu;xnow(g+1).key];
            if size(tabu,1)>L 
                tabu(1,:)=[];
            end 
            %%%%%%%%把改進解賦給下一次迭代的目前最優解%%%%%%%%%%%%
            %%%%%%%%%%%%%%%%%包含藐視準則%%%%%%%%%%%%%%%%%%%%%%%
            bestsofar.key=candidate(g).key;
            bestsofar.value=func2(bestsofar.key);
            g=g+1;                %更新禁忌表後,迭代次數自增1
        else
            %%%%%%%%%%%%%%%判斷改進解時候在禁忌表裏%%%%%%%%%%%%%%%
            [M,N]=size(tabu);
            r=0;
            for m=1:M
                if candidate(g).key(1)==tabu(m,1)...
                   & candidate(g).key(2) == tabu(m,1)
                    r=1;
                end
            end
            if  r==0
                %%改進解不在禁忌表裏,把改進解賦給下一次迭代的當前解
                xnow(g+1).key=candidate(g).key;
                xnow(g+1).value=func2(xnow(g+1).key);
                %%%%%%%%%%%%%%%%%%%%%更新禁忌表%%%%%%%%%%%%%%%%%%
                tabu=[tabu;xnow(g).key];
                if size(tabu,1)>L
                    tabu(1,:)=[];
                end
                g=g+1;               %更新禁忌表後,迭代次數自增1
            else
                %%%若是改進解在禁忌表裏,用當前解從新產生鄰域解%%%%%
                xnow(g).key=xnow(g).key;
                xnow(g).value=func2(xnow(g).key);
            end
        end
    end
    trace(g)=func2(bestsofar.key);
end
bestsofar;           %最優變量及最優值
figure
plot(trace);
xlabel('迭代次數')
ylabel('目標函數值')
title('搜索過程最優值曲線')
%%%%%%%%%%%%%%%%%%%%%%%適應度函數%%%%%%%%%%%%%%%%%%%%%%%%
function result=func1(x)
summ=sum(x.^2);
result=summ;

3、解題過程及運行結果

1 解題過程
在這裏插入圖片描述
在這裏插入圖片描述

2 運行結果
在這裏插入圖片描述

4、matlab版本及參考文獻

1 matlab版本
2014a

2 參考文獻[1] 包子陽,餘繼周,楊杉.智能優化算法及其MATLAB實例(第2版)[M].電子工業出版社,2016.[2]張巖,吳水根.MATLAB優化算法源代碼[M].清華大學出版社,2017.

相關文章
相關標籤/搜索