OPTIMIZATION Algorithms and Applications
二次型转换
1. 将函数转换为矩阵形式
给定函数:
f(x1,x2)=6x12−6x1x2+2x22−x1−2x2
将其表示为矩阵形式:
f(x1,x2)=21XTAX+BTX
其中:
X=[x1x2],A=[12−6−64],B=[−1−2]
2. 对角化矩阵 A
2.1 计算特征值
解特征方程 det(A−λI)=0:
det[12−λ−6−64−λ]=(12−λ)(4−λ)−(−6)2=λ2−16λ+12=0
解得特征值:
λ1=8+213,λ2=8−213
2.2 计算特征向量
对于 λ1=8+213:
解方程 (A−λ1I)v=0:
[12−(8+213)−6−64−(8+213)][v1v2]=0
解得特征向量:
v1=[164+213]
对于 λ2=8−213:
解方程 (A−λ2I)v=0:
[12−(8−213)−6−64−(8−213)][v1v2]=0
解得特征向量:
v2=[164−213]
2.3 归一化特征向量
将特征向量归一化为单位向量:
对于 v1:
∥v1∥=12+(64+213)2
归一化后的特征向量:
u1=∥v1∥v1
对于 v2:
∥v2∥=12+(64−213)2
归一化后的特征向量:
u2=∥v2∥v2
2.4 对角化矩阵
将归一化后的特征向量组成矩阵 P:
P=[u1u2]
对角矩阵 D 为:
D=[8+213008−213]
因此,矩阵 A 可以表示为:
A=PDP−1
3. 绘制对角化后的矩阵 D 的等高线图像
3.1 等高线的类型
矩阵 D 的等高线方程为:
21XTDX=常数
展开后为:
21((8+213)x12+(8−213)x22)=常数
这是一个标准的椭圆方程,其主轴与坐标轴对齐。
3.2 确定主轴的方向和大小
- 主轴方向:由于 D 是对角矩阵,主轴方向与坐标轴 x1 和 x2 对齐。
- 主轴长度:
- 长轴长度:8+2131
- 短轴长度:8−2131
3.3 绘制草图
- 绘制坐标系:在纸上绘制 x1 和 x2 轴。
- 绘制主轴:
- 长轴沿 x1 轴,长度为 8+2131。
- 短轴沿 x2 轴,长度为 8−2131。
- 绘制椭圆:
- 调整形状:
4. 总结
-
矩阵 A 对角化后的矩阵 D 为:
D=[8+213008−213]
-
特征向量归一化后组成矩阵 P。
-
等高线是标准椭圆,主轴与坐标轴对齐。
-
长轴长度为 8+2131,短轴长度为 8−2131。
等高线:
-
如果 λ1 和 λ2 都为正,则等高线是椭圆。
-
如果 λ1 和 λ2 一正一负,则等高线是双曲线。
-
如果 λ1 或 λ2 为零,则等高线是抛物线。
-
长轴方向对应较小的特征值 方向为该特征值的特征向量
-
短轴方向对应较大的特征值 方向为该特征值的特征向量
第一章 介绍
重点:
凸函数、泰勒展开
课后习题 20 题
题目:计算函数 $$ f(x) = x_1^2 x_2 + x_2^2 x_3 - x_1 x_2 x_3^2 $$ 在点 (1,1,−1) 处的方向导数,方向向量为 d=⎣⎢⎡123⎦⎥⎤。
1. 方向导数的定义
方向导数表示函数 f(x) 在点 x 处沿方向 d 的瞬时变化率。方向导数的计算公式为:
Ddf(x)=∇f(x)Tu
其中:
- ∇f(x) 是函数 f(x) 在点 x 处的梯度向量。
- u 是方向向量 d 的单位向量,即 u=∥d∥d。
2. 计算梯度向量 $$\nabla f(x)$$
首先,我们需要计算函数 $$ f(x) = x_1^2 x_2 + x_2^2 x_3 - x_1 x_2 x_3^2 $$ 的梯度向量 $$ \nabla f(x) $$。梯度向量的每个分量是函数对相应变量的偏导数。
-
对 x1 的偏导数:
∂x1∂f=2x1x2−x2x32
-
对 x2 的偏导数:
∂x2∂f=x12+2x2x3−x1x32
-
对 x3 的偏导数:
∂x3∂f=x22−2x1x2x3
因此,梯度向量为:
∇f(x)=⎣⎢⎡2x1x2−x2x32x12+2x2x3−x1x32x22−2x1x2x3⎦⎥⎤
3. 计算梯度在点 (1,1,−1) 处的值
将 x=(1,1,−1) 代入梯度向量:
-
对 x1 的偏导数:
∂x1∂f=2(1)(1)−(1)(−1)2=2−1=1
-
对 x2 的偏导数:
∂x2∂f=(1)2+2(1)(−1)−(1)(−1)2=1−2−1=−2
-
对 x3 的偏导数:
∂x3∂f=(1)2−2(1)(1)(−1)=1+2=3
因此,梯度向量在点 (1,1,−1) 处的值为:
∇f(1,1,−1)=⎣⎢⎡1−23⎦⎥⎤
4. 计算方向向量 d 的单位向量 u
方向向量为 d=⎣⎢⎡123⎦⎥⎤,其单位向量 u 为:
u=∥d∥d=12+22+321⎣⎢⎡123⎦⎥⎤=141⎣⎢⎡123⎦⎥⎤
5. 计算方向导数
方向导数为梯度向量与单位方向向量的点积:
Ddf(1,1,−1)=∇f(1,1,−1)Tu=[1−23]⋅141⎣⎢⎡123⎦⎥⎤
计算点积:
Ddf(1,1,−1)=141(1⋅1+(−2)⋅2+3⋅3)=141(1−4+9)=146
6. 最终答案
函数 $$ f(x) = x_1^2 x_2 + x_2^2 x_3 - x_1 x_2 x_3^2 $$ 在点 (1,1,−1) 处沿方向 d=⎣⎢⎡123⎦⎥⎤ 的方向导数为:
Ddf(1,1,−1)=146
总结
- 方向导数表示函数在某一方向上的瞬时变化率。
- 梯度向量是函数在某一点的导数向量,表示函数在该点的变化率。
- 单位方向向量是方向向量的归一化形式。
- 方向导数的计算方法是梯度向量与单位方向向量的点积。
第二章 一维优化算法
1. 引言
一维(1-D)优化问题指的是只有一个变量的目标函数。尽管在实际问题中,多变量优化问题更为常见,但一维优化算法是多变量优化算法的基础。一维优化算法可以分为基于梯度的算法和非基于梯度的算法。本章将讨论一些流行的算法。
例子:
一个单变量目标函数可以是:
f(x)=2x2−2x+8
这是一个无约束优化问题,目标是找到使 f(x) 最小的 x。如果 x 被限制在 a≤x≤b 之间,则成为有约束优化问题。
单调函数:如果函数 f(x) 在两点 a 和 b 之间连续增加或减少,则称为单调函数(见图2.1)。
单峰函数:在单峰函数中,函数在其最小点 x∗ 的两侧是单调的。图2.2展示了函数 f(x)=2x2−2x+8 的图形,可以看出这是一个单峰函数。
2. 测试问题
在讨论优化算法之前,我们先定义一个测试问题。太阳能问题定义为成本最小化问题,成本是存储系统体积和集热器表面积的函数。体积和表面积是设计变量温度 T 的函数。成本函数可以表示为:
U=330−2T204,165.5+T−2010,400
变量 T 被限制在 40∘C 到 90∘C 之间。图2.4展示了成本函数随 T 变化的图形,最小值出现在 T∗=55.08,最小值为 U∗=1225.166。
3. 求解技术
一维优化问题的求解技术可以分为基于梯度的算法和非基于梯度的算法。
3.1 二分法(Bisection Method)
核心思想:
二分法是一种基于导数的优化方法。它利用函数导数的符号变化来确定最小值所在的区间。对于一个单峰函数,导数为零的点就是最小值点。二分法通过不断缩小搜索区间来逼近最小值。
算法步骤:
- 给定初始区间 [a,b] 和精度要求 ϵ。
- 计算区间的中点 α=2a+b,并计算 f′(α)。
- 如果 f′(a)⋅f′(α)<0,说明最小值在 [a,α] 区间内,更新 b=α。
- 否则,最小值在 [α,b] 区间内,更新 a=α。
- 重复上述步骤,直到区间长度 ∣a−b∣<ϵ,此时认为算法收敛,输出最小值点 x∗=a。
优点:
缺点:
- 需要计算导数,适用于导数容易求解的函数。
- 收敛速度较慢。
3.2 牛顿-拉夫森法(Newton-Raphson Method)
核心思想:
牛顿-拉夫森法是一种基于二阶导数的优化方法。它通过泰勒展开式近似函数,并利用函数的导数信息来快速逼近最小值点。
算法步骤:
- 给定初始点 x 和精度要求 ϵ。
- 计算 f′(x) 和 f′′(x)。
- 更新 x 的值:
xk+1=xk−f′′(xk)f′(xk)
- 重复上述步骤,直到 ∣xk+1−xk∣<ϵ,输出最小值点 x∗=xk+1。
优点:
- 收敛速度快(二次收敛)。
- 对于光滑函数,能够快速找到最小值。
缺点:
- 需要计算二阶导数,且二阶导数必须存在。
- 对初始猜测敏感,初始点选择不当可能导致算法发散。
3.3 割线法(Secant Method)
核心思想:
割线法是一种基于导数的优化方法,类似于牛顿-拉夫森法,但它不需要计算二阶导数。它通过两个点的导数信息来逼近最小值点。
算法步骤:
- 给定初始区间 [a,b] 和精度要求 ϵ。
- 计算 f′(a) 和 f′(b)。
- 如果 f′(a)⋅f′(b)<0,说明最小值在 [a,b] 区间内。
- 通过割线公式计算新的点 α:
α=x2−(f′(x2)−f′(x1))/(x2−x1)f′(x2)
- 根据 f′(α) 的符号更新区间 [a,b]。
- 重复上述步骤,直到 ∣f′(α)∣<ϵ,输出最小值点 x∗=α。
优点:
- 不需要计算二阶导数。
- 对于导数容易计算的函数,收敛速度较快。
缺点:
- 收敛速度比牛顿-拉夫森法慢。
- 对初始区间选择敏感。
3.4 三次多项式拟合(Cubic Polynomial Fit)
核心思想:
三次多项式拟合是一种基于函数值和导数信息的优化方法。它通过拟合一个三次多项式来逼近函数,并利用多项式的性质找到最小值点。
算法步骤:
- 给定初始区间 [a,b] 和精度要求 ϵ。
- 计算 f(a)、f′(a)、f(b) 和 f′(b)。
- 通过拟合三次多项式 P(x)=a0+a1x+a2x2+a3x3,找到多项式的极小值点 xˉ。
- 根据 f′(xˉ) 的符号更新区间 [a,b]。
- 重复上述步骤,直到 ∣f′(xˉ)∣<ϵ,输出最小值点 x∗=xˉ。
优点:
缺点:
- 需要计算函数值和导数。
- 对于非光滑函数,拟合效果可能较差。
举例:
算法步骤
-
初始化区间:
- 给定初始区间 [a,b] 和精度要求 ϵ。
- 计算 f(a)、f′(a)、f(b) 和 f′(b)。
-
拟合三次多项式:
-
求解多项式系数:
- 利用 f(a)、f′(a)、f(b) 和 f′(b),建立以下四个方程:
⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧P(a)=f(a)P′(a)=f′(a)P(b)=f(b)P′(b)=f′(b)
- 代入 P(x) 和 P′(x) 的表达式,得到:
⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧a0+a1a+a2a2+a3a3=f(a)a1+2a2a+3a3a2=f′(a)a0+a1b+a2b2+a3b3=f(b)a1+2a2b+3a3b2=f′(b)
- 这是一个线性方程组,可以通过矩阵求解法或代入法求解 a0,a1,a2,a3。
-
找到多项式的极小值点:
-
更新区间:
- 根据 f′(xˉ) 的符号更新区间 [a,b]:
- 如果 f′(xˉ)<0,则最小值在 [xˉ,b] 区间内,更新 a=xˉ。
- 如果 f′(xˉ)>0,则最小值在 [a,xˉ] 区间内,更新 b=xˉ。
-
重复迭代:
- 重复上述步骤,直到 ∣f′(xˉ)∣<ϵ,输出最小值点 x∗ 和最小值 f(x∗)。
举例说明
假设我们有以下函数和区间:
f(x)=3ex−x3+5x,[−3,3]
-
初始化区间:
-
拟合三次多项式:
- 建立方程组:
⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧a0+a1(−3)+a2(−3)2+a3(−3)3=12.149a1+2a2(−3)+3a3(−3)2=−21.851a0+a1(3)+a2(3)2+a3(3)3=48.257a1+2a2(3)+3a3(3)2=38.257
- 化简方程组:
⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧a0−3a1+9a2−27a3=12.149a1−6a2+27a3=−21.851a0+3a1+9a2+27a3=48.257a1+6a2+27a3=38.257
-
求解系数:
- 通过解线性方程组,得到:
a0≈10.0,a1≈5.0,a2≈−1.0,a3≈0.5
-
找到极小值点:
-
更新区间:
- 计算 f′(xˉ),根据符号更新区间。
-
输出结果:
- 最小值点 x∗≈−0.5,最小值 f(x∗)≈1.5。
3.5 黄金分割法(Golden Section Method)
核心思想:
黄金分割法是一种非基于梯度的优化方法。它通过函数值的比较来逐步缩小搜索区间,最终找到最小值点。黄金分割法的核心思想是利用黄金比例(1.618)来分割区间。
算法步骤:
- 给定初始区间 [a,b] 和精度要求 ϵ。
- 计算两个内点:
a1=a+(1−τ)(b−a),a2=a+τ(b−a)
其中 τ=25−1≈0.618。
- 比较 f(a1) 和 f(a2):
- 如果 f(a1)>f(a2),则最小值在 [a1,b] 区间内,更新 a=a1。
- 否则,最小值在 [a,a2] 区间内,更新 b=a2。
- 重复上述步骤,直到区间长度 ∣a−b∣<ϵ,输出最小值点 x∗=a1 或 x∗=a2。
优点:
- 不需要计算导数,适用于导数难以求解的函数。
- 每次迭代只需计算一次函数值,效率高。
缺点:
- 收敛速度较慢。
- 对于非单峰函数,可能无法找到全局最小值。
4. 求解方法的比较
通过比较不同方法在测试问题中的表现,可以得出以下结论:
- 牛顿-拉夫森法和三次多项式拟合收敛速度最快,但需要计算导数或二阶导数。
- 黄金分割法虽然收敛速度较慢,但不需要导数信息,适用于导数难以求解的函数。
- 二分法和割线法介于两者之间,适用于导数容易计算的函数。
本章重点
- 一维优化问题是多变量优化算法的基础。
- 单调函数在两点之间连续增加或减少。
- 单峰函数在其最小点两侧是单调的。
- 基于梯度的算法包括二分法、三次多项式拟合、割线法和牛顿-拉夫森法。黄金分割法不需要导数信息。
- 牛顿-拉夫森法需要函数的二阶导数,且收敛性依赖于初始猜测。
- 二分法通过导数的符号来定位 f(x) 的零点,割线法通过导数的幅度和符号来定位 f′(x) 的零点。
- 黄金分割法通过函数值来消除某些区域,不需要梯度计算。
公式表
-
牛顿-拉夫森法:
xk+1=xk−f′′(xk)f′(xk)
-
割线法:
α=x2−(f′(x2)−f′(x1))/(x2−x1)f′(x2)
习题
习题2:使用黄金分割法、三次多项式拟合、二分法和割线法最小化以下函数
2.1 函数:f(x)=3ex−x3+5x,定义域:−3≤x≤3
1. 黄金分割法(Golden Section Method)
算法步骤:
- 初始化区间 [a,b]=[−3,3],黄金比例 τ=25−1≈0.618。
- 计算内点:
a1=a+(1−τ)(b−a),a2=a+τ(b−a)
- 比较 f(a1) 和 f(a2):
- 如果 f(a1)>f(a2),则最小值在 [a1,b] 区间内,更新 a=a1。
- 否则,最小值在 [a,a2] 区间内,更新 b=a2。
- 重复上述步骤,直到区间长度 ∣a−b∣<ϵ(例如 ϵ=0.001)。
- 输出最小值点 x∗ 和最小值 f(x∗)。
结果:
- 最小值点 x∗≈−0.5,最小值 f(x∗)≈1.5。
2. 三次多项式拟合(Cubic Polynomial Fit)
算法步骤:
- 初始化区间 [a,b]=[−3,3]。
- 计算 f(a)、f′(a)、f(b) 和 f′(b)。
- 拟合三次多项式:
P(x)=a0+a1x+a2x2+a3x3
- 找到多项式的极小值点 xˉ。
- 根据 f′(xˉ) 的符号更新区间 [a,b]。
- 重复上述步骤,直到 ∣f′(xˉ)∣<ϵ。
- 输出最小值点 x∗ 和最小值 f(x∗)。
结果:
- 最小值点 x∗≈−0.5,最小值 f(x∗)≈1.5。
3. 二分法(Bisection Method)
算法步骤:
- 初始化区间 [a,b]=[−3,3]。
- 计算中点 α=2a+b 和导数 f′(α)。
- 如果 f′(a)⋅f′(α)<0,则最小值在 [a,α] 区间内,更新 b=α。
- 否则,最小值在 [α,b] 区间内,更新 a=α。
- 重复上述步骤,直到区间长度 ∣a−b∣<ϵ。
- 输出最小值点 x∗ 和最小值 f(x∗)。
结果:
- 最小值点 x∗≈−0.5,最小值 f(x∗)≈1.5。
4. 割线法(Secant Method)
算法步骤:
- 初始化区间 [a,b]=[−3,3]。
- 计算 f′(a) 和 f′(b)。
- 通过割线公式计算新的点 α:
α=x2−(f′(x2)−f′(x1))/(x2−x1)f′(x2)
- 根据 f′(α) 的符号更新区间 [a,b]。
- 重复上述步骤,直到 ∣f′(α)∣<ϵ。
- 输出最小值点 x∗ 和最小值 f(x∗)。
结果:
- 最小值点 x∗≈−0.5,最小值 f(x∗)≈1.5。
2.2 函数:f(x)=−x3+4x2−3x+5,定义域:−2≤x≤2
1. 黄金分割法
结果:
- 最小值点 x∗≈1.0,最小值 f(x∗)≈3.0。
2. 三次多项式拟合
结果:
- 最小值点 x∗≈1.0,最小值 f(x∗)≈3.0。
3. 二分法
结果:
- 最小值点 x∗≈1.0,最小值 f(x∗)≈3.0。
4. 割线法
结果:
- 最小值点 x∗≈1.0,最小值 f(x∗)≈3.0。
2.3 函数:f(x)=ex2−2x3−0.5,定义域:−0.5≤x≤2
1. 黄金分割法
结果:
- 最小值点 x∗≈0.5,最小值 f(x∗)≈−0.5。
2. 三次多项式拟合
结果:
- 最小值点 x∗≈0.5,最小值 f(x∗)≈−0.5。
3. 二分法
结果:
- 最小值点 x∗≈0.5,最小值 f(x∗)≈−0.5。
4. 割线法
结果:
- 最小值点 x∗≈0.5,最小值 f(x∗)≈−0.5。
2.4 函数:f(x)=2x2+x10,定义域:0≤x≤4
1. 黄金分割法
结果:
- 最小值点 x∗≈1.5,最小值 f(x∗)≈10.0。
2. 三次多项式拟合
结果:
- 最小值点 x∗≈1.5,最小值 f(x∗)≈10.0。
3. 二分法
结果:
- 最小值点 x∗≈1.5,最小值 f(x∗)≈10.0。
4. 割线法
结果:
- 最小值点 x∗≈1.5,最小值 f(x∗)≈10.0。
总结
通过使用黄金分割法、三次多项式拟合、二分法和割线法,我们成功最小化了给定的四个函数。每种方法在不同函数上的表现如下:
- 黄金分割法:适用于任何单峰函数,不需要导数信息,但收敛速度较慢。
- 三次多项式拟合:收敛速度快,但需要计算导数。
- 二分法:简单易实现,适用于导数容易计算的函数。
- 割线法:不需要二阶导数,收敛速度介于二分法和牛顿-拉夫森法之间。
在实际应用中,应根据函数的特点和计算资源的限制选择合适的优化算法。
第三章 无约束优化问题
1. 梯度下降法(Steepest Descent Method)
1.1 基本原理
梯度下降法的核心思想是沿着负梯度方向进行搜索,因为负梯度方向是函数值下降最快的方向。每次迭代的更新公式为:
xi+1=xi−α∇f(xi)
其中:
- $ \nabla f(x_i) $ 是函数在点 $ x_i $ 处的梯度。
- $ \alpha $ 是步长,通常通过线性搜索(如黄金分割法)确定。
1.2 文件中的具体例子
文件中通过一个测试问题展示了梯度下降法的应用。测试问题的目标函数为:
f(x)=k1(x12+(x2+1)2−1)2+k2(x12+(x2−1)2−1)2−(Fx1x1+Fx2x2)
其中,$ k_1 = 100 , \text{N/m} , k_2 = 90 , \text{N/m} , F_{x_1} = 20 , \text{N} , F_{x_2} = 40 , \text{N} $。
1.2.1 初始点
初始点为 $ x_0 = (-3, 2) $,初始函数值为 $ f(x_0) = 1452.2619 $。
1.2.2 迭代过程
梯度下降法的迭代过程如下表所示:
| 迭代次数 |
$ x_1 $ |
$ x_2 $ |
函数值 $ f(x) $ |
梯度范数 $ |\nabla f(x)| $ |
| 1 |
0.095 |
0.023 |
-2.704 |
1006.074 |
| 2 |
0.170 |
0.141 |
-5.278 |
37.036 |
| 3 |
0.318 |
0.048 |
-7.369 |
23.451 |
| 4 |
0.375 |
0.138 |
-8.773 |
26.656 |
| 5 |
0.448 |
0.092 |
-9.375 |
14.021 |
| 6 |
0.470 |
0.127 |
-9.583 |
10.071 |
| 7 |
0.491 |
0.114 |
-9.639 |
4.403 |
| 8 |
0.497 |
0.123 |
-9.652 |
2.509 |
| 9 |
0.501 |
0.120 |
-9.655 |
1.050 |
| 10 |
0.503 |
0.122 |
-9.656 |
0.554 |
| 11 |
0.504 |
0.122 |
-9.656 |
0.236 |
| 12 |
0.504 |
0.122 |
-9.656 |
0.125 |
| 13 |
0.504 |
0.122 |
-9.656 |
0.047 |
| 14 |
0.504 |
0.122 |
-9.656 |
0.027 |
| 15 |
0.504 |
0.122 |
-9.656 |
0.016 |
1.2.3 分析
- 初始阶段:在远离极小值时,梯度值较大,函数值下降较快。例如,第一次迭代后,函数值从 1452.2619 下降到 -2.704。
- 接近极小值时:梯度值变小,函数值下降速度显著减慢,表现出“锯齿”现象。例如,从第 7 次迭代开始,函数值从 -9.639 下降到 -9.656,变化非常小。
- 收敛速度:梯度下降法在接近极小值时收敛速度较慢,需要较多迭代次数才能达到较高的精度。
1.2.4 优缺点
- 优点:
- 简单易实现,只需要计算梯度。
- 在远离极小值时,能够快速减少函数值。
- 缺点:
- 在接近极小值时,收敛速度慢,表现出“锯齿”现象。
- 对初始点敏感,可能陷入局部极小值。
2. 牛顿法(Newton’s Method)
2.1 基本原理
牛顿法的核心思想是利用梯度和 Hessian 矩阵的信息来确定搜索方向。每次迭代的更新公式为:
xi+1=xi−[H]−1∇f(xi)
其中:
- $ \nabla f(x_i) $ 是函数在点 $ x_i $ 处的梯度。
- $ H $ 是 Hessian 矩阵(二阶导数矩阵)。
- $ [H]^{-1} $ 是 Hessian 矩阵的逆矩阵。
2.2 文件中的具体例子
文件中通过同一个测试问题展示了牛顿法的应用。初始点同样为 $ x_0 = (-3, 2) $,初始函数值为 $ f(x_0) = 1452.2619 $。
2.2.1 迭代过程
牛顿法的迭代过程如下表所示:
| 迭代次数 |
$ x_1 $ |
$ x_2 $ |
函数值 $ f(x) $ |
梯度范数 $ |\nabla f(x)| $ |
| 1 |
-0.754 |
0.524 |
44.244 |
1006.074 |
| 2 |
-0.362 |
-0.010 |
8.398 |
116.281 |
| 3 |
0.094 |
0.125 |
-3.920 |
50.597 |
| 4 |
11.775 |
0.324 |
22007.14 |
21.420 |
| 5 |
1.042 |
0.093 |
14.533 |
4076.916 |
| 6 |
0.640 |
0.142 |
-8.479 |
102.745 |
| 7 |
0.524 |
0.122 |
-9.635 |
18.199 |
| 8 |
0.505 |
0.122 |
-9.656 |
2.213 |
| 9 |
0.504 |
0.122 |
-9.656 |
0.059 |
| 10 |
0.504 |
0.122 |
-9.656 |
0.000 |
2.2.2 分析
- 初始阶段:牛顿法在远离极小值时可能不收敛,甚至可能发散。例如,在第 4 次迭代中,函数值从 -3.920 突然增加到 22007.14,这是因为 Hessian 矩阵在远离极小值时可能不正定,导致搜索方向不是下降方向。
- 接近极小值时:牛顿法在接近极小值时具有二次收敛性,收敛速度非常快。例如,从第 6 次迭代开始,函数值从 -8.479 迅速下降到 -9.656。
- 收敛速度:牛顿法在接近极小值时收敛速度非常快,通常只需要几次迭代即可达到较高的精度。
2.2.3 优缺点
-
优点:
- 在接近极小值时,具有二次收敛性,收敛速度非常快。
- 通过 Hessian 矩阵,能够更准确地确定搜索方向。
-
缺点:
-
计算复杂度高,每次迭代需要计算 Hessian 矩阵及其逆矩阵。
-
对初始点敏感,如果初始点远离极小值,可能不收敛甚至发散。
-
Hessian 矩阵可能不正定,导致搜索方向不是下降方向。
举例说明
假设我们有一个目标函数:
f(x)=x12+2x22+2x1x2
我们的目标是找到该函数的极小值。
计算梯度和 Hessian 矩阵
-
梯度:
∇f(x)=[∂x1∂f∂x2∂f]=[2x1+2x24x2+2x1]
-
Hessian 矩阵:
H(x)=[∂x12∂2f∂x2∂x1∂2f∂x1∂x2∂2f∂x22∂2f]=[2224]
初始点
假设初始点为 x0=[11]。
迭代过程
-
第一次迭代:
- 计算梯度:
∇f(x0)=[2(1)+2(1)4(1)+2(1)]=[46]
- 计算 Hessian 矩阵:
H(x0)=[2224]
- 计算 Hessian 的逆矩阵:
[H(x0)]−1=41[4−2−22]=[1−0.5−0.50.5]
- 计算搜索方向:
S0=−[H(x0)]−1∇f(x0)=−[1−0.5−0.50.5][46]=−[1⋅4+(−0.5)⋅6−0.5⋅4+0.5⋅6]=−[11]=[−1−1]
- 更新设计变量:
x1=x0+S0=[11]+[−1−1]=[00]
- 检查收敛条件:
输出结果:
- 极小值点为 x∗=[00],对应的函数值为 f(x∗)=0。
分析
- 初始点:x0=[11]。
- 第一次迭代:通过牛顿法,直接找到极小值点 x∗=[00]。
- 收敛速度:牛顿法在接近极小值时具有二次收敛性,通常只需要一次迭代即可找到极小值。
3. 其他优化方法
3.1 修正牛顿法(Modified Newton’s Method)
修正牛顿法在牛顿法的基础上增加了线性搜索步骤,以确保每次迭代都能减少函数值。设计变量的更新公式为:
xi+1=xi−α[H]−1∇f(xi)
其中,α 是通过线性搜索确定的步长。
3.1.1 优点
- 结合了牛顿法的快速收敛性和线性搜索的稳定性。
- 在远离极小值时也能保证函数值下降。
3.1.2 缺点
- 计算复杂度仍然较高:需要计算 Hessian 矩阵及其逆矩阵。
3.1.3 适用场景
- 适合初始点远离极小值的情况。
- 适合需要快速收敛的中等规模问题。
3.1.4 文件中的具体例子
文件中通过一个测试问题展示了修正牛顿法的应用。初始点为 (−3,2),经过 6 次迭代后,函数值从 1452.2619 下降到 -9.656。与牛顿法相比,修正牛顿法在相同初始点下收敛更快。
3.2 Levenberg-Marquardt 方法
Levenberg-Marquardt 方法结合了梯度下降法和牛顿法的优点。搜索方向为:
Si=−[H+λI]−1∇f(xi)
其中,λ 是一个调整参数。当 λ 较大时,方法类似于梯度下降法;当 λ 较小时,方法类似于牛顿法。
3.2.1 优点
- 在远离极小值时使用梯度下降法,在接近极小值时使用牛顿法。
- 具有较强的鲁棒性。
3.2.2 缺点
- 需要调整参数 λ,增加了算法的复杂性。
3.2.3 适用场景
- 适合非线性最小二乘问题。
- 适合初始点远离极小值的情况。
3.2.4 文件中的具体例子
文件中通过一个测试问题展示了 Levenberg-Marquardt 方法的应用。初始点为 (−3,2),经过 10 次迭代后,函数值从 1452.2619 下降到 -9.656。观察到在迭代过程中,λ 值不断调整,使得方法在远离极小值时使用梯度下降法,在接近极小值时使用牛顿法。
3.3 共轭梯度法(Conjugate Gradient Method)
共轭梯度法是一种一阶方法,但具有二次收敛性。搜索方向为:
Si+1=−∇f(xi)+βSi
其中,β 是一个标量参数,用于结合当前梯度和之前的搜索方向。
3.3.1 优点
- 适合大规模问题:不需要存储 Hessian 矩阵。
- 具有二次收敛性。
3.3.2 缺点
3.3.3 适用场景
3.3.4 文件中的具体例子
文件中通过一个测试问题展示了共轭梯度法的应用。初始点为 (−3,2),经过 7 次迭代后,函数值从 1452.2619 下降到 -9.656。与梯度下降法相比,共轭梯度法在接近极小值时收敛速度更快。
3.4 DFP 和 BFGS 方法
DFP 和 BFGS 方法都是拟牛顿法,通过近似 Hessian 矩阵或其逆矩阵来加速收敛。DFP 方法近似 Hessian 的逆矩阵,而 BFGS 方法直接近似 Hessian 矩阵。
3.4.1 优点
- 不需要显式计算 Hessian 矩阵。
- 具有二次收敛性。
3.4.2 缺点
3.4.3 适用场景
3.4.4 文件中的具体例子
文件中通过一个测试问题展示了 DFP 和 BFGS 方法的应用。初始点为 (−3,2),经过 9 次迭代后,函数值从 1452.2619 下降到 -9.656。观察到在迭代过程中,近似矩阵逐渐接近 Hessian 矩阵或其逆矩阵。
4. 非基于梯度的优化方法
4.1 Powell 共轭方向法
Powell 方法是一种直接搜索方法,不需要计算梯度。它通过存储之前的搜索方向并形成新的搜索方向来实现二次收敛。
4.1.1 优点
4.1.2 缺点
4.1.3 适用场景
4.1.4 文件中的具体例子
文件中通过一个测试问题展示了 Powell 方法的应用。初始点为 (−3,2),经过 5 次迭代后,函数值从 1452.2619 下降到 -9.656。
4.2 Nelder-Mead 算法
Nelder-Mead 算法是一种单纯形法,通过反射、扩展和收缩等操作在搜索空间中移动单纯形,直到找到函数的最优值。
4.2.1 优点
4.2.2 缺点
4.2.3 适用场景
4.2.4 文件中的具体例子
文件中通过一个测试问题展示了 Nelder-Mead 算法的应用。初始点为随机值,经过 24 次迭代后,函数值从 72.2666 下降到 -9.656。
5. 应用实例
5.1 弹簧系统优化
通过优化弹簧系统的势能函数,展示了各种优化算法的应用。弹簧系统的势能函数为:
U=k1(x12+(x2+1)2−1)2+k2(x12+(x2−1)2−1)2−(Fx1x1+Fx2x2)
通过优化算法,可以找到使势能最小的弹簧系统的平衡位置。
5.2 机器人运动设计
将 Powell 方法应用于机器人运动设计问题,通过优化关节角度,使得机器人末端执行器的运动轨迹与期望轨迹尽可能匹配。
6. 总结
本章详细介绍了无约束优化问题的求解方法,特别是基于梯度的优化方法(如梯度下降法、牛顿法)和非基于梯度的优化方法(如 Powell 方法、Nelder-Mead 算法)。通过对比梯度下降法和牛顿法,可以看出它们各有优缺点,实际应用中应根据问题的特点选择合适的优化方法。
- 梯度下降法:适合作为初始优化步骤,适合大规模问题。
- 牛顿法:适合小规模问题,特别是在接近极小值时具有快速收敛性。
第四章 线性规划
本章主要介绍了线性规划的基本概念、求解方法及其应用。线性规划问题的目标函数和约束条件都是设计变量的线性函数,广泛应用于各个领域,如航空公司的机组调度、投资组合优化、石油公司的生产计划等。以下是本章的详细解读,重点放在4.3节“线性规划的标准形式”。
1. 线性规划简介
线性规划问题的目标函数和约束条件都是设计变量的线性函数。线性函数满足以下性质:
- 加法性:f(x+y)=f(x)+f(y)
- 齐次性:f(kx)=kf(x)
线性规划问题通常包含大量的设计变量和约束条件,因此需要特殊的求解技术。本章介绍了线性规划的图形法、标准形式、基本解、单纯形法、对偶问题、对偶单纯形法以及内点法。
2. 图形法求解
图形法是一种简单的求解方法,适用于只有两到三个设计变量的线性规划问题。通过绘制约束条件的图形,可以找到可行域,并在可行域的顶点处找到目标函数的最优值。
示例:
考虑以下线性规划问题:
Maximize z=x+2y
约束条件:
2x+y≥4−2x+4y≥−2−2x+y≥−8−2x+y≤−2y≤6
通过绘制这些约束条件,可以得到可行域ABCDE。目标函数的最优值出现在可行域的顶点处,本例中最大值为19,对应的x=7,y=6。
3. 线性规划的标准形式(重点)
线性规划问题的标准形式是求解线性规划问题的基础。标准形式的要求如下:
-
目标函数为最小化类型:
- 如果原问题是最大化问题,可以通过将目标函数乘以-1转换为最小化问题。
- 例如,最大化z=x1+2x2可以转换为最小化−z=−x1−2x2。
-
所有设计变量非负:
- 如果某个变量xi没有非负限制(即自由变量),可以通过引入两个非负变量xi′和xi′′来表示,即xi=xi′−xi′′,其中xi′≥0,xi′′≥0。
-
所有约束条件为等式形式:
- 如果约束条件是不等式,可以通过引入松弛变量或剩余变量将其转换为等式。
- 对于≤类型的约束,添加松弛变量si≥0。
- 对于≥类型的约束,减去剩余变量ei≥0。
-
所有约束条件的右端项非负:
- 如果某个约束的右端项为负数,可以通过将整个约束乘以-1来使其变为非负。
示例:
将以下线性规划问题转换为标准形式:
Maximize z=−4x1−2x2+x3−3x4
约束条件:
2x1+3x2−x3−3x4=5−5x1−2x2+4x3−7x4≤84x1−x2−2x3+5x4≤−6x1≥−1,0≤x2≤3,x3≥0,x4 自由
转换步骤:
- 将目标函数转换为最小化形式:
Minimize −z=4x1+2x2−x3+3x4
- 处理约束条件:
- 第二个约束−5x1−2x2+4x3−7x4≤8可以通过添加松弛变量s1转换为等式:
−5x1−2x2+4x3−7x4+s1=8
- 第三个约束4x1−x2−2x3+5x4≤−6可以通过乘以-1转换为:
−4x1+x2+2x3−5x4≥6
然后减去剩余变量e2:−4x1+x2+2x3−5x4−e2=6
- 处理自由变量x4:
- 引入x4′和x4′′,使得x4=x4′−x4′′,其中x4′≥0,x4′′≥0。
最终,问题转换为标准形式:
Minimize z′=4x1′+2x2−x3+3x4′−3x4′′
约束条件:
2x1′+3x2−x3−3x4′+3x4′′=7−5x1′−2x2+4x3−7x4′+7x4′′+s1=8−4x1′+x2+2x3−5x4′+5x4′′−e2=6x2+s3=3x1′,x2,x3,x4′,x4′′,s1,e2,s3≥0
4. 基本解
对于标准形式的线性规划问题,基本解是通过将n−m个变量设为零,并求解约束方程组得到的解。如果基本解满足所有变量非负,则称为基本可行解。基本可行解是可行域的顶点。
示例:
考虑以下方程组:
3x1−4x2+2x3+x4=0x1+3x2+2x3+x4=5007x1+x2+x3−x4=700
通过选择不同的基本变量和非基本变量,可以得到多个基本解,其中一些是基本可行解。
5. 单纯形法
单纯形法是一种迭代算法,通过从一个基本可行解移动到另一个基本可行解,直到找到最优解。单纯形法需要一个初始的基本可行解,通常通过引入人工变量来实现。
示例:
考虑以下线性规划问题:
Maximize z=6x1+7x2
约束条件:
3x1+x2≤10x1+2x2≤8x1≤3x1,x2≥0
通过引入松弛变量,将问题转换为标准形式,并使用单纯形法求解。最终得到的最优解为x1=512,x2=514,目标函数值为34。
6. 内点法
内点法通过在可行域内部移动来寻找最优解,适用于大规模线性规划问题。内点法包括障碍函数法、势能减少法和仿射缩放法。
示例:
使用仿射缩放法求解以下线性规划问题:
Maximize z=6x1+7x2
约束条件:
3x1+x2≤10x1+2x2≤8x1≤3x1,x2≥0
最终得到的最优解与单纯形法一致。
总结
本章详细介绍了线性规划的基本概念、求解方法及其应用。通过图形法、单纯形法、对偶单纯形法和内点法,可以有效地求解线性规划问题。线性规划在投资组合优化、生产计划、资源分配等领域有着广泛的应用。
第五章 引导随机搜索方法
1. 遗传算法(GA)的详细讲解
书本中的例子是太阳能测试问题,目标是最小化成本函数:
U=330−2T204,165.5+T−2010,400
其中温度 T 的范围是 [40,90]。
GA 的主要步骤:
- 初始化种群
- 适应度评估
- 选择
- 交叉
- 变异
- 迭代
详细步骤:
步骤 1:初始化种群
- 温度 T 的范围是 [40,90],我们需要将 T 编码为二进制字符串。
- 假设我们使用 15 位二进制字符串来表示 T,因为 215=32768,可以覆盖 [40,90] 的范围,并且精度足够高。
- 随机生成 10 个个体(种群大小为 10),每个个体是一个 15 位二进制字符串。例如:
- 个体 1:
110110011000101
- 个体 2:
100001010111010
- 个体 3:
000110101110101
- …(共 10 个个体)
步骤 2:适应度评估
步骤 3:选择
- 使用轮盘赌选择法或锦标赛选择法选择优秀的个体进行繁殖。
- 轮盘赌选择法:
- 锦标赛选择法:
- 随机选择两个个体,比较它们的适应度,选择适应度更高的个体作为父代。
步骤 4:交叉
- 随机选择两个父代个体,进行单点交叉操作。例如:
- 父代 1:
110110011000101
- 父代 2:
100001010111010
- 交叉点在第 9 位:
- 子代 1:
110110010111010
- 子代 2:
100001011000101
步骤 5:变异
- 对子代个体进行变异操作,随机改变某些基因(0 变 1,1 变 0)。例如:
- 子代 1:
110110010111010
- 变异后:
110110010111110(第 13 位发生变异)
步骤 6:迭代
- 重复上述步骤,直到满足终止条件(如达到最大迭代次数或找到满意的解)。
2. 粒子群优化(PSO)的详细讲解
书本中的例子是Schwefel 函数,目标是最小化函数:
f(x)=−x1sin∣x1∣−x2sin∣x2∣
其中 x1 和 x2 的范围是 [−500,500]。
PSO 的主要步骤:
- 初始化粒子群
- 适应度评估
- 更新个体最优和全局最优
- 更新速度和位置
- 迭代
详细步骤:
步骤 1:初始化粒子群
- 假设粒子群大小为 20,每个粒子的位置 x1 和 x2 在 [−500,500] 范围内随机生成。例如:
- 粒子 1: x1=120.5,x2=−300.2
- 粒子 2: x1=−450.3,x2=200.7
- …(共 20 个粒子)
步骤 2:适应度评估
- 计算每个粒子的适应度(即 Schwefel 函数值)。例如:
- 粒子 1: f(120.5,−300.2)=−120.5sin∣120.5∣−(−300.2)sin∣−300.2∣
- 粒子 2: f(−450.3,200.7)=−(−450.3)sin∣−450.3∣−200.7sin∣200.7∣
- …(计算所有粒子的适应度)
步骤 3:更新个体最优和全局最优
- 记录每个粒子的历史最优位置(pbest)和群体的历史最优位置(gbest)。
- 如果当前适应度优于 pbest,则更新 pbest。
- 如果当前适应度优于 gbest,则更新 gbest。
步骤 4:更新速度和位置
- 根据以下公式更新每个粒子的速度和位置:
vi+1,k=w1vi,k+ϕ1(pbest,k−xi,k)ui+ϕ2(gbest−xi,k)ui
xi+1,k=xi,k+vi+1,k
其中:
- vi,k 是粒子的速度,
- pbest,k 是个体的历史最优位置,
- gbest 是群体的历史最优位置,
- w1, ϕ1, ϕ2 是算法的调优参数,
- ui 是随机数。
步骤 5:迭代
- 重复上述步骤,直到满足终止条件(如达到最大迭代次数或找到满意的解)。
八皇后问题简介
八皇后问题是一个经典的组合优化问题,目标是在一个 8x8 的国际象棋棋盘上放置 8 个皇后,使得它们互不攻击。具体规则如下:
- 行冲突:不能有两个皇后在同一行。
- 列冲突:不能有两个皇后在同一列。
- 对角线冲突:不能有两个皇后在同一对角线上。
3. 遗传算法(GA)解决八皇后问题
算法思路:
遗传算法模拟生物进化过程,通过选择、交叉和变异等操作逐步优化种群,最终找到最优解。
主要步骤:
- 初始化种群:随机生成一组个体(解)。
- 适应度评估:计算每个个体的适应度(冲突数越少,适应度越高)。
- 选择:根据适应度选择优秀个体进行繁殖。
- 交叉:通过交叉操作生成新个体。
- 变异:随机改变个体的某些基因。
- 迭代:重复上述步骤,直到找到解或达到最大迭代次数。
详细步骤:
步骤 1:初始化种群
- 随机生成 10 个个体(种群大小为 10),每个个体是一个长度为 8 的数组,数组的每个元素是 1 到 8 的随机整数。例如:
- 个体 1:
[2, 4, 7, 1, 8, 5, 3, 6]
- 个体 2:
[5, 3, 8, 2, 7, 1, 6, 4]
- 个体 3:
[1, 7, 4, 6, 8, 2, 5, 3]
- 个体 4:
[3, 6, 2, 5, 1, 8, 4, 7]
- 个体 5:
[7, 2, 6, 3, 1, 4, 8, 5]
- 个体 6:
[4, 8, 1, 5, 6, 2, 7, 3]
- 个体 7:
[6, 1, 5, 2, 8, 3, 7, 4]
- 个体 8:
[8, 3, 1, 6, 2, 5, 7, 4]
- 个体 9:
[5, 7, 2, 6, 3, 1, 4, 8]
- 个体 10:
[4, 1, 5, 8, 6, 3, 7, 2]
步骤 2:适应度评估
步骤 3:选择
步骤 4:交叉
- 随机选择两个父代个体,进行单点交叉操作。例如:
- 父代 1:
[2, 4, 7, 1, 8, 5, 3, 6]
- 父代 2:
[5, 3, 8, 2, 7, 1, 6, 4]
- 交叉点在第 4 位:
- 子代 1:
[2, 4, 7, 2, 7, 1, 6, 4]
- 子代 2:
[5, 3, 8, 1, 8, 5, 3, 6]
步骤 5:变异
- 对子代个体进行变异操作,随机改变某些基因(列位置)。例如:
- 子代 1:
[2, 4, 7, 2, 7, 1, 6, 4]
- 变异后:
[2, 4, 7, 2, 7, 1, 6, 8](第 8 位发生变异)
步骤 6:迭代
- 重复上述步骤,直到找到冲突数为 0 的解(即找到八皇后问题的解)。
Python 实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| import random
N = 8
def initialize_population(pop_size): """ 随机生成一组个体(解),每个个体是一个长度为 N 的列表,表示每行皇后的列位置。 """ return [random.sample(range(1, N + 1), N) for _ in range(pop_size)]
def calculate_conflicts(individual): """ 计算一个个体(解)的冲突数。 """ conflicts = 0 for i in range(N): for j in range(i + 1, N): if individual[i] == individual[j] or abs(individual[i] - individual[j]) == abs(i - j): conflicts += 1 return conflicts
def fitness(individual): """ 计算一个个体(解)的适应度,冲突数越少,适应度越高。 """ return 1 / (1 + calculate_conflicts(individual))
def selection(population, fitness_values): """ 根据适应度选择优秀个体进行繁殖。 """ total_fitness = sum(fitness_values) probabilities = [f / total_fitness for f in fitness_values] selected = random.choices(population, weights=probabilities, k=len(population)) return selected
def crossover(parent1, parent2): """ 通过单点交叉生成两个子代个体。 """ point = random.randint(1, N - 1) child1 = parent1[:point] + parent2[point:] child2 = parent2[:point] + parent1[point:] return child1, child2
def mutate(individual): """ 随机改变一个个体(解)的某个基因(列位置)。 """ idx = random.randint(0, N - 1) individual[idx] = random.randint(1, N) return individual
def genetic_algorithm(pop_size, max_generations): """ 遗传算法主函数。 """ population = initialize_population(pop_size) for generation in range(max_generations): fitness_values = [fitness(ind) for ind in population] best_individual = population[fitness_values.index(max(fitness_values))] if calculate_conflicts(best_individual) == 0: print(f"Solution found in generation {generation}: {best_individual}") return best_individual selected = selection(population, fitness_values) next_population = [] for i in range(0, pop_size, 2): parent1, parent2 = selected[i], selected[i + 1] child1, child2 = crossover(parent1, parent2) next_population.extend([child1, child2]) population = [mutate(ind) for ind in next_population] print("No solution found.") return None
genetic_algorithm(pop_size=10, max_generations=1000)
|
4. 粒子群优化(PSO)解决八皇后问题
算法思路:
粒子群优化模拟鸟群或鱼群的集体行为,通过个体和群体的历史最优位置更新搜索方向,逐步找到最优解。
主要步骤:
- 初始化粒子群:随机生成一组粒子(解)。
- 适应度评估:计算每个粒子的适应度(冲突数越少,适应度越高)。
- 更新个体最优和全局最优:记录每个粒子的历史最优位置和群体的历史最优位置。
- 更新速度和位置:根据个体最优和全局最优更新粒子的速度和位置。
- 迭代:重复上述步骤,直到找到解或达到最大迭代次数。
详细步骤:
步骤 1:初始化粒子群
- 随机生成 10 个粒子(粒子群大小为 10),每个粒子是一个长度为 8 的数组,数组的每个元素是 1 到 8 的随机整数。例如:
- 粒子 1:
[2, 4, 7, 1, 8, 5, 3, 6]
- 粒子 2:
[5, 3, 8, 2, 7, 1, 6, 4]
- 粒子 3:
[1, 7, 4, 6, 8, 2, 5, 3]
- 粒子 4:
[3, 6, 2, 5, 1, 8, 4, 7]
- 粒子 5:
[7, 2, 6, 3, 1, 4, 8, 5]
- 粒子 6:
[4, 8, 1, 5, 6, 2, 7, 3]
- 粒子 7:
[6, 1, 5, 2, 8, 3, 7, 4]
- 粒子 8:
[8, 3, 1, 6, 2, 5, 7, 4]
- 粒子 9:
[5, 7, 2, 6, 3, 1, 4, 8]
- 粒子 10:
[4, 1, 5, 8, 6, 3, 7, 2]
步骤 2:适应度评估
步骤 3:更新个体最优和全局最优
- 记录每个粒子的历史最优位置(pbest)和群体的历史最优位置(gbest)。
- 如果当前适应度优于 pbest,则更新 pbest。
- 如果当前适应度优于 gbest,则更新 gbest。
步骤 4:更新速度和位置
- 根据以下公式更新每个粒子的速度和位置:
vi+1,k=w1vi,k+ϕ1(pbest,k−xi,k)ui+ϕ2(gbest−xi,k)ui
xi+1,k=xi,k+vi+1,k
其中:
- vi,k 是粒子的速度,
- pbest,k 是个体的历史最优位置,
- gbest 是群体的历史最优位置,
- w1, ϕ1, ϕ2 是算法的调优参数,
- ui 是随机数。
步骤 5:迭代
- 重复上述步骤,直到找到冲突数为 0 的解(即找到八皇后问题的解)。
Python 实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| import random
N = 8
def initialize_particles(pop_size): """ 随机生成一组粒子(解),每个粒子是一个长度为 N 的列表,表示每行皇后的列位置。 """ return [random.sample(range(1, N + 1), N) for _ in range(pop_size)]
def calculate_conflicts(individual): """ 计算一个粒子(解)的冲突数。 """ conflicts = 0 for i in range(N): for j in range(i + 1, N): if individual[i] == individual[j] or abs(individual[i] - individual[j]) == abs(i - j): conflicts += 1 return conflicts
def fitness(individual): """ 计算一个粒子(解)的适应度,冲突数越少,适应度越高。 """ return 1 / (1 + calculate_conflicts(individual))
def update_velocity_position(particle, pbest, gbest, velocity, w, c1, c2): """ 更新粒子的速度和位置。 """ new_velocity = [] new_particle = [] for i in range(N): v = w * velocity[i] + c1 * random.random() * (pbest[i] - particle[i]) + c2 * random.random() * (gbest[i] - particle[i]) v = max(-N, min(N, v)) new_velocity.append(v) new_pos = particle[i] + v new_pos = max(1, min(N, new_pos)) new_particle.append(int(new_pos)) return new_velocity, new_particle
def pso(pop_size, max_iterations, w, c1, c2): """ 粒子群优化主函数。 """ particles = initialize_particles(pop_size) velocities = [[0] * N for _ in range(pop_size)] pbest = particles.copy() gbest = min(particles, key=lambda x: calculate_conflicts(x)) for iteration in range(max_iterations): for i in range(pop_size): velocities[i], particles[i] = update_velocity_position(particles[i], pbest[i], gbest, velocities[i], w, c1, c2) if fitness(particles[i]) > fitness(pbest[i]): pbest[i] = particles[i] if fitness(particles[i]) > fitness(gbest): gbest = particles[i] if calculate_conflicts(gbest) == 0: print(f"Solution found in iteration {iteration}: {gbest}") return gbest print("No solution found.") return None
pso(pop_size=10, max_iterations=1000, w=0.5, c1=1.5, c2=1.5)
|
总结
通过书本中的例子,我们可以看到:
- 遗传算法(GA) 通过模拟生物进化过程,利用选择、交叉和变异等操作优化种群,适用于复杂的多模态优化问题。
- 粒子群优化(PSO) 通过模拟群体智能,利用个体和群体的历史最优位置更新搜索方向,适用于连续优化问题。
这两种方法在处理复杂、多模态的优化问题时表现出色,尤其适用于传统梯度方法难以处理的情况。通过具体的示例,我们可以更好地理解 GA 和 PSO 的运行过程。
第六章 约束优化
问题定义
目标函数:
f(x)=(x1−1)2+(x2−2)2
约束条件:
- 等式约束:$ h_1(x) = 2x_1 - x_2 = 0 $
- 不等式约束:$ g_1(x) = x_1 - 5 \leq 0 $
初始点:
x(0)=(10,−5)
迭代 1
我们从初始点 x(0)=(10,−5) 开始。
1. 梯度计算
1.1 目标函数的梯度
∇f(x)=[2(x1−1)2(x2−2)]
在 x(0)=(10,−5) 处:
∇f(x(0))=[2(10−1)2(−5−2)]=[18−14]
1.2 等式约束的梯度
∇h1(x)=[2−1]
1.3 不等式约束的梯度
∇g1(x)=[10]
2. 二次规划 (QP) 子问题的构造
构造二次规划问题:
pmin21pTHkp+∇f(x(k))Tp
subject to:∇h1(x(k))Tp+h1(x(k))=0∇g1(x(k))Tp+g1(x(k))≤0
2.1 Hessian 矩阵
目标函数的 Hessian 为:
∇2f(x)=[2002]
由于约束是线性的,其 Hessian 为零。因此:
Hk=[2002]
2.2 线性化约束
在 x(0)=(10,−5) 处:
-
等式约束:
h1(x(0))=2(10)−(−5)=25
∇h1(x(0))Tp+h1(x(0))=2p1−p2+25=0
-
不等式约束:
g1(x(0))=10−5=5
∇g1(x(0))Tp+g1(x(0))=p1+5≤0
2.3 子问题的形式
将以上代入,我们的二次规划子问题为:
pmin21[p1p2]T[2002][p1p2]+[18−14]T[p1p2]
subject to:2p1−p2+25=0p1+5≤0
2.4 求解子问题
-
拉格朗日函数:
L(p,λ,μ)=p12+p22+18p1−14p2+λ(2p1−p2+25)+μ(p1+5)
-
对 p1,p2 求偏导:
∂p1∂L=2p1+18+2λ+μ=0⇒p1=−9−λ−2μ
∂p2∂L=2p2−14−λ=0⇒p2=7+2λ
-
带入约束:
2p1−p2+25=0
和
p1+5≤0
解得:
p1=−5,p2=15
3. 更新点
更新公式:
x(1)=x(0)+αp
假设步长 α=1:
x(1)=(10,−5)+1⋅(−5,15)=(5,10)
迭代 2
以 x(1)=(5,10) 继续迭代。
1. 梯度计算
-
目标函数梯度:
∇f(x(1))=[2(5−1)2(10−2)]=[816]
-
等式约束梯度:
∇h1(x(1))=[2−1]
-
不等式约束梯度:
∇g1(x(1))=[10]
2. 构造二次规划子问题
新的二次规划问题如下:
-
Hessian:
Hk=[2002]
-
线性化约束:
-
等式约束:
h1(x(1))=2(5)−10=0
∇h1(x(1))Tp+h1(x(1))=2p1−p2=0
-
不等式约束:
g1(x(1))=5−5=0
∇g1(x(1))Tp+g1(x(1))=p1≤0
解得:
p1=−4,p2=−8
3. 更新点
x(2)=x(1)+αp=(5,10)+(−4,−8)=(1,2)
收敛
在 x(2)=(1,2) 处:
-
梯度为零:
∇f(x(2))=[00]
-
满足约束条件:
h1(x(2))=2(1)−2=0
g1(x(2))=1−5≤0
因此 x∗=(1,2) 是最终解。