# 这是一个示例 Python 脚本。
# 按 Shift+F10 执行或将其替换为您的代码。
# 按 双击 Shift 在所有地方搜索类、文件、工具窗口、操作和设置。
from scipy import optimize
import numpy as np
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
c=np.array([2,3,-5])
A=np.array([[-2,5,-1],[1,3,1]])#二维数组两个中括号
B=np.array([-10,12])
Aeq=np.array([[1,1,1]])#约束式都写成二维,一维只有列,二维是行
Beq=np.array([7])
res=optimize.linprog(-c,A,B,Aeq,Beq)
print(res)
print(res.fun)#最小值
print(res.x)#最优解
运行结果
con: array([1.80714554e-09])
fun: -14.571428565645032
message: 'Optimization terminated successfully.'
nit: 5
slack: array([-2.24602559e-10, 3.85714286e+00])
status: 0
success: True
x: array([6.42857143e+00, 5.71428571e-01, 2.35900788e-10])
-14.571428565645032
[6.42857143e+00 5.71428571e-01 2.35900788e-10]
如果你搜别人的方案,会发现是错的,我改了一下,加了等式约束改了求最大值,结果应该是对的。
import pulp
# 1. LpProblem类
# LpProblem(name='NoName', sense=LpMinimize)
# 构造函数,用来构造一个LP问题实例,其中name指定问题名(输出信息用),
# sense值是LpMinimize或LpMaximize中的一个,用来指定目标函数是求极大值还是极小值。
# 2.solve(solver=None, **kwargs)
# 在对LpProblem添加完约束条件后,调用该函数进行求解,如果不是求解特定的整数规划问题,solver一般使用默认即可。
# 3. LpVariable类
# LpVariable(name, lowBound=None, upBound=None, cat='Continuous', e=None)
# 构造函数,用来构造LP问题中的变量,name指定变量名,lowBound和upBound是下界和上界,
# 默认分别是负无穷到正无穷,cat用来指定变量是离散(Integer,Binary)还是连续(Continuous)。
# 4.lpDot
# 可以将两个列表的对应位相乘再相加
# 比如
# pulp.lpDot(z,x)
# z[0]*x[0]+z[1]*x[1]+z[2]*x[2]...
# 目标函数的系数
z = [2, 3, 1]
# 约束eq表示等式的意思a是左b是右
a = [[1, 4, 2], [3, 2, 0]]
b = [8, 6]
eqa = [1, 2, 4]
eqb = [101]
# 确定最大化最小化问题,最大化只要把Min改成Max即可
m = pulp.LpProblem(sense=pulp.LpMaximize)
# 定义三个变量x1,x2,x3放到列表中,下界为0,
x = [pulp.LpVariable(f'x{i}', lowBound=0) for i in [1, 2, 3]]
# 定义目标函数,m是z和x对应相乘再相加
m += pulp.lpDot(z, x)
# 设置约束条件len(a)是2,下面表示第i行的a乘以X(x1,x2,x3)≥第i行的b,是不等式约束
for i in range(len(a)):
m += (pulp.lpDot(a[i], x) >= b[i])
m += pulp.lpDot(eqa, x) == eqb
# 求解
m.solve()
# 输出结果
print(f'优化结果:{pulp.value(m.objective)}')
print(f'参数取值:{[pulp.value(var) for var in x]}')
运行结果
优化结果:202.0
参数取值:[101.0, 0.0, 0.0]
下一个例题运输问题
数学规划学过
import pulp
import numpy as np
from pprint import pprint
#定义的函数,x_max是对行的约束,y_max是对列的约束
def transportation_problem(costs, x_max, y_max):
#行数
row = len(costs)
#列数
col = len(costs[0])
#最大值问题
prob = pulp.LpProblem('Transportation Problem', sense=pulp.LpMaximize)
#二维列表xij,i是x_max,j是y_max
var = [[pulp.LpVariable(f'x{i}{j}', lowBound=0, cat=pulp.LpInteger) for j in range(col)] for i in range(row)]
#作用是把列表展开成一维的,相当于定义了一个函数
flatten = lambda x: [y for l in x for y in flatten(l)] if type(x) is list else [x]
#这里调用了上一行写的flatten把var展开成一维,然后再对应相乘,至于cost的flatten是自带的
prob += pulp.lpDot(flatten(var), costs.flatten())
#添加不等式约束
for i in range(row):
prob += (pulp.lpSum(var[i]) <= x_max[i])
for j in range(col):
prob += (pulp.lpSum([var[i][j] for i in range(row)]) <= y_max[j])
prob.solve()
return {'objective': pulp.value(prob.objective),
'var': [[pulp.value(var[i][j]) for j in range(col)] for i in range(row)]}
if __name__ == "__main__":
costs = np.array([[500, 550, 630, 1000, 800, 700],
[800, 700, 600, 950, 900, 930],
[1000, 960, 840, 650, 600, 700],
[1200, 1040, 980, 860, 880, 780]])
max_plant = [76, 88, 96, 40]
max_cultivation = [42, 56, 44, 39, 60, 59]
res = transportation_problem(costs, max_plant, max_cultivation)
#objective是最优解,var是x的值
print(f'最大值为{res["objective"]}')
print('各变量的取值为:')
pprint(res['var'])
运行结果
最大值为284230.0
各变量的取值为:
[[0.0, 0.0, 6.0, 39.0, 31.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 29.0, 59.0],
[2.0, 56.0, 38.0, 0.0, 0.0, 0.0],
[40.0, 0.0, 0.0, 0.0, 0.0, 0.0]]