尋找“最好”(4)——不等約束和KKT條件
不等約束
上篇文章介紹瞭如何在等式約束下使用拉格朗日乘子法,然而真實的世界哪有那麼多等式約束?我們碰到的大多數問題都是不等約束。對於不等約束的優化問題,可以這樣描述:
其中f(x)是目標函式,g(x)為不等式約束,h(x)為等式約束,x = x1, x2, …… xk。
對於不等約束來說,無非是大於(包括大於等於)和小於(包括小於等於),常見的不等約束是這樣:
就像等式約束總是轉換成g(x) = 0一樣,我們也希望所有的不等約束都用小於號表達,所以首先將兩個不等約束轉換為小於0的形式:
優化問題的幾何解釋
等式約束g(x) = 0可以在平面上畫出等高線,它與f(x)相切的地方就是最小值。比如下面這個:
f(x)和g(x)的等高線都是圓,在切點處二者的梯度梯度平行,因此可以引入拉格朗日乘子形成新的方程組求解。
對於不等約束來說,g(x) ≤ 0是一個區域,而不是一條線,更準確地說,是很多條等高線堆疊而成的區域,我們把這塊區域稱為可行域。如果不考慮邊界,不等約束有兩種情況,一種是極小值點落在可行域內;另一種是極小值點落在可行域外。
第一種情況相當於約束是多餘的,直接求f(x)的極值即可,例如:
f(x)極小值(0, 0)一定是符合約束的,它落在g(x)內,此時極小值點滿足:
其中條件1是求臨界點,條件2是約束條件本身,只不過這個條件沒有起到任何作用。拉格朗日乘子法當然少不了拉格朗日乘子,所以上式可以改寫成:
λg(x) = 0意味著g(x)是多餘的,g(x)無論取什麼值,最終結果都將是0。
第二種情況才是正真需要考慮的,例如:
f(x)極小值(0, 0)落在g(x)外,這時候g(x)起了作用,需要考慮f(x)在g(x)區域內的極小值點。同等約束一樣,在達到極小值點時,f(x)和g(x)的梯度平行,只不過這次是g(x)的梯度和f(x)的負梯度方向相同:
此時,在極小值處滿足:
g(x) = 0表示極小值位於可行域邊界。根據新的方程組可以求得極小值點。
聯合①和②,同時考慮極值點落在可行域內和可行域外兩種情況,可以將方程組寫成:
在此之上加上約束條件g(x):
更進一步,條件1可以看作新函式的梯度:
方程組的解就是f(x)的極小值點,準確地說是候選極小值點。
如果約束是g(x) < 0,方程組中同樣需要用g(x) ≤ 0,否則就變成了λ = 0,引入拉格朗日乘子將沒有任何意義。從幾何意義上看,如果極值剛剛好滿足g(x) < 0,也就是無限靠近邊界,那麼此時邊界的極限就是g(x) = 0。
KKT條件
KKT來源於人名,Karush-Kuhn-Tucker,其實是三個人,L arush、Kuhn和Tucker,這哥仨研究了不等約束下的最優化條件,所以叫KKT條件。
帶約束的優化可能同時包含等式優化約束和不等約束:
求解問題的第一步是將所有約束和目標函式聯立,其中λ和μ是拉格朗日乘子:
再加使用上一節的結論③:
這些求解條件就是KKT條件——帶約束最優化問題的必要條件。KKT 條件看起來很多,其實很好理解:
(1):目標函式和所有約束函式組成的拉格朗日函式;
(2):學名叫互補鬆弛條件,不用在意叫什麼。它的來歷在上一節介紹過,實際上忘了來歷也沒關係,知道有它就行;
(3)~(4):約束條件;
(5)~(6):拉格朗日系數,符號與約束條件的相反(等號約束的拉格朗日系數λ用不等號,小於等於約束的拉格朗日系數μ用大於等於)。
KKT條件可推廣到更多的條件約束:
將所有約束和目標函式聯立:
KKT條件:
regularity條件
如果不等約束的一組解不滿足KKT條件,它一定不是最優解;然而滿足KKT條件的解也未必是最優解,這就如同鞍點一樣。KKT是否是最優解的必要條件是通過regularity條件(Regularity Conditions)判斷的。regularity條件要求所有起作用的g(x)和h(x)在極值點的梯度是線性無關的。在使用求解方程組時應當首先驗證是否滿足regularity條件。
示例
求(x1 – 1)2 + (x2 + 2)2在滿足約束條件x1 –x2 = 1和x1 + 10 x2 > 10下的極小值。
將問題轉換成數學語言:
通過影象可以看出,存在唯一的極小值點,並且該點就是兩個約束條件的交點,由此可以得到方程組:
由於極值點在g(x)的邊界,所以第二個條件可以改成等於,這就可以求得最終解:
作圖雖然直觀,但並不總是能夠作圖,這就需要拉格朗日乘子法登場了。
首先校驗是否滿足regularity條件:
二者線性無關滿足regularity條件。接下來將目標函式和約束條件轉換成拉格朗日函式:
再通過KKT條件建立方程組:
方程一可以將x1和x2用λ和μ表示:
將x1和x2代h(x):
再將x1和x2代μg(x):
當μ = 0時,
這不滿足約束條件g(x) ≤ 0。再來看μ = 80/99:
所以當μ = 80/99能夠得到極值點(20/11, 9/11),此時f(x)的極小值是:
相關程式碼
帶有不等式的方程組計算太過麻煩,好在Python的cvxpy包可以幫助我們解決優化問題。
從https://www.lfd.uci.edu/~gohlke/pythonlibs/#cvxpy中下載cvxpy.whl.為保證cvxpy安裝成功,還要將numpy升級到最新版,如果cvxpy是通過cvxpy.whl安裝的,numpy也要通過下載.whl安裝,否則將出現“ImportError: cannot import name 'NUMPY_MKL'”錯誤。
下面是使用cvxpy求解示例1:
import cvxpy as cp # 定義變數x1,x2 x1, x2 = cp.Variable(), cp.Variable() # 定義目標函式 obj = cp.Minimize(cp.square(x1 - 1) + cp.square(x2 + 2)) # 定義約束條件 constraints = [x1 - x2 == 1, x1 + 10*x2 >= 10] # 求解 prob = cp.Problem(obj, constraints) prob.solve() # status 的值: # OPTIMAL: 問題被成功解決 # INFEASIBLE:問題無解 # UNBOUNDED:無邊界 # OPTIMAL_INACCURATE:解不精確 print('status: ', prob.status) print('Min value = ', prob.value) print('(x1, x2) = (', x1.value, x2.value , ')')
列印結果:
作者:我是8位的
出處:http://www.cnblogs.com/bigmonkey
本文以學習、研究和分享為主,如需轉載,請聯絡本人,標明作者和出處,非商業用途!
掃描二維碼關注公眾號“我是8位的”
出處:http://www.cnblogs.com/bigmonkey
本文以學習、研究和分享為主,如需轉載,請聯絡本人,標明作者和出處,非商業用途!
掃描二維碼關注公眾號“我是8位的”