1. 程式人生 > >尋找“最好”(4)——不等約束和KKT條件

尋找“最好”(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位的”