线性规划如何用python代码实现(1)

昨天我们就已经讲了,一道例题,得到了这个例题的数学建模,可是该怎么求呢?自己用手算,太复杂了,我们可以利用python代码或者matlab,由于matlab搞这些没啥难度(要太多内存了),我就用pycharm来写python代码求解。(主要pycharm不占内存)。

昨天我们已经得到了数学建模的模型,如下:


 max z=4x_{1}+3x_{2}

s.t.\left\{\begin{matrix} 2x_{1}+x_{2}\leq 10,& & & \\ x_{1}+x_{2}\leq 8,& & & \\ x_{2} \leq 7,\\ x_{1},x_{2}\geq 0. \end{matrix}\right.


在这个模型中,我们有一个目标函数(利润函数),两种机床(甲和乙)生产数量的线性组合,同时我们还有一些线性约束条件(比如机器的加工时间限制)且约束条件为不等式约束,所以这个可以用linprog函数来解决这个线性规划问题。

scipy.optimize.linprog 函数适合解决一般形式的线性规划问题,目标函数和约束条件为线性关系和不等式约束形式时可用

现在,我们需要先导入scipy.optimize模块中的linprog函数。这个函数主要是用来解决一个线性规划问题。线性规划是数学中用于在给定的线性等式或不等式约束条件下,求解线性目标函数的最优解(最大值或最小值)的方法。

from scipy.optimize import linprog

我们还需要导入numpy库,为了方便后续调用该库,实现定义目标函数的系数向量和不等式约束的系数矩阵和右侧常数向量。

import numpy as np

做完导库操作后,我们可以下一步,定义目标函数的系数向量,也就是 max z=4x_{1}+3x_{2}的系数。

c = np.array([-4, -3]) 

肯定有人问,为什么这里要取负数而不是取正数,这是因为在 linprog 函数中,它默认解决最小化问题,所以我们用负数来表示最大化问题。也就是说,最后我们只要在算出来的结果,加个负号就是最大值了。

接下来我们开始定义不等式约束的系数矩阵和右侧常数向量,这个A的矩阵就是不等式左边的,b就是不等式右边的,肯定又有同学会问,为什么第三个x_{2}\leq 7有两个系数,你可以当成这样的形式0x_{1}+1x_{2}\leq 7这样的形式。

# 定义不等式约束的系数矩阵和右侧常数向量
A = np.array([[2, 1], [1, 1], [0, 1]])  # 系数矩阵
b = np.array([10, 8, 7])  # 右侧常数向量

我们现在已经求出他的系数矩阵了,接下来定义一下他的变量范围。

# 定义变量的范围(默认为非负)
x_bounds = (0, None)  # x1 >= 0, x2 >= 0

最后,我们开始求解这个模型的解。

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

这里面的c就代表目标函数的系数向量。

b_ub:表示三个不等式约束条件的右侧常数。

bounds: 这是一个元组,用来指定每个变量的边界范围。每个元素都是一个元组,分别表示变量的下界和上界。默认情况下,变量被认为是非负的,因此只需要指定上界即可。在这个例子中,x_bounds = (0, None) 表示两个变量 x1 和 x2 都是非负的。

method: 这是用于求解线性规划问题的特定算法的字符串。在这里,method='highs' 指定了使用 HiGHS 算法来求解。HiGHS 是一个高性能的线性规划求解器。

res: 这是 linprog 函数的返回结果,是一个 OptimizeResult 对象,包含了求解线性规划问题的详细信息。其中包括最优解向量 res.x、最优值 res.fun(因为我们是最大化问题,所以需要取负值 -res.fun 才是最大化的目标函数值)、求解状态、迭代次数等信息。

这上边我巴拉巴拉一大堆,应该还是会有人没看懂,我就简单来说,这个linprog这个函数,会将你传入的系数数组,经过处理,得到,以下形式:


max z=4x_{1}+3x_{2}

s.t.\left\{\begin{matrix} 2x_{1}+x_{2}\leq 10,& & & \\ x_{1}+x_{2}\leq 8,& & & \\ x_{2} \leq 7,\\ x_{1},x_{2}\geq 0. \end{matrix}\right.


你只需要记住,c是传入目标函数的系数向量,A_ub传入的是左侧的不等式约束的系数,b_ub是传入右侧常数,bounds是变量范围,method写不写都行不关事的。

接下来我们开始打印结果。

# 打印结果
print("最大总利润为:", -res.fun)  # 注意要取负值才是原问题的最大化利润
print("甲机床的最优生产数量:", res.x[0])
print("乙机床的最优生产数量:", res.x[1])

为什么最大总利润为负数,原因是在 linprog 函数中,它默认解决最小化问题,所以我们用负数来表示最大化问题,一定要记住。

完整代码如下:

import numpy as np
from scipy.optimize import linprog

# 定义目标函数的系数向量
c = np.array([-4, -3])  # 因为要最大化利润,所以取负值

# 定义不等式约束的系数矩阵和右侧常数向量
A = np.array([[2, 1], [1, 1], [0, 1]])  # 系数矩阵
b = np.array([10, 8, 7])  # 右侧常数向量

# 定义变量的范围(默认为非负)
x_bounds = (0, None)  # x1 >= 0, x2 >= 0

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

# 打印结果
print("最大总利润为:", -res.fun)  # 注意要取负值才是原问题的最大化利润
print("甲机床的最优生产数量:", res.x[0])
print("乙机床的最优生产数量:", res.x[1])

运行结果如下:

如果有啥不懂的可以在评论区评论,如果有错的欢迎指正!

点赞加关注,下期不迷路

  • 17
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值