一、线性规划
1.使用scipy库求解线性规划问题
#sicpy
from scipy import optimize
import numpy as np
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)
运行结果
2.使用pulp库求解线性规划问题
#pulp
import pulp
z=[2,3,1]#mubiao函数
a=[[1,4,2],[3,2,0]]#约束
b=[8,6]
m=pulp.LpProblem(sense=pulp.LpMinimize)#确定最大化最小化问题,最大化只要把Min改成Max即可
x=[pulp.LpVariable(f'x{i}',lowBound=0) for i in [1,2,3]]#LpV是x1x2x3字符串实际化放进去 lB下边界
m+=pulp.lpDot(z,x)#定义目标函数,lpDot可以将两个列表的对应位相乘再加和 相当于z[O]*x[O]+z[1]*x[1]+z[2]*x[2]
for i in range(len(a)):#a是二维
m+=(pulp.lpDot(a[i],x)>=b[i])
m.solve()
print(f'优化结果目标结果:{pulp.value(m.objective)}')
print(f'参数取值目标解:{[pulp.value(var) for var in x]}')
运行结果
3.运输问题
import pulp
import numpy as np
from pprint import pprint
def transportation_problem(costs, x_max, y_max):
row = len(costs)
col = len(costs[0])
prob = pulp.LpProblem('Transportation Problem', sense=pulp.LpMaximize)
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]
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)
print(f'最大值为{res["objective"]}')
print('各变量的取值为:')
pprint(res['var'])
结果
二、整数规划
整数规划的模型与线性规划基本相同,只是额外增加了部分变量为整数的约束
整数规划求解的基本框架是分支定界法,首先去除整数约束得到"松弛模型"。使用线性规划的方法求解。
方法一与方法二可以作为以后做整数规划的模板
pulp库:
import pulp
# 参数设置
c = [3,4,1] #目标函数未知数前的系数
A_gq = [[1,6,2],[2,0,0]] # 大于等于式子 未知数前的系数集合 二维数组
b_gq = [5,3] # 大于等于式子右边的数值 一维数组
# 确定最大最小化问题,当前确定的是最小化问题
m = pulp.LpProblem(sense=pulp.LpMinimize)
# 定义三个变量放到列表中 生成x1 x2 x3
x = [pulp.LpVariable(f'x{i}',lowBound=0,cat='Integer') for i in [1,2,3]]
# 定义目标函数,并将目标函数加入求解的问题中
m += pulp.lpDot(c,x) # lpDot 用于计算点积
# 设置比较条件
for i in range(len(A_gq)):# 大于等于
m += (pulp.lpDot(A_gq[i],x) >= b_gq[i])
# 求解
m.solve()
# 输出结果
print(f'优化结果:{pulp.value(m.objective)}')
print(f'参数取值:{[pulp.value(var) for var in x]}')
运行结果
三、非线性规划
# scipy.optimize.minimize(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None)
# 解释:
# fun: 求最小值的目标函数
# x0:变量的初始猜测值,如果有多个变量,需要给每个变量一个初始猜测值。minimize是局部最优的解法
# args:常数值,fun中没有数字,都以变量的形式表示,对于常数项,需要在这里给值
# method:求极值的方法,官方文档给了很多种。一般使用默认
# constraints:约束条件,针对fun中为参数的部分进行约束限制
# 1.计算 1/x+x 的最小值
from scipy.optimize import minimize
import numpy as np
# 计算 1/x+x 的最小值
def fun(args):
a = args
v = lambda x: a / x[0] + x[0]
return v
if __name__ == "__main__":
args = (1) # a
x0 = np.asarray((1.4)) # 初始猜测值
res = minimize(fun(args), x0, method='SLSQP')
print(res.fun)
print(res.success)
print(res.x)
运行结果
# 2.计算 (2+x1)/(1+x2) - 3*x1+4*x3 的最小值 x1,x2,x3的范围都在0.1到0.9之间
from scipy.optimize import minimize
import numpy as np
def fun(args):
a,b,c,d=args
v=lambda x: (a+x[0])/(b+x[1]) -c*x[0]+d*x[2]
return v
def con(args):
# 约束条件 分为eq 和ineq
#eq表示 函数结果等于0 ; ineq 表示 表达式大于等于0
x1min, x1max, x2min, x2max,x3min,x3max = args
cons = ({'type': 'ineq', 'fun': lambda x: x[0] - x1min},\
{'type': 'ineq', 'fun': lambda x: -x[0] + x1max},\
{'type': 'ineq', 'fun': lambda x: x[1] - x2min},\
{'type': 'ineq', 'fun': lambda x: -x[1] + x2max},\
{'type': 'ineq', 'fun': lambda x: x[2] - x3min},\
{'type': 'ineq', 'fun': lambda x: -x[2] + x3max})
return cons
if __name__ == "__main__":
#定义常量值
args = (2,1,3,4) #a,b,c,d
#设置参数范围/约束条件
args1 = (0.1,0.9,0.1, 0.9,0.1,0.9) #x1min, x1max, x2min, x2max
cons = con(args1)
#设置初始猜测值
x0 = np.asarray((0.5,0.5,0.5))
res = minimize(fun(args), x0, method='SLSQP',constraints=cons)
print(res.fun)
print(res.success)
print(res.x)