演算法——分支限界法

來源:互聯網
上載者:User
對比回溯法
  • 回溯法的求解目標是找出解空間中滿足約束條件的所有解,想必之下,分支限界法的求解目標則是找出滿足約束條件的一個解,或是滿足約束條件的解中找出使某一目標函數值達到極大或極小的解,即在某種意義下的最優解。
  • 另外還有一個非常大的不同點就是,回溯法以深度優先的方式搜尋解空間,而分支界限法則以廣度優先的方式或以最小耗費優先的方式搜尋解空間。
分支限界法的搜尋策略

在當前節點(擴充節點)處,先產生其所有的兒子節點(分支),然後再從當前的活節點(當前節點的子節點)表中選擇下一個擴充節點。為了有效地選擇下一個擴充節點,加速搜尋的進程,在每一個活節點處,計算一個函數值(限界),並根據函數值,從當前活節點表中選擇一個最有利的節點作為擴充節點,使搜尋朝著解空間上有最優解的分支推進,以便儘快地找出一個最優解。分支限界法解決了大量離散最佳化的問題。

選擇方法

1.隊列式(FIFO)分支限界法

隊列式分支限界法將活節點表組織成一個隊列,並將隊列的先進先出原則選取下一個節點為當前擴充節點。

2.優先隊列式分支限界法

優先隊列式分支限界法將活節點表組織成一個優先隊列,並將優先隊列中規定的節點優先順序選取優先順序最高的下一個節點成為當前擴充節點。如果選擇這種選擇方式,往往將資料排成最大堆或者最小堆來實現。

例子:裝載問題

有一批共n個集裝箱要裝上2艘載重量分別為c1,c2的輪船,其中集裝箱i的重量為wi,且要求確定是否有一個合理的裝載方案可將這n個集裝箱裝上這2艘輪船。
可證明,採用如下策略可以得到一個最優裝載方案:先儘可能的將第一艘船裝滿,其次將剩餘的集裝箱裝到第二艘船上。

代碼如下:

 1 //分支限界法解裝載問題 2  3 //子函數,將當前活節點排入佇列 4 template<class Type> 5 void EnQueue(Queue<Type> &Q, Type wt, Type &bestw, int i, int n)  6 { 7     if(i == n)     //可行葉結點 8     {      9         if(wt>bestw) bestw = wt ;10     }11     else Q.Add(wt) ; //非葉結點12 }13 14 //裝載問題先盡量將第一艘船裝滿15 //隊列式分支限界法,返回最優載重量16 template<class Type>17 Type MaxLoading(Type w[],Type c,int n)18 {19     //初始化資料20     Queue<Type> Q;    //儲存活節點的隊列21     Q.Add(-1);    //-1的標誌是標識分層22     int i=1;    //i表示當前擴充節點所在的層數23     Type Ew=0;    //Ew表示當前擴充節點的重量24     Type bestw=0;    //bestw表示當前最優載重量25     26     //搜尋子集空間樹27     while(true)28     {29         if(Ew+w[i]<=c)    //檢查左兒子30             EnQueue(Q,Ew+w[i],bestw,i,n);    //將左兒子添加到隊列31         32         //將右兒子添加到隊列 即表示不將當前貨物裝載在第一艘船33         EnQueue(Q,Ew,bestw,i,n);34         Q.Delete(Ew);    //取下一個節點為擴充節點並將重量儲存在Ew35         if(Ew==-1)    //檢查是否到了同層結束36         {37             if(Q.IsEmpty()) return bestw;    //遍曆完畢,返回最優值38             Q.Add(-1);    //添加分層標誌39             Q.Delete(Ew);    //刪除分層標誌,進入下一層40             i++;41         }42     }43 }

 

演算法MaxLoading的計算時間和空間複雜度為O(2^n).

上述演算法可以改進,設r為剩餘集裝箱的重量,當Ew+r<=bestw的時候,可以將右子樹剪去。因為最優值不可能出現在下面了。

改進代碼如下:

分支限界法解裝載問題的改進

 1 //分支限界法解裝載問題 2  3 //裝載問題先盡量將第一艘船裝滿 4 //隊列式分支限界法,返回最優載重量 5 template<class Type> 6 Type MaxLoading(Type w[],Type c,int n) 7 { 8     //初始化資料 9     Queue<Type> Q;    //儲存活節點的隊列10     Q.Add(-1);    //-1的標誌是標識分層11     int i=1;    //i表示當前擴充節點所在的層數12     Type Ew=0;    //Ew表示當前擴充節點的重量13     Type bestw=0;    //bestw表示當前最優載重量14     15     //搜尋子集空間樹16     while(true)17     {18         //檢查左兒子19         Type wt=Ew+w[i]; //wt為左兒子節點的重量20         if(wt<=c)    //若裝載之後不超過船體可承受範圍21             if(wt>bestw)    //更新最優裝載重量22             {23                 bestw=wt;24                 if(i<n) Q.Add(wt);    //將左兒子添加到隊列25             }26         27         //將右兒子添加到隊列28         if(Ew+r>bestw&&i<n)29             Q.Add(Ew);30         Q.Delete(Ew);    //取下一個節點為擴充節點並將重量儲存在Ew31         if(Ew==-1)    //檢查是否到了同層結束32         {33             if(Q.IsEmpty()) return bestw;    //遍曆完畢,返回最優值34             Q.Add(-1);    //添加分層標誌35             Q.Delete(Ew);    //刪除分層標誌,進入下一層36             i++;37             r-=w[i];    //剩餘集裝箱重量38         }39     }40 }

 

 

用處

分支限界法解決了大量離散最佳化問題。

 

參考資料電腦演算法設計與分析/王曉東編著。-3版。-北京:電子工業出版社,2007.5

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.