利用python处理非线性规划问题


(例题和部分解答思路来自清风老师,代码由自己实现,仅供参考)

思路综述

局部优化算法
最小化 (Minimize)
描述:局部优化算法通常用于在给定初始点附近寻找最优解。SciPy中提供了多种方法,例如BFGS、L-BFGS-B、TNC等。
优点:速度较快,适合在已知局部最优初始点附近进行精细调整。
缺点:局部优化算法的结果高度依赖于初始点的选择。如果初始点选择不佳,算法可能会收敛到一个局部最优解,而不是全局最优解。

全局优化算法
a差分进化 (Differential Evolution)
描述:差分进化是一种基于群体的全局优化算法,适用于连续空间的非线性函数。它通过维护一个种群并利用变异、交叉和选择等操作来搜索最优解。
优点:适合处理复杂的、具有多个局部极小值的问题,能在较大的搜索空间内找到全局最优解。
缺点:计算成本较高,结果可能不稳定,运行多次可能会得到不同的结果。

综合思路
使用全局优化算法(例如,差分进化)来搜索整个搜索空间,找到一个较好的解或一个接近全局最优解的初始点。这一阶段的目的是探索更广泛的解空间,寻找可能的全局最优解。

以全局优化阶段得到的解作为初始点,使用局部优化算法(例如,BFGS或L-BFGS-B)在该点附近进行细致的优化。这一步是为了进一步改进解,充分利用局部优化算法在解的附近精细求解的能力。

基本例题

例题1

在这里插入图片描述

#使用全局优化算法结合局部最优
import numpy as np
from scipy.optimize import differential_evolution, minimize, NonlinearConstraint, Bounds

# 目标函数,需要最大化,因此取负
def objective(x):
    x1, x2 = x
    return -(x1**2 + x2**2 - x1 * x2 - 2 * x1 - 5 * x2)


# 线性约束
def constraint2(x):
    x1, x2 = x
    return 2 * x1 - 3 * x2 + 6

# 定义变量的边界(明确的范围而不是无界,取足够大的范围1e6)
bounds = Bounds([-1e6, -1e6], [1e6, 1e6])

# 不等式约束:
nonlinear_constraint1 = NonlinearConstraint(constraint1, 0, np.inf)
# 定义线性约束
linear_constraint1 = LinearConstraint([2, -3], -6, 1e6)  

# 进行差分进化全局优化
result_global = differential_evolution(objective, bounds=bounds, constraints=[nonlinear_constraint1, linear_constraint_1])

# 使用差分进化的结果作为初始猜测进行局部优化
result_local = minimize(objective, result_global.x, constraints=[nonlinear_constraint1, nonlinear_constraint2])

# 输出结果
print('Global optimization result:')
print(f'Optimal value: {-result_global.fun:.4f}')  # 目标函数取负值,因此应反转回去
print(f'Optimal solution: x1 = {result_global.x[0]:.4f}')
print(f'Optimal solution: x2 = {result_global.x[1]:.4f}')

print('\nLocal optimization result:')
print(f'Optimal value: {-result_local.fun:.4f}')  # 目标函数取负值,因此应反转回去
print(f'Optimal solution: x1 = {result_local.x[0]:.4f}')
print(f'Optimal solution: x2 = {result_local.x[1]:.4f}')

Global optimization result:
Optimal value: -1.0000
Optimal solution: x1 = 1.0000
Optimal solution: x2 = 0.0000

Local optimization result:
Optimal value: -1.0000
Optimal solution: x1 = 1.0000
Optimal solution: x2 = 0.0000

例题2

在这里插入图片描述

import numpy as np
from scipy.optimize import differential_evolution, minimize, NonlinearConstraint, Bounds,LinearConstraint

# 目标函数,需要最大化
def objective(x):
    x1, x2,x3 = x
    return -(x1*x2*x3)

A1=np.array([-1,2,2])
b1_=0
b1=np.inf

A2=np.array([1,2,2])
b2_=-np.inf
b2=72

A3=np.array([1,-1,0])
b3_=10
b3=10

# 定义变量的边界(明确的范围而不是无界)
bounds = Bounds([20, 10,-1e6], [30, 20,1e6])

# 不等式约束:约束函数应该大于等于0
linear_constraint1 = LinearConstraint(A1,b1_,b1)
linear_constraint2 = LinearConstraint(A2,b2_,b2)

#等式约束:
linear_constraint3=LinearConstraint(A3,b3_,b3)


# 进行差分进化全局优化
result_global = differential_evolution(objective, bounds=bounds, constraints=[linear_constraint1,linear_constraint2,linear_constraint3])

# 使用差分进化的结果作为初始猜测进行局部优化
result_local = minimize(objective, result_global.x, constraints=[linear_constraint1,linear_constraint2,linear_constraint3])

# 输出结果
print('Global optimization result:')
print(f'Optimal value: {result_global.fun:.4f}')  
print(f'Optimal solution: x1 = {result_global.x[0]:.4f}')
print(f'Optimal solution: x2 = {result_global.x[1]:.4f}')
print(f'Optimal solution: x3 = {result_global.x[2]:.4f}')

print('\nLocal optimization result:')
print(f'Optimal value: {result_local.fun:.4f}')  
print(f'Optimal solution: x1 = {result_local.x[0]:.4f}')
print(f'Optimal solution: x2 = {result_local.x[1]:.4f}')
print(f'Optimal solution: x3 = {result_global.x[2]:.4f}')
Optimal value: -3445.6051
Optimal solution: x1 = 22.5850
Optimal solution: x2 = 12.5850
Optimal solution: x3 = 12.1225

Local optimization result:
Optimal value: -3445.6051
Optimal solution: x1 = 22.5850
Optimal solution: x2 = 12.5850
Optimal solution: x3 = 12.1225

典型例题

例一:工地选址问题(2)

在这里插入图片描述

建模
在这里插入图片描述

代码

import numpy as np
from math import sqrt
from scipy.optimize import differential_evolution, minimize, LinearConstraint, Bounds

# 工地坐标(p_j, q_j) j=1,2,...,6
loc_wok = [[1.25, 1.25], [8.75, 0.75], [0.5, 4.75], [5.75, 5], [3, 6.5], [7.25, 7.25]]

min_x=np.array(loc_wok).min(axis=0)[0]
min_y=np.array(loc_wok).min(axis=0)[1]
max_x=np.array(loc_wok).max(axis=0)[0]
max_y=np.array(loc_wok).max(axis=0)[0]

# 工地日需求量
need_wok = [3, 5, 4, 7, 6, 11]

# 最大供应量
max_sup = 20

# 目标函数,需要最小化
def objective(vars):
    result = 0
    a = [vars[12], vars[14]]
    b = [vars[13], vars[15]]
    for i in range(2):
        for j in range(6):
            result += (vars[i*6+j] * sqrt((a[i] - loc_wok[j][0])**2 + (b[i] - loc_wok[j][1])**2))
    return result

# 不等式约束
index1 = np.zeros((2, 16))
index1[0, :6] = 1
index1[1, 6:12] = 1

unequal_constraint = [LinearConstraint(index1[i], 0, max_sup) for i in range(2)]

# 等式约束
index2 = np.zeros((6, 16))
for i in range(6):
    index2[i, i] = index2[i, 6 + i] = 1

equal_constraint = [LinearConstraint(index2[i], need_wok[i], need_wok[i]) for i in range(6)]

# 定义变量的边界(减少搜索范围)
lowBound = [0] * 12 + [min_x,min_y]*2
highBound = [max(need_wok)] * 12 + [max_x,max_y]*2
bounds = Bounds(lowBound, highBound)

# 多阶段优化:先进行快速全局优化,然后进行局部优化

# 快速全局优化替代差分进化
result_global = differential_evolution(objective, bounds=bounds, constraints=equal_constraint + unequal_constraint, maxiter=500, popsize=10)

# 使用差分进化的结果作为初始猜测进行局部优化
result_local = minimize(objective, result_global.x, bounds=bounds, constraints=equal_constraint + unequal_constraint)

# 输出结果
print('Global optimization result:')
print(f'Optimal value: {result_global.fun:.2f}')
for i in range(16):
    print(f'Optimal solution: x{i+1} = {result_global.x[i]:.2f}')

print('\nLocal optimization result:')
print(f'Optimal value: {result_local.fun:.4f}')
for i in range(16):
    print(f'Optimal solution: x{i+1} = {result_local.x[i]:.2f}') 

结果

Global optimization result:
Optimal value: 89.57
Optimal solution: x1 = 2.98
Optimal solution: x2 = 0.03
Optimal solution: x3 = 3.99
Optimal solution: x4 = 0.10
Optimal solution: x5 = 5.99
Optimal solution: x6 = 2.93
Optimal solution: x7 = 0.02
Optimal solution: x8 = 4.97
Optimal solution: x9 = 0.01
Optimal solution: x10 = 6.90
Optimal solution: x11 = 0.01
Optimal solution: x12 = 8.07
Optimal solution: x13 = 3.00
Optimal solution: x14 = 6.50
Optimal solution: x15 = 6.14
Optimal solution: x16 = 5.17

Local optimization result:
Optimal value: 89.5715
Optimal solution: x1 = 2.98
Optimal solution: x2 = 0.03
Optimal solution: x3 = 3.99
Optimal solution: x4 = 0.10
Optimal solution: x5 = 5.99
Optimal solution: x6 = 2.93
Optimal solution: x7 = 0.02
Optimal solution: x8 = 4.97
Optimal solution: x9 = 0.01
Optimal solution: x10 = 6.90
Optimal solution: x11 = 0.01
Optimal solution: x12 = 8.07
Optimal solution: x13 = 3.00
Optimal solution: x14 = 6.50
Optimal solution: x15 = 6.14
Optimal solution: x16 = 5.17

例二:飞行管理问题

在这里插入图片描述
在这里插入图片描述
建模
在这里插入图片描述

代码

import numpy as np
from math import sqrt, cos, sin, radians
from scipy.optimize import differential_evolution, minimize, NonlinearConstraint, Bounds

# 工地坐标与初始角度
loc = np.array([[150, 140], [85, 85], [150, 155], [145, 50], [130, 150], [0, 0]])
angle = np.array([243, 236, 220.5, 159, 230, 52])
v = 800  # 速度

def objective(vars):
    return np.sum(vars**2)

# 非线性约束函数生成器
def create_func(i, j):
    def func(x):
        A1 = cos(radians(angle[j] + x[j])) - cos(radians(angle[i] + x[i]))
        B1 = sin(radians(angle[j] + x[j])) - sin(radians(angle[i] + x[i]))
        t0 = -((loc[j][1] - loc[i][1]) * B1 + (loc[j][0] - loc[i][0]) * A1) / (v * (A1**2 + B1**2))
        
        t = max(0, t0)
        
        x_j = loc[j][0] + v * t * cos(radians(angle[j] + x[j]))
        x_i = loc[i][0] + v * t * cos(radians(angle[i] + x[i]))
        y_j = loc[j][1] + v * t * sin(radians(angle[j] + x[j]))
        y_i = loc[i][1] + v * t * sin(radians(angle[i] + x[i]))
        
        return sqrt((x_j - x_i)**2 + (y_j - y_i)**2)
    
    return func

# 构建非线性约束
Constraints = []
for i in range(6):
    for j in range(6):
        if i != j:
            Constraints.append(NonlinearConstraint(create_func(i, j), 8, 1e6))

# 定义变量的边界
lowBound = [-30] * 6
highBound = [30] * 6
bounds = Bounds(lowBound, highBound)

# 全局优化
result_global = differential_evolution(objective, bounds=bounds, constraints=Constraints)

# 局部优化
result_local = minimize(objective, result_global.x, bounds=bounds, constraints=Constraints)

# 输出结果
print('Global optimization result:')
print(f'Optimal value: {result_global.fun:.2f}')
for i in range(6):
    print(f'Optimal solution: x{i+1} = {result_global.x[i]:.2f}')

print('\nLocal optimization result:')
print(f'Optimal value: {result_local.fun:.2f}')
for i in range(6):
    print(f'Optimal solution: x{i+1} = {result_local.x[i]:.2f}')

结果

Global optimization result:
Optimal value: 6.95
Optimal solution: x1 = 0.00
Optimal solution: x2 = -0.00
Optimal solution: x3 = 2.06
Optimal solution: x4 = -0.50
Optimal solution: x5 = -0.00
Optimal solution: x6 = 1.57

Local optimization result:
Optimal value: 6.95
Optimal solution: x1 = 0.00
Optimal solution: x2 = -0.00
Optimal solution: x3 = 2.06
Optimal solution: x4 = -0.50
Optimal solution: x5 = -0.00
Optimal solution: x6 = 1.57
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值