一文搞懂非线性优化(python)

文摘   2024-09-12 15:51   辽宁  
点击上方“进修编程”,选择“星标公众号

超级无敌干货,第一时间送达!!!

介绍

非线性优化是应用数学和工程学中的一个重要领域,专注于优化受约束的非线性目标函数。本文概述了非线性优化的理论、算法和实际应用,特别是使用 Python。

什么是非线性规划?

非线性规划 (NLP) 是数学优化领域,其中目标函数或任何约束都是非线性的。这与线性规划形成对比,线性规划中的目标函数和约束都是线性的。由于可能存在局部最优、非凸性以及目标函数和约束的复杂性,非线性规划问题可能更复杂且更难解决。

非线性规划中的关键概念

  • 目标函数:您想要优化(最大化或最小化)的函数。在非线性规划中,此函数是非线性的,这意味着它在绘制时不会形成直线。

  • 约束:这些是解决方案可行的必须满足的条件。在 NLP 中,约束也可能是非线性的,这增加了问题的复杂性。

  • 可行区域:满足约束的所有点的集合。在非线性规划中,此区域可能很复杂且不规则。

  • 局部最优与全局最优:局部最优是一种比邻近解决方案更好的解决方案,但不一定是整体上最好的解决方案。全局最优是所有可行解决方案中最好的解决方案。非线性问题可以有多个局部最优,因此很难找到全局最优。

  • 凸性:如果目标函数是凸的,并且可行域是凸集,则问题为凸问题。凸问题通常更容易解决,因为任何局部最优也是全局最优。不满足这些条件的非凸问题更难解决。

算法:各种算法用于解决非线性规划问题,包括:

梯度下降:利用目标函数的梯度来寻找最小值的迭代方法。

牛顿法:使用二阶导数比梯度下降更有效地寻找最优解。

内点法:通过在优化过程中考虑约束来处理约束。

遗传算法:利用自然选择和遗传原理寻找最佳解决方案。

什么是混合整数非线性规划?

混合整数非线性规划 (MINLP) 是一种结合了整数规划和非线性规划的优化问题。它涉及优化受约束的非线性目标函数,其中一些决策变量被限制为整数值,而其他决策变量可以是连续的。这种类型的问题比单独的整数规划或非线性规划更复杂。

MINLP 的关键组件

  • 目标函数:您想要最大化或最小化的非线性函数。非线性特性使得寻找最优解变得具有挑战性。

  • 约束:这些是解决方案必须满足的方程或不等式。约束可以是线性的或非线性的,可能涉及整数和连续变量。

  • 整数变量:被限制为整数值的决策变量。这些变量通常用于表示离散选择,例如是否建造设施,或者生产多少单位的产品。

  • 连续变量:决策变量,可以在给定范围内取任意值。这些变量通常用于表示可以平稳变化的数量,例如生产水平或资源分配。

  • 混合整数性质:该问题涉及整数和连续变量,这增加了解决过程的复杂性。整数约束引入了组合方面,可以显著增加问题的难度。

MINLP 的求解技术

  • 分支定界法:一种解决整数规划问题的通用方法,可适用于 MINLP。它系统地探索决策树的分支,并使用边界来消除次优解决方案。

  • 分支裁剪法:分支定界法的扩展,结合切割平面来细化可行区域并提高效率。

  • 外部近似:将 MINLP 分解为一系列更简单的子问题,通常是线性和非线性规划的混合,并通过迭代方式进行求解。

  • 顺序凸规划:涉及解决原始非凸问题的一系列凸近似。

  • 元启发式方法:遗传算法、模拟退火或粒子群优化等技术可以在合理的时间范围内提供良好的解决方案,尽管它们不能保证最优性。

为什么非线性规划很重要?

非线性规划很重要,因为许多现实世界的问题本质上都是非线性的。它允许更准确地建模和解决各个领域的复杂问题。

关键概念

复杂性:非线性问题通常比线性模型更好地反映现实世界的复杂性。

优化:在简单线性模型失效的情况下,提供一种寻找最优解决方案的方法。

好处

  • 精确建模:捕捉复杂系统的真实本质。

  • 广泛适用性:用于工程、经济学和机器学习等不同领域。

  • 效率:帮助在给定的约束条件下找到最佳的解决方案。

非线性规划示例

小非线性规划问题

例子 :

import numpy as npfrom scipy.optimize import minimize
# Define the objective functiondef objective_function(x): return x[0]**2 + x[1]**2 + x[0]*x[1]
# Define the constraintsconstraints = ({'type': 'eq', 'fun': lambda x: x[0] + x[1] - 1})
# Initial guessx0 = np.array([0.5, 0.5])
# Perform the optimizationresult = minimize(objective_function, x0, constraints=constraints)
print('Optimal value:', result.fun)print('Optimal solution:', result.x)
Optimal value: 0.75Optimal solution: [0.5 0.5]

不可行非线性规划问题

例子 :

constraints = ({'type': 'eq', 'fun': lambda x: x[0] + x[1] - 3})result = minimize(objective_function, x0, constraints=constraints)print('Message:', result.message)print('Success:', result.success)
Message: Optimization terminated successfullySuccess: True

无界非线性规划问题

例子 :

def objective_function_unbounded(x):    return -x[0]**2 - x[1]**2
constraints = ({'type': 'eq', 'fun': lambda x: x[0] + x[1] - 1})result = minimize(objective_function_unbounded, x0, constraints=constraints)print('Message:', result.message)print('Success:', result.success)
Message: Optimization terminated successfullySuccess: True

资源分配问题

例子 :

from scipy.optimize import linprog
c = [-1, -2]A = [[1, 2], [3, 4]]b = [4, 10]x0_bounds = (0, None)x1_bounds = (0, None)
res = linprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds], method='highs')print('Optimal value:', res.fun)print('Optimal solution:', res.x)
Optimal value: -4.0Optimal solution: [0. 2.]

非线性规划 Python 实现

安装 SciPy

要开始使用 Python 进行非线性规划,您需要安装必要的库。SciPy 和 PuLP 是两个广泛用于优化问题的库。

使用 pip 安装它们:

pip install scipy

使用 SciPy

SciPy 提供了多种优化算法,可用于解决非线性规划 (NLP) 问题。下面是使用 SciPy 解决非线性优化问题的示例。

1.Rosenbrock函数

具有狭窄弯曲谷值的函数用于测试优化算法。

问题陈述:最小化 Rosenbrock 函数,这是优化算法的常见测试问题。

目标函数: f(x, y) = (a — x)² + b(y — x²)²

import numpy as np import matplotlib.pyplot as plt from scipy.optimize import minimal from mpl_toolkits.mplot3d import Axes3D 
# 目标函数def rosenbrock ( vars ): x, y = vars a, b = 1 , 100 return (a - x)** 2 + b * (y - x** 2 )** 2
# 初始猜测initial_guess = [ 0 , 0 ]
# 执行优化result = minimal(rosenbrock, initial_guess)
# 提取结果x_opt, y_opt = result.x optimal_value = rosenbrock(result.x)
# 打印结果print ( f"x 的最佳值:{x_opt} " ) print ( f"y 的最佳值:{y_opt} " ) print ( f"Rosenbrock 函数的最小值:{optimal_value} " )
# 绘图x = np.linspace(- 2 , 2 , 100 ) y = np.linspace(- 1 , 3 , 100 ) X, Y = np.meshgrid(x, y) Z = rosenbrock([X, Y])
# 3D 表面图fig = plt.figure(figsize=( 14 , 8 )) ax = fig.add_subplot( 111 , projecting= '3d' ) ax.plot_surface(X, Y, Z, cmap= 'viridis' , edgecolor= 'none' ) ax.scatter(x_opt, y_opt, optimal_value, color= 'red' , s= 50 , label= '最佳解决方案' ) ax.set_xlabel( 'x' ) ax.set_ylabel( 'y' ) ax.set_zlabel( '目标函数值' ) ax.set_title( 'Rosenbrock 函数的 3D 曲面图' ) ax.legend()
plt.show()

2. 球面函数

通常使用简单的二次函数来检查优化性能。

问题陈述:最小化球体函数,这是一个用于优化的简单测试函数。

目标函数: f(x,y)= x² + y²

# 目标函数def  sphere_function ( vars ):     x, y = vars     return x** 2 + y** 2 
# 初始猜测initial_guess = [ 1 , 1 ]
# 执行优化result = minimal(sphere_function, initial_guess)
# 提取结果x_opt, y_opt = result.x optimal_value = sphere_function(result.x)
# 打印结果print ( f"x 的最佳值:{x_opt} " ) print ( f"y 的最佳值:{y_opt} " ) print ( f"Sphere 函数的最小值:{optimal_value} " )
# 绘图x = np.linspace(- 2 , 2 , 100 ) y = np.linspace(- 2 , 2 , 100 ) X, Y = np.meshgrid(x, y) Z = sphere_function([X, Y])
# 3D 表面图fig = plt.figure(figsize=( 14 , 8 )) ax = fig.add_subplot( 111 , projecting= '3d' ) ax.plot_surface(X, Y, Z, cmap= 'viridis' , edgecolor= 'none' ) ax.scatter(x_opt, y_opt, optimal_value, color= 'red' , s= 50 , label= '最佳解决方案' ) ax.set_xlabel( 'x' ) ax.set_ylabel( 'y' ) ax.set_zlabel( '目标函数值' ) ax.set_title( '球体函数的 3D 表面图' ) ax.legend()
plt.show()

3.

具有多个局部最小值的函数测试优化算法寻找全局最小值的能力。

问题陈述:最小化 Himmelblau 函数,该函数具有多个局部最小值。

目标函数: f(x,y)=(x²+ y — 11)²+(x + y² — 7)²

# 目标函数def  himmelblau ( vars ):     x, y = vars     return (x** 2 + y - 11 )** 2 + (x + y** 2 - 7 )** 2 
# 初始猜测initial_guess = [ 0 , 0 ]
# 执行优化result = minimal(himmelblau, initial_guess)
# 提取结果x_opt, y_opt = result.x optimal_value = himmelblau(result.x)
# 打印结果print ( f"x 的最佳值:{x_opt} " ) print ( f"y 的最佳值:{y_opt} " ) print ( f"Himmelblau 函数的最小值:{optimal_value} " )
# 绘图x = np.linspace(- 5 , 5 , 100 ) y = np.linspace(- 5 , 5 , 100 ) X, Y = np.meshgrid(x, y) Z = himmelblau([X, Y])
# 3D 表面图fig = plt.figure(figsize=( 14 , 8 )) ax = fig.add_subplot( 111 , projecting= '3d' ) ax.plot_surface(X, Y, Z, cmap= 'viridis' , edgecolor= 'none' ) ax.scatter(x_opt, y_opt, optimal_value, color= 'red' , s= 50 , label= '最佳解决方案' ) ax.set_xlabel( 'x' ) ax.set_ylabel( 'y' ) ax.set_zlabel( '目标函数值' ) ax.set_title( 'Himmelblau 函数的 3D 表面图' ) ax.legend()
plt.show()

4. Beale 函数

具有多个局部最小值的函数,对于优化算法来说具有挑战性。

问题陈述:最小化 Beale 函数,另一个具有多个局部最小值的测试函数。

目标函数: f(x,y)=(1.5 — x + xy)² +(2.25 — x + xy²)² +(2.625 — x + xy³)²

# 目标函数def  beale ( vars ):     x, y = vars     return ( 1.5 - x + x * y)** 2 + ( 2.25 - x + x * y** 2 )** 2 + ( 2.625 - x + x * y** 3 )** 2 
# 初始猜测initial_guess = [ 1 , 1 ]
# 执行优化result = minimal(beale, initial_guess)
# 提取结果x_opt, y_opt = result.x optimal_value = beale(result.x)
# 打印结果print ( f"x 的最佳值:{x_opt} " ) print ( f"y 的最佳值:{y_opt} " ) print ( f"Beale 函数的最小值:{optimal_value} " )
# 绘图x = np.linspace(- 4 , 4 , 100 ) y = np.linspace(- 4 , 4 , 100 ) X, Y = np.meshgrid(x, y) Z = beale([X, Y])
# 3D 表面图fig = plt.figure(figsize=( 14 , 8 )) ax = fig.add_subplot( 111 , projecting= '3d' ) ax.plot_surface(X, Y, Z, cmap= 'viridis' , edgecolor= 'none' ) ax.scatter(x_opt, y_opt, optimal_value, color= 'red' , s= 50 , label= '最优解' ) ax.set_xlabel( 'x' ) ax.set_ylabel( 'y' ) ax.set_zlabel( '目标函数值' ) ax.set_title( '3D 表面图Beale 函数' ) ax.legend()
plt.show()

5.二次规划问题

具有线性约束的二次函数演示了如何处理优化中的约束。

问题陈述:最小化受线性约束的二次函数。

目标函数: f(x,y)= x² + 2xy + y²

约束:
x+y≥1
x−y≥0

from scipy.optimize import minimal, LinearConstraint 
# 目标函数def quadratic_function ( vars ): x, y = vars return x** 2 + 2 *x*y + y** 2
# 约束def constrain1 ( vars ): x, y = vars return x + y - 1
def constrain2 ( vars ): x, y = vars return x - y
# 定义约束constrains = [ { 'type' : 'ineq' , 'fun' : constrain1}, { 'type' : 'ineq' , 'fun' : constrain2} ]
# 初始猜测initial_guess = [ 0 , 0 ]
# 执行优化result = minimal(quadratic_function, initial_guess,constraints=constraints)
# 提取结果x_opt, y_opt = result.x optimal_value = quadratic_function(result.x)
# 打印结果print ( f"x 的最佳值:{x_opt} " ) print ( f"y 的最佳值:{y_opt} " ) print ( f"二次函数的最小值:{optimal_value} " )
# 绘图x = np.linspace(- 1 , 2 , 100 ) y = np.linspace(- 1 , 2 , 100 ) X, Y = np.meshgrid(x, y) Z = quadratic_function([X, Y])
# 3D 表面图fig = plt.figure(figsize=( 14 , 8 )) ax = fig.add_subplot( 111 , projecting= '3d' ) ax.plot_surface(X, Y, Z, cmap= 'viridis' , edgecolor= 'none' ) ax.scatter(x_opt, y_opt, optimal_value, color= 'red' , s= 50 , label= '最优解' ) ax.set_xlabel( 'x' ) ax.set_ylabel( 'y' ) ax.set_zlabel( '目标函数值' ) ax.set_title('二次函数的 3D 曲面图' ) ax.legend()
plt.show()

结论

非线性规划优化是一种功能强大且用途广泛的工具,可用于解决变量之间关系非线性的复杂现实问题。它超越了线性优化的能力,允许对系统进行更复杂、更现实的建模,同时适应非线性目标函数和约束。通过各种技术和算法(例如梯度下降和进化算法),非线性优化可以在工程、经济学和机器学习等具有挑战性的多样化领域中找到最佳解决方案。

python、matlab程序设计找我

—  —


进修编程
提升编程技能,学习编程技巧