干貨 | 10分鐘帶你徹底了解column generation(列生成)算法的原理附j(luò)ava代碼

OUTLINE

  • 前言
  • 預備知識預警
  • 什么是column generation
  • 相關(guān)概念科普
  • Cutting Stock Problem
  • CG求解Cutting Stock Problem
  • 列生成代碼
  • reference

00 前言

這幾天勤奮的小編一直在精確算法的快樂學習之中不能自拔。到列生成算法這一塊,看了好幾天總算把這塊硬骨頭給啃下來了。然后發(fā)現(xiàn)網(wǎng)上關(guān)于列生成的教學資料也不是很多,大部分講的不是那么通俗易懂。所以今天就打算寫一寫這個算法,盡可能寫得通俗易懂。

01 預備知識預警

由于列生成算法涉及的知識點非常多,所以在開始之前希望讀者必須要具備以下的基礎(chǔ)知識,不然就沒法往下玩了:

  • 線性規(guī)劃以及線性規(guī)劃對偶問題
  • 單純形法原理
  • 原問題的影子價格(shadow price)以及對偶變量
  • 單純形法非基變量進基時非基變量檢驗數(shù)(reduce cost)的計算

以上內(nèi)容我就不展開科普了。如果對這些概念還有不熟悉的小伙伴,一定要回去搞清楚再往下看哦。

Cutting Stock Problem[1]

講column generation怎么可能少得了Cutting Stock Problem這個經(jīng)典的問題呢!在開始之前我們將以這個問題為鋪墊一步一步往下講解。

我們有以下問題,原紙卷每個長為L=17m,顧客們分別需要25個3m長,20個5m長,18個7m長的紙卷。那么需要怎樣切割才能使得浪費最小呢?

建模

Column Generation Formulation:
對于一卷紙,可以有很多種切割方案。

  • a_{ij} 表示第j種方案里類別i的個數(shù)。
  • y_{j}表示第 j 種方案的選擇個數(shù)。

于是,我們得到如下模型:
min (y_1 +...+y_n) \\ a_{11}y_1+...+a_{1n}y_n \ge 25 \\ a_{21}y_1+...+a_{2n}y_n \ge 20 \\ a_{31}y_1+...+a_{3n}y_n \ge 18 \\ y_i \in Z

從上面的模型中,所有可行的裁剪方案的總數(shù)為n,我們并不知道這個值是多少,也不需要知道,只需要知道它很大。并且,隨著一卷紙長度的不斷增加,n是爆炸式增長的。

總之,可行的裁剪方案非常多,在上面的模型中我們無法顯式地把所有裁剪方案給表現(xiàn)出來。

02 什么是column generation?

2.1 相關(guān)背景

Column generation 是一種用于求解大規(guī)模線性優(yōu)化問題的非常高效的算法。[3]其理論基礎(chǔ)是由Danzig等于1960年提出。本質(zhì)上而言,列生成算法就是單純形法的一種形式,是用來求解線性規(guī)劃問題的。列生成算法已被應(yīng)用于求解如下著名的NP-hard優(yōu)化問題:機組人員調(diào)度問題(Crew Assignment Problem)、切割問題(Cutting Stock Problem)、車輛路徑問題(Vehicle Routing Problem)、單資源工廠選址問題(The single facility location problem )等。

2.2 larger linear programs

在某些線性優(yōu)化問題的模型中,約束的數(shù)目有限,但是變量的數(shù)目隨著問題規(guī)模的增長會爆炸式的增長,因此不能把所有的變量都顯性的在模型中表達出來。

比如剛剛介紹的Cutting Stock Problem的模型。隨著一卷紙長度的不斷增加,行的裁剪方案數(shù)量是爆炸式增長的。并且,可行的裁剪方案非常多,在模型中無法顯式地把所有裁剪方案給表現(xiàn)出來。

2.3 column generation

單純型法雖然能保證在數(shù)次迭代后找到最優(yōu)解,但像Cutting Stock Problem這一類的問題,由于變量太多根本無法把所有的變量都顯性的在模型中表達出來。所以單純形法在這里就無能為力了。

再有,在用單純形法求解這類線性規(guī)劃問題時,基變量(basic variable)只與約束的個數(shù)相關(guān),每次迭代只會有一個新的非基變量(non-basic variable)進基,因此,在整個求解過程中其實只有很少一部分變量會被涉及到。

因此,有人基于單純型法提出了列生成算法。其思路大概如下:[1]

  1. 先把原問題P_0給restrict到一個規(guī)模更小(即變量數(shù)比原問題少的)的P_1,在P_1上用單純型法求最優(yōu)解,但是此時求得的最優(yōu)解只是P_1上的,并不是P_0 的最優(yōu)解。

  2. 此時,就需要通過一個subproblem去check在那些未被考慮的變量中是否有使得reduced cost小于零的?如果有,那么就把這個變量的相關(guān)系數(shù)列加入到P_1的系數(shù)矩陣中,回到第1步。

經(jīng)過反復的迭代,直到subproblem中的reduced cost rate大于等于零,那么原問題P_0就求到了最優(yōu)解。

看算法流程圖會更加直觀哦:[2]

03 相關(guān)概念科普

剛剛講的內(nèi)容涉及到了幾個概念,master problem,linear master problem(LMP),restricted linear master problem,subproblem等,這一節(jié)來把這幾個概念給講清楚。還是基于上面的Cutting Stock Problem的模型:
min (y_1 +...+y_n) \\ a_{11}y_1+...+a_{1n}y_n \ge 25 \\ a_{21}y_1+...+a_{2n}y_n \ge 20 \\ a_{31}y_1+...+a_{3n}y_n \ge 18 \\ y_i \in Z

3.1 master problem(MP)

對于一般問題而言,如果要用列生成求解,一般需要重新建模成set covering model。也就是和上面的Cutting Stock Problem類似形式的模型。重新建模成set covering model以后的問題就是master problem了。在Cutting Stock Problem中由于一開始就是建成這種形式,所以其Master Problem就是原模型:
min (y_1 +...+y_n) \\ a_{11}y_1+...+a_{1n}y_n \ge 25 \\ a_{21}y_1+...+a_{2n}y_n \ge 20 \\ a_{31}y_1+...+a_{3n}y_n \ge 18 \\ y_i \in Z

3.2 linear master problem(LMP)

Column generation 是一種用于求解大規(guī)模線性優(yōu)化問題的。而上面的模型中,決策變量是整數(shù),因此要用列生成算法的話,要把整數(shù)變量給線性松弛了。得到linear master problem:
min (y_1 +...+y_n) \\ a_{11}y_1+...+a_{1n}y_n \ge 25 \\ a_{21}y_1+...+a_{2n}y_n \ge 20 \\ a_{31}y_1+...+a_{3n}y_n \ge 18 \\ y_i \ge 0

3.2 restricted linear master problem(RLMP)

把LMP給restrict到一個規(guī)模更小(即變量數(shù)比原問題少的)的就是restricted linear master problem了。比如可以用啟發(fā)式算法,在上面的linear master problem找出滿足條件(也就是形成的restricted linear master problem必須要有能滿足LMP所有約束的可行解)的k個列,得到如下的restricted linear master problem:
min (y_1+y_2+...+y_k) \\ a_{11}y_1+...+a_{1k}y_k \ge 25\\ a_{21}y_1+...+a_{2k}y_k \ge 20 \\ a_{31}y_1+...+a_{3n}y_n \ge 18 \\ y_i \ge 0

可以看到,相比原來的linear master problem,restricted linear master problem相當于把y_{k+1}...y_n強制限制為非基變量了。[4]

3.3 subproblem

核能預警,如果這部分看不懂,請確保預備知識過關(guān)。如果預備知識不過關(guān),請在運籌學老師的陪同下觀看,謝謝合作!

上面的限制主問題求解完成后,我們想使用單純型法進行基變量的轉(zhuǎn)換,看看y_{k+1}...y_m中,是否有可以轉(zhuǎn)入基變量的列。還記得怎么找進基的非基變量嗎?(不記得就去問你們的運籌學老師)。當然是通過非基變量的檢驗數(shù)辣,通過\sigma_j = c_j - c_BB^{-1}a_j,在y_{k+1}...y_m中尋找檢驗數(shù)最小并且為負數(shù)的變量,將變量對應(yīng)的那一列添加到RMP中。

那么,在檢驗數(shù)的計算公式中,大家還記得c_BB^{-1}是什么嗎?c_BB^{-1}有兩重含義:

  • 通過求解RLMP問題得到的影子價格(shadow price)。
  • 通過求解RLMP對偶問題得到的對偶變量(dual variable)。

所以在開始之前小編一直強調(diào)預備知識一定要過關(guān)。這兩個含義意味著我們有上面兩種方式得到c_BB^{-1},不過我們一般傾向于使用第二種,WHY?


雖然通過單純型法直接求解restricted linear master problem能得到c_BB^{-1}。但是restricted linear master problem也可能是一個變量很多的線性規(guī)劃。為了加快求解速度,通過單純型法求restricted linear master problemde的對偶問題(將restricted linear master problem對偶一下,就能使得變量數(shù)大幅減小,因為這些變量轉(zhuǎn)換成了對偶問題中的限制條件了),能更快地得到子問題想要的c_BB^{-1}。[1]

所以我們總結(jié)一下:
通過求解RLMP問題或者RLMP對偶問題,得到我們想要的c_BB^{-1}以后,subproblem就是通過\sigma_j = c_j - c_BB^{-1}a_j這條公式,在y_{k+1}...y_m中尋找檢驗數(shù)為負并且最小的變量,將變量對應(yīng)的那一列添加到RLMP中。

3.4 算法流程圖

通過上面講了這么多以后,這里在給出一個更詳細的流程圖:[5]

04 CG求解Cutting Stock Problem

通過上面的問題分析和建模以后,我們這一步一步一步來求解該問題,讓大家徹底理解column generation這個過程。該過程模擬需要用到一個線性求解器,大家還記得小編以前講過的lpsolve的教程嗎?趕緊去翻一下以前的教程,把lpsolveIDE裝上,然后跟著小編的腳步一步一步往下走。


4.1 restricted linear master problem(RLMP)

前面我們完成了問題的建模,得到了Cutting Stock Problem的linear Master Problem。現(xiàn)在,我們可以用啟發(fā)式算法找到一個滿足客戶需要的初始解:
首先,一個卷筒有三種切割方案:
方案1:切成5個3m
方案2:切成2個6m
方案3:切成2個7m

很容易得出,5個方案1、10個方案2、8個方案3,是能滿足所有客戶需求的。即得LMP的一個RLMP如下:
min (y_1 +...+y_3) \\ a_{11}y_1+...+a_{13}y_3 \ge 25 \\ a_{21}y_1+...+a_{23}y_3 \ge 20 \\ a_{31}y_1+...+a_{33}y_3 \ge 18 \\ y_i \ge 0
其中,
a_{11} = 5,a_{12} = 0, a_{13} = 0 \\ a_{21} = 0,a_{22} = 2, a_{13} = 0 \\ a_{31} = 0,a_{32} = 0, a_{13} = 2 \\
這三列分別對應(yīng)著方案1、方案2、方案3。還有一點需要注意的,對于每一列,都需要滿足:
3a_{1j} + 6a_{2j}+ 7a_{3j} \le 16,也就是每一卷紙只有16的長度,不能超出這個長度。這個叫列生成規(guī)則,不同問題有不同的規(guī)則約束。subproblem在尋找某些列或者生成某些列時,就是受到列生成規(guī)則的約束的。

4.2 開始列生成過程

iteration 1

RLMP:
min (y_1 +...+y_3) \\ 5y_1+0y_2+0y_3 \ge 25 \\ 0y_1+2y_2+0y_3 \ge 20 \\ 0y_1+0y_2+2y_3 \ge 18 \\ y_i \ge 0
將該模型輸入lpsolve,得到對偶變量如下:

得到c_BB^{-1} = [0.2, 0.5, 0.5]。現(xiàn)在要找一列加入RMP,是哪一列呢?現(xiàn)在還不知道,我們暫記為\alpha_4 = [a_{14},a_{24},a_{34}]^T。非基變量檢驗數(shù)\sigma_4 = c_4 - c_BB^{-1}\alpha_4 = 1 - 0.2a_{14}-0.5a_{24}-0.5a_{34}

subproblem:
min (1 - 0.2a_{14}-0.5a_{24}-0.5a_{34}) \\ s.t. 3a_{14} + 6a_{24}+ 7a_{34} \le 16 \\ a_{ij} \in Z
求解結(jié)果得\alpha_4 = [1,2,0]^T, \sigma_4= -0.2 < 0,reduced cost 為負數(shù),因此將\alpha_4加入RLMP,開始第二輪迭代。

iteration 2

RLMP:
min (y_1 +...+y_3+y_4) \\ 5y_1+0y_2+0y_3 +1y_4\ge 25 \\ 0y_1+2y_2+0y_3+2y_4 \ge 20 \\ 0y_1+0y_2+2y_3+0y_3 \ge 18 \\ y_i \ge 0
將該模型輸入lpsolve,得到對偶變量如下:

得到c_BB^{-1} = [0.2, 0.4, 0.5]。現(xiàn)在要找一列加入RLMP,是哪一列呢?現(xiàn)在還不知道,我們暫記為\alpha_5 = [a_{15},a_{25},a_{35}]^T。非基變量檢驗數(shù)\sigma_5 = c_5 - c_BB^{-1}\alpha_5 = 1 - 0.2a_{15}-0.4a_{25}-0.5a_{35}

subproblem:
min (1 - 0.2a_{15}-0.4a_{25}-0.5a_{35}) \\ s.t. 3a_{15} + 6a_{25}+ 7a_{35} \le16 \\ a_{ij} \in Z
求解結(jié)果得\alpha_5 = [1,1,1]^T, \sigma_5= -0.1 < 0,reduced cost 為負數(shù),因此將\alpha_5加入RLMP,開始第三輪迭代。

iteration 3

RMP:
min (y_1 +...+y_3+y_4+y5) \\ 5y_1+0y_2+0y_3 +1y_4+1y_5\ge 25 \\ 0y_1+2y_2+0y_3+2y_4+1y_5 \ge 20 \\ 0y_1+0y_2+2y_3+0y_3 +1y_5\ge 18 \\ y_i \ge 0
將該模型輸入lpsolve,得到對偶變量如下:

得到c_BB^{-1} = [0.2, 0.4, 0.4]。現(xiàn)在要找一列加入RLMP,是哪一列呢?現(xiàn)在還不知道,我們暫記為\alpha_6 = [a_{16},a_{26},a_{36}]^T。非基變量檢驗數(shù)\sigma_6 = c_6 - c_BB^{-1}\alpha_6 = 1 - 0.2a_{16}-0.4a_{26}-0.5a_{36}

subproblem:
min (1 - 0.2a_{16}-0.4a_{26}-0.5a_{36}) \\ s.t. 3a_{16} + 6a_{26}+ 7a_{36} \le16 \\ a_{ij} \in Z
求解結(jié)果得\alpha_6 = [5,0,0]^T, \sigma_6 = 0,reduced cost 不為負數(shù),因此不用將\alpha_6加入RLMP,列生成算法結(jié)束。

最終,我們求解最后一次迭代的RLMP:
min (y_1 +...+y_3+y_4+y_5) \\ 5y_1+0y_2+0y_3 +1y_4+1y_5\ge 25 \\ 0y_1+2y_2+0y_3+2y_4+1y_5 \ge 20 \\ 0y_1+0y_2+2y_3+0y_3 +1y_5\ge 18 \\ y_i \ge 0

得到RLMP的最優(yōu)解y = [1.2, 0,0,1, 18],這里因為把MP的整數(shù)決策變量給線性松弛了,求解的是MP問題的一個lower bound。畢竟列生成是用于求解linear program的。如果要求解大規(guī)模整數(shù)規(guī)劃問題,后面我們會介紹結(jié)合column generation的branch and price方法。

至此,我們已經(jīng)完完整整把列生成算法給走了一遍。相信列生成算法的原理已經(jīng)深入各位讀者的心里啦。

05 列生成代碼

獲取方式

06 reference

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,702評論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,615評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,606評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,044評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,826評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,227評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,307評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,447評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,992評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,807評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,001評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,550評論 5 361
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,243評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,667評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,930評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,709評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,996評論 2 374

推薦閱讀更多精彩內(nèi)容