Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
GKDGKD committed Apr 28, 2024
1 parent d400af0 commit 504462b
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,4 @@ Temporary Items

*.pdf
docs/第一期/SGD.py
docs/第一期/增光拉格朗日函数法.py
docs/第一期/增广拉格朗日函数法.py
86 changes: 77 additions & 9 deletions docs/第二期/拉格朗日法.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# 拉格朗日法
# 拉格朗日函数法
本文目录:
[TOC]

## 1. 带约束优化问题
在实际应用中,我们经常面对的优化问题涉及到一定的约束条件。例如,背包问题要求在不超过背包容量的限制下,使得装入背包的物品价值最大化。这些约束可以是等式约束,也可以是不等式约束,可以通过如下形式的数学表达来表示:

Expand All @@ -11,10 +14,10 @@ $$
\end{aligned}
$$

其中,$f(x)$ 是目标函数,$g_i(x)$ 是等式约束条件,$h_j(x)$ 是不等式约束条件。为了解决这种带约束优化的问题,可以采用罚函数、内点法、启发式算法等,但这些算法相对复杂。因此,本文介绍一种常见且易于理解的方法——拉格朗日乘子法
其中,$f(x)$ 是目标函数,$g_i(x)$ 是等式约束条件,$h_j(x)$ 是不等式约束条件。为了解决这种带约束优化的问题,可以采用罚函数、内点法、启发式算法等,但这些算法相对复杂。因此,本文介绍一种常见且易于理解的方法——拉格朗日函数法

## 2. 拉格朗日法
通过引入拉格朗日乘子构建拉格朗日函数,拉格朗日乘子法巧妙地将带约束的优化问题转化为无约束的优化问题,进而求解。
## 2. 拉格朗日函数法
通过引入拉格朗日乘子构建拉格朗日函数,拉格朗日函数法巧妙地**将带约束的优化问题转化为无约束的优化问题**,进而求解。

### 2.1 基本步骤:

Expand Down Expand Up @@ -73,11 +76,11 @@ $$
最后,将最优解 \( x^* = 2 \) 代入原始问题的目标函数中,得到原始问题的最优解为 \( f(x^*) = 2^2 = 4 \)

### 2.3 理解
拉格朗日乘子法到底在做什么?我们先来看下图:
拉格朗日函数法到底在做什么?我们先来看下图:

![](./images/拉格朗日理解.png)

图中的椭圆虚线为目标函数$f(x,y)$ 的等高线,红色实线为约束条件$g(x,y)=c$。我们可以发现,当约束曲线$g(x,y)=c$和等高线$f(x,y)=d_1$相切时,目标函数$f(x,y)$取得极值。两条曲线相切,意味着他们在这点的法线平行,只差一个常数倍(设为$-\lambda$)。
图中的椭圆虚线为目标函数$f(x,y)$ 的等高线,红色实线为约束条件$g(x,y)=c$。我们可以发现,**当约束曲线$g(x,y)=c$和等高线$f(x,y)=d_1$相切时,目标函数$f(x,y)$取得极值**。两条曲线相切,意味着他们在这点的法线平行,只差一个常数倍(设为$-\lambda$)。

联立方程:

Expand All @@ -97,7 +100,7 @@ $$
$$
求解可知$x^* = 2$。可以发现这个方程组和$2.2$中的求解拉格朗日函数的梯度的方程组是等价的。

因此,拉格朗日法其实就是在找目标函数与约束条件相切的那个极值点,同时也是拉格朗日函数的驻点、原始优化问题的解。
因此,拉格朗日法其实就是在**找目标函数与约束条件相切的那个极值点**,同时也是拉格朗日函数的驻点、原始优化问题的解。

### 2.4 优缺点
拉格朗日法**将带约束优化问题转换为一个不带约束的问题**,从而简化了问题的求解,且适用于各种类型的约束条件,包括等式约束和不等式约束。
Expand All @@ -106,7 +109,7 @@ $$

## 3. 增广拉格朗日函数法

增广拉格朗日函数法在拉格朗日函数法的基础上增加了一个二次惩罚项,融合了拉格朗日函数法和二次罚函数法的优势。增广拉格朗日函数法可以将约束优化问题转化为一个无约束优化问题,简化了问题的求解;罚项的引入强化了对约束条件的满足,有助于算法更快地收敛到可行解。相较于二次罚函数法,增广拉格朗日函数法具有更小的约束违反度,求解更为稳定。
增广拉格朗日函数法在拉格朗日函数法的基础上**增加了一个二次惩罚项**,融合了拉格朗日函数法和二次罚函数法的优势。增广拉格朗日函数法可以将约束优化问题转化为一个无约束优化问题,简化了问题的求解;罚项的引入强化了对约束条件的满足,有助于算法**更快地收敛到可行解**。相较于二次罚函数法,增广拉格朗日函数法具有**更小的约束违反度**,求解更为稳定。

### 3.1 等式约束
$$
Expand Down Expand Up @@ -243,6 +246,71 @@ $$
\end{aligned}
$$

### 3.3 代码示例
以$2.2$节的示例为例:

$$
\begin{aligned}
\min_{x} &\quad x^2 \quad \\
\text{s.t.} &\quad x-2 = 0
\end{aligned}
$$

构建增广拉格朗日函数:

$$
\begin{aligned}
L(x, \lambda) &= f(x) + \lambda g(x) + \frac{\sigma}{2} g^2(x) \\
&= x^2 + \lambda (x - 2) + \frac{\sigma}{2} (x-2)^2
\end{aligned}
$$

编写代码求解:

```python
import numpy as np
from scipy.optimize import minimize

# 目标函数
def objective(x):
return x**2

# 约束函数
def constraint(x):
return x - 1

# 增广拉格朗日函数
def augmented_lagrangian(x, lambda_, sigma):
return objective(x) + lambda_ * constraint(x) + (sigma / 2) * constraint(x)**2

# 带约束优化问题求解
def solve_constrained_optimization():
# 初始化参数
x0 = np.array([0.0]) # 初始点
lambda_ = 0.0 # 初始拉格朗日乘子
sigma = 1.0 # 初始惩罚参数

# 定义优化问题
def objective_with_constraints(x):
return augmented_lagrangian(x, lambda_, sigma)

# 求解优化问题
result = minimize(objective_with_constraints, x0, constraints={'type': 'ineq', 'fun': constraint})
return result

# 求解并输出结果
result = solve_constrained_optimization()
print("最优解 x:", result.x)
print("目标函数值:", result.fun)
```

运行结果:
```
最优解 x: [1.]
目标函数值: 1.0
```


## 4. 参考资料
[1] [【知乎】如何理解拉格朗日乘子法?](https://www.zhihu.com/question/38586401) <br>
[1] [【知乎】如何理解拉格朗日乘子法?](https://www.zhihu.com/question/38586401)
[2] [刘浩洋, 户将, 李勇锋, 文再文. (2021). 最优化:建模、算法与理论. 北京: 高教出版社](https://bicmr.pku.edu.cn/~wenzw/optbook/opt1.pdf)

0 comments on commit 504462b

Please sign in to comment.