前言
目录
二、运输问题的解决(农夫种地的问题解决):以下是一个线性规划的例子。我们可以分析得:
一、一般线性规划问题的解决
(1)相关程序编写:
线性规划问题的目标函数及约束条件均为线性函数;约束条件记为 s.t.(即 subject to)。目标函数可以是求最大值,也可以是求最小值,约束条件的不等号可以 是小于号也可以是大于号。
一般线性规划问题的(数学)标准型为
其实线性规划问题主要分为三个方面:目标函数,约束条件已经决策变量,其中如上图所示,max函数就是我们的目标函数,而约束条件也就是我们的s,t函数,而决策变量我们可以得知是Xj,aij,和cj.
而我们又可以得知:
1、每个模型都有若干个决策变量(x1,x2,x3……,xn),其中n为决策变量个数。决策变量的一组值表示一种方案,同时决策变量一般是非负的。
2、目标函数是决策变量的线性函数,根据具体问题可以是最大化(max)或最小化(min),二者统称为最优化(opt)。
3、约束条件也是决策变量的线性函数。
当我们得到的数学模型的目标函数为线性函数,约束条件为线性等式或不等式时称此数学模型的线性规划模型。
所以我们在解决问题的时候只需要分清问题的目标函数,决策变量和约束条件即可。
(2)相关代码编写:
一、python方法解决
from scipy import optimize as op
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 = op.linprog(-c,A,b,Aeq,beq)#-c代表求最大值
print(res)
python运行结果
con: array([1.80714643e-09])
fun: -14.571428565645032
message: 'Optimization terminated successfully.'
nit: 5
slack: array([-2.24616770e-10, 3.85714286e+00])
status: 0
success: True
x: array([6.42857143e+00, 5.71428571e-01, 2.35900788e-10])
#仅关注首行和末行,fun为目标函数最小值,x为最优解
二、matlab中此函数的.m文件
c=[2;3;-5];
a=[-2,5,-1;1,3,1];
b=[-10;12];
aeq=[1,1,1];
beq=7;
x=linprog(-c,a,b,aeq,beq,zeros(3,1))
value=c'*x
编写的相应代码
c=[2;3;1];
a=[1,4,2;3,2,0];
b=[8;6];
[x,y]=linprog(c,-a,-b,[],[],zeros(3,1))
(3)代码分析
[x,fval]=linprog(c,A,b,Aeq,beq,LB,UB,X0,OPTIONS)
op.linprog(c,A,b,Aeq,beq,LB,UB,X0,OPTI
ONS
这是matlab和python在解决线性规划问题时所用到的函数,我们下面来简单解析一下相关变量。
其中c和 x为n 维列向量, A、 Aeq 为适当维数的矩阵,b 、beq为适当维数的列向量。 (Aeq 对应约束条件中等式约束的系数矩阵,A为约不等式约束的系数矩阵)。基本函数形式为 linprog(c,A,b),它的返回值是向量 x的值。LB 和 UB 分别是变量 x的下界和上界, 0 x 是x的初始值, OPTIONS 是控制参数。
比如此题:根据python代码我们可以得知:c为是目标函数的系数矩阵,a为两个不等式(约束条件)的系数矩阵;b是不等式右侧的数值矩阵;aeq为等式的系数矩阵;beq为等式的右侧的数值矩阵。
二、运输问题的解决(农夫种地的问题解决):以下是一个线性规划的例子。我们可以分析得:
(1) 最大化利润就是我们要求的目标函数,
(2)而限制条件有:1.不可以栽种负数的面积 2.种植面积的限制
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'])
运行结果
三、整数线性规划
(这里使用的是分支定界方法)
import numpy
from scipy.optimize import linprog
import sys
import math
#判断是否为整数(当一个值与他的下取整或上取整相差小于1e-6时,为整数)
def judge(L, t=1e-6):
for i in L:
if (i-math.floor(i)) < t or (math.ceil(i)-i) < t:
return False
return True
def intergerpro(c, A, B, Aeq, Beq, t=1.0e-6):
res = linprog(c, A, B, Aeq, Beq)
if not res.success:#整数规划问题不可解时终止分支(定界)
return [sys.maxsize]
if judge(res.x):
bestX = [10000]*len(c)#抄的视频上的代码,意义不明
else:
bestX = res.x
bestVal = sum(x*y for x, y in zip(c, bestX))
if all(((x-math.floor(x)) < t or (math.ceil(x)-x) < t) for x in bestX):
return (bestVal, bestX)#整数解
else:#加约束条件
ind = [i for i, x in enumerate(bestX) if (x-math.floor(x) > t) and (math.ceil(x)-x) > t][0]
newcol1 = [0] * len(A[0])
newcol2 = [0] * len(A[0])
newcol1[ind] = -1#新不等式约束的系数
newcol2[ind] = 1#新不等式约束的系数
newA1 = A.copy()
newA2 = A.copy()
newA1.append(newcol1)#追加新不等式约束系数
newA2.append(newcol2)#追加新不等式约束系数
newB1 = B.copy()
newB2 = B.copy()
newB1.append(-math.ceil(bestX[ind]))#新不等式约束的值
newB2.append(math.floor(bestX[ind]))#新不等式约束的值
r1 = intergerpro(c, newA1, newB1, Aeq, Beq)#分支
r2 = intergerpro(c, newA2, newB2, Aeq, Beq)#分支
if r1[0] < r2[0]:
return r1
else:
return r2
c = [3, 4, 1]#问题方程
A = [[-1, -6, -2],[-2, 0, 0]]#不等式约束的系数
B = [-5, -3]#不等式约束右边的值
Aeq = [[0, 0, 0]]#等式约束(aeq与beq都为0,代表0*x1+0*x2+0*x3=0,因此这里不写这个参数也行)
Beq = [0]#等式约束值
print(intergerpro(c, A, B, Aeq, Beq))
运行结果
Ø 结果:
(8.0, array([2., 0., 2.]))
其中8是目标函数值,2,0,2是三个整数变量的值
四、非线性规划
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((2)) # 初始猜测值
res = minimize(fun(args), x0, method='SLSQP')
print(res.fun)
print(res.success)
print(res.x)