拉格朗日乘子法原理介绍
对于二元函数,设目标函数为f(x1,x2),极值存在的必要条件为:
等式约束为:g(x1,x2)=0
在无约束时,∂x1∂f∗=∂x1∂f∗=0,即df=(∂x1∂f∗)dx1+(∂x2∂f∗)dx2=0
在有等式约束时,除了以上关系式还要满足:
dg=(∂x1∂g∗)dx1+(∂x2∂g∗)dx2=0
由以上两个式子可以得出
dx1dx2=−(∂f∗/∂x2∂f∗/∂x1)dx1dx2=−(∂g∗/∂x2∂g∗/∂x1)
即为(∂x1∂f∗)(∂x2∂g∗)=(∂x2∂f∗)(∂x1∂g∗)
令这个式子等于一个可正可负的常数λ,这个数为拉格朗日乘子
λ=(∂x1∂f∗)(∂x2∂g∗)=(∂x2∂f∗)(∂x1∂g∗)
这些就可以得到一个方程组为
⎩⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎧∂x1∂f∗−λ∂x1∂g∗=0g(x1,x2)=0∂x2∂f∗−λ∂x2∂g∗=0
联立解方程组可得x1、x2、λ,就求得了极值点
这个方程组就相当于一个无约束的函数L=f−λg的极值点,
此函数极值点存在的必要条件为∂x2∂L=∂x2∂L=∂λ∂L=0
这个新定义的函数就为拉格朗日函数L
df=λ(∂x2∂g∗)dx1+λ(∂x2∂g∗)dx2=λdg
这表明在极值点附近,L为目标函数f随约束条件g的微小变化而变化的比率
通过应用拉格朗日乘子,可以使求等式约束条件下函数f的极小点,成为求拉格朗日函数L的驻点。这种引进待定乘子,将有等式约束的寻优问题转化为无约束的寻优问题的做法,称为拉格朗日乘子法。可用于求解有等式约束的非线性规划,还可以用于求解有不等式约束的非线性规划。
对于不等式约束,就要引入松弛变量使得不等式约束变为等式约束,然后进行求解。
例如不等式约束为:
g(X)=ax1+bx2+c≤0
引入松弛变量后为:
g(X)=ax1+bx2+c+x32=0,然后就可以用拉格朗日乘子法进行求解。
拉格朗日乘子法python代码
非线性规划为:min f(x)=60−10x1−4x2+x12+x22−x1x2
等式约束为:g(x)=x1+x2−8=0
构造的拉格朗日等式为:L=60−10x1−4x2+x12+x22−x1x2−λ(x1+x2−8)
λ为乘子
对未知数求导∂x1∂L、∂x2∂L、∂λ∂L
令得到的三个公式等于0,可以求出x1、x2、λ,从而将x1、x2带入f(X)中,就得到了极小值的最优解。
from sympy import *
import numpy as np
#设置变量
x1 = symbols("x1")
x2 = symbols("x2")
a = symbols("a")
#构造拉格朗日等式
L = 60-10*x1-4*x2+x1*x1+x2*x2-x1*x2 - a * (x1+x2-8)
#求导,构造KKT条件
difyL_x1 = diff(L, x1) #对变量x1求导
difyL_x2 = diff(L, x2) #对变量x2求导
difyL_a = diff(L,a) #对乘子a求导
#求解KKT等式
aa = solve([difyL_x1, difyL_x2, difyL_a], [x1, x2, a])
b=[]
#打印结果
for key in aa:
b.append(aa[key])
print(key,aa[key])
c=60-10*b[0]-4*b[1]+b[0]*b[0]+b[1]*b[1]-b[0]*b[1]
print("f(x)=",c)
结果为:
用KKT条件验证解的有效性
KKT条件:最优值必须满足
1、拉格朗日函数L对未知数求导∂x1∂L、∂x2∂L、∂λ∂L为0,
2、拉格朗日乘子与约束函数相乘为0,λg(X)=0
3、约束函数g(X)为0
求取这三个条件所得到的等式就能得到候选最优值。
具体原理参考: 拉格朗日乘子法与KKT条件详解.
对于极值的优化是满足强对偶的(就是对偶式子的最优值是等于原式子的最优值的)
如有错误请指正!