规划类模型(线性规划、整数规划、非线性规划)
线性规划
1.1 scipy库解决(参考自https://www.bilibili.com/video/BV12h411d7Dm?p=4)详见第二个网址
Scipy是一个用于数学、科学、工程领域的常用软件包,可以处理插值、积分、优化、图像处理、常微分方程数值解的求解、信号处理等问题。
方法:
from scipy import optimize
import numpy as np
#求解函数
res = # res表示对象
optimize.linprog(c, A, b, Aeq, beq, LB, UB, X0, OPTIONS)
# c表示有多少个自变量;A表示不等式约束条件;b表示小于等于右边的部分,如果是大于等于,那么就添负号转向;Aeq beq为等式约束,运输问题和指派问题Aeq较多,资源调配问题,资源统筹问题结合经济A偏多;LB UB为对自变量的约束;X0为给定的初始位置;OPTIONS为参数设置
#目标函数最小值
print(res.fun)
#最优解
print(res.x)
示例
算法:
# scipy函数求解
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)
pulp求解
pulp.LpProblem是定义问题的构造函数
pulp.LpVariable 是定义决策变量的函数(参数 lowBound、upBound 用来设定决策变量的下界、上界;可以不定义下界/上界,默认的下界/上界是负无穷/正无穷。)
添加目标函数使用 "问题名 += 目标函数式" 格式。
pulp.
示例
# pulp函数求解
import pulp
# 目标函数的系数
z = [2,3,1]
# 约束
a = [[1.4,2],[3,2,0]]
b = [8,6]
m = pulp.LpProblem(sense = pulp.LpMinimize)
# 定义三个变量到列表中
x = [pulp.LpVariable(f'x{i}', lowBound = 0) for i in [1,2,3]]
m += pulp.lpDot(z,x)
for i in range(len(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]}')
运输问题
示例
算法
#运输问题
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 Problen', 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)]
# j在列循环上,i在行循环上,中间放了对象,名字为x{i}{j},lowBound设置下界,就不用写对自变量的约束了
flatten = lambda x: [y for l in x for y in flatten(l)] if type(x) is list else [x]
# lambda 可把多维数组转换成一维,把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'])
整数规划
部分变量为整数。
用分支定界法,去除整数约束得到松弛模型,再分支:在松弛模型上分别添加约束,再分别求解。所有变量都是整数时,停止分支。定界:叶子节点产生后,给问题定了下界,求解过程中一旦某个结点的目标函数值小于这个下界,就直接PASS。
lamdba函数
一种小的匿名函数,可以接受任意数量的参数,但只能有一个表达式。
语法:
lamdba arguments:expression
详见https://www.w3school.com.cn/python/python_lambda.asp
非线性规划
目标函数为凸函数或者非凸函数
凸函数可用库cvxpy
非凸函数可用 :
1.纯数学方法,求导求极
2.神经网络、深度学习(反向传播算法中链式求导过程)
3.scipy.optimize.minimize