python与数学建模(一)——线性规划

python与数学建模(一)——线性与非线性规划

​ 数学建模国赛刚刚结束,博主想做一个有关使用python进行数学建模的专题。python作为一个简单高效的语言,虽然执行速度慢,不过能够快速开发。相比matlab, python更加轻量集成度更高,使用在数学建模上完全可以胜任。

一、什么是线性规划?

​ 我们不阐述具体的概念,可以将由以下形式的优化问题看成线性规划问题:
m i n ∑ j = 1 n c j x j s . t . ∑ j = 1 n a i j x j = b i , i = 1 , . . . , m , x j > = 0 , i = 1 , . . . , m , min\sum_{j=1}^{n}c_{j}x_{j}\\s.t.\sum_{j=1}^{n}a_{ij}x_{j}=b_{i}, i=1,...,m,\\x_{j}>=0,i=1,...,m, minj=1ncjxjs.t.j=1naijxj=bi,i=1,...,m,xj>=0,i=1,...,m,
​ 或者我们可以用矩阵表示:
m i n cx s . t . Ax = b , x > = 0 , min\quad\textbf{cx}\\ s.t.\quad\textbf{Ax}=\textbf{b},\\ \quad\quad\quad\textbf{x}>=\textbf{0}, mincxs.t.Ax=b,x>=0,
​ 很多时候,我们遇到的线性规划或者是非线性规划问题的约束条件不都是等式,需要加入松弛变量转化为标准形式。此处不深入讨论,我们看下面的代码求解说明,仅考虑最简单的情形。

二、python求解线性规划问题

假设我们要最小化目标函数f=2x+y,满足以下约束条件:

  1. x >= 0
  2. y >= 0
  3. x + y <= 8
  4. 2x + y <= 12
from scipy.optimize import linprog

# 定义目标函数的系数
c = [2, 1]

# 定义不等式约束的系数矩阵
A = [
    [-1, 0],
    [0, -1],
    [1, 1],
    [2, 1]
]

# 定义不等式约束的上界
b = [0, 0, 8, 12]

# 求解线性规划问题
res = linprog(c, A_ub=A, b_ub=b)

if res.success:
    print("最小值为:", res.fun)
    print("最优解为: x =", res.x)
else:
    print("无法找到最优解。")

在这个例子中,c是目标函数的系数,A是不等式约束的系数矩阵,b是不等式约束的上界。linprog函数将会返回一个OptimizeResult对象,其中fun表示目标函数的最小值,x表示最优解。

输出结果

# 最小值为: 0.0
# 最优解为: x = [0. 0.]

三、python求解非线性规划

求解非线性规划,转化为线性规划问题即可。

假设我们要最小化目标函数 f = x^2 + y^2,同时满足以下约束条件:

  1. x >= 1

  2. y >= 1

  3. x + y <= 10

  4. x^2+y^2 = 5

    from scipy.optimize import minimize
    
    # 定义目标函数
    def objective_function(x):
        return x[0]**2 + x[1]**2
    
    # 定义约束条件
    def constraint1(x):
        return x[0] - 1
    
    def constraint2(x):
        return x[1] - 1
    
    def constraint3(x):
        return 10 - x[0] - x[1]
    
    # 定义等式约束
    def eq_constraint(x):
        return x[0]**2 + x[1]**2 - 5
    
    # 定义初始猜测点
    x0 = [0, 0]
    
    # 定义约束条件,ineq表示大于0的不等式等式约束,eq表示等式约束
    constraints = [{'type': 'ineq', 'fun': constraint1},
                   {'type': 'ineq', 'fun': constraint2},
                   {'type': 'ineq', 'fun': constraint3},
                   {'type': 'eq', 'fun': eq_constraint}]
    
    # 求解非线性规划问题
    res = minimize(objective_function, x0, constraints=constraints)
    
    if res.success:
        print("最小值为:", res.fun)
        print("最优解为: x =", res.x)
    else:
        print("无法找到最优解。")
    
    • ineq: 表示不等式约束,即将约束函数的结果限制在非负区间。对于函数fun(x),如果约束条件为fun(x) >= 0,则使用{'type': 'ineq', 'fun': fun}来表示。如果约束条件为fun(x) <= 0,则需要在定义约束函数时取反:fun(x) <= 0 等价于 -fun(x) >= 0

    • eq: 表示等式约束,即将约束函数的结果限制为一个常数。对于函数fun(x),如果约束条件为fun(x) = 0,则使用{'type': 'eq', 'fun': fun}来表示。

等式约束,即将约束函数的结果限制为一个常数。对于函数fun(x),如果约束条件为fun(x) = 0,则使用{'type': 'eq', 'fun': fun}来表示。

输出结果

# 无法找到最优解。