运输问题
运输问题(transportation problem)一般是研究把某种商品从若干产地运至若干个销地而使总运费最小的一类问题。一种特殊的线性规划问题,由于其技术系数矩阵具有特殊的结构,可以使用表上作业法高效求解;
-
产销平衡的运输问题总是存在可行解
-
产销不平衡:
-
产大于销:增加虚拟销地,销量为产销之差,并设置单位运价为0
-
产小于销:增加虚拟产地,产量为销产之差,并设置单位运价为0
-
表上作业法
-
表上作业法是单纯形法在求解运输问题时的一种简化方法, 其实质是单纯形法
-
计算步骤:
1)找出初始基可行解(最小元素法、伏格尔法)。即在( m× n) 产销平衡表上给出 m + n - 1 个数字格。
2)求各非基变量的检验数, 即在表上计算空格的检验数,判别是否达到最优解(闭回路法、位势法)。如
已是最优解,则停止计算, 否则转到下一步。
3)确定换入变量和换出变量, 找出新的基可行解。在表上用闭回路法调整。
4) 重复( 2) , ( 3) 直到得到最优解为止。
python调用scip求解案例
from pyscipopt import *
import numpy as np
model = Model()
# 生成测试数据
product = {'1': 45, '2': 120, '3': 95} # key: 生产地编号 value: 对应的产量
sales = {'1': 80, '2': 78, '3': 47, '4': 55} # key: 销售地编号 value:对应的需求量
# 物流运输成本
cost = np.array([[250, 420, 380, 280],
[1280, 990, 1440, 1520],
[1550, 1420, 1660, 1730]])
product_num = len(product)
sales_num = len(sales)
# 添加变量
# x{i}{j} 代表产地i 到销地j的运输量
x = {}
for i in range(1, product_num + 1):
for j in range(1, sales_num + 1):
x[str(i) + str(j)] = model.addVar(vtype='I', name='x' + str(i) + str(j))
# 添加约束
# 以供销平衡为例,如供销不平衡,则添加虚拟销地或者产地,作为松弛变量
# 3个生产地,运输量等于产量
for i in range(1, product_num + 1):
model.addCons(quicksum(x[str(i) + str(j)] for j in range(1, sales_num + 1)) == product[str(i)])
# 4个销售地,运输量等于需求量
for j in range(1, sales_num + 1):
model.addCons(quicksum(x[str(i) + str(j)] for i in range(1, product_num + 1)) == sales[str(j)])
# 添加目标
model.setObjective(quicksum(x[str(i) + str(j)] * cost[[i-1], [j-1]] for i in range(1, product_num + 1) for j in range(1, sales_num + 1)))
model.setMinimize()
model.writeProblem('problem.lp')
model.optimize()
print('min cost = ', model.getObjVal())
for i in range(1, product_num + 1):
for j in range(1, sales_num + 1):
print('x' + str(i) + str(j), '=',model.getVal(x[str(i) + str(j)]))
- 打印结果
- lp文件