python调用开源求解器scip求解运输问题

运输问题

运输问题(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文件
    在这里插入图片描述
  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值