如何在Gurobi中正确实现成本最小化目标功能?

时间:2019-03-25 04:09:09

标签: python linear-programming gurobi

将超市从三个配送中心到十个单独商店的运输单价指定为运费。

注意:请查看我的代码的#data部分,以查看不允许以照片形式发布的数据。还请注意,虽然我的费用是包含30个条目的向量。每个配送中心只能获取10个费用。因此,DC1成本=条目1-10,DC2成本=条目11-20等。


我希望根据十个商店的需求(以交付单位为准)中的每一个来使运输成本最小化。

这可以通过检查来完成。最低费用为$ 150313。问题是使用Python和Gurobi实现解决方案并产生相同的结果。


到目前为止,我所尝试的只是一个有点草率的问题模型。我不确定如何正确索引和遍历产生结果所需的集合。

这是我的主要问题:我定义的用于最小化运输成本的目标函数不正确,因为我会产生非答案。

虽然代码“运行”。如果我转向最大化,我只会遇到一个无穷的问题。因此,我觉得我绝对不会通过设置调用正确的数据/迭代。

到目前为止,我的解决方案很小,所以我觉得我可以将其格式化为问题并进行评论。

from gurobipy import *

#Sets
Distro = ["DC0","DC1","DC2"]
Stores = ["S0", "S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9"]
D = range(len(Distro))
S = range(len(Stores))

在这里,我定义了我的配送中心和商店集。我不确定在何处或如何准确定义DS迭代变量以获取正确答案。


#Data
Demand  = [10,16,11,8,8,18,11,20,13,12]
Costs = [1992,2666,977,1761,2933,1387,2307,1814,706,1162,
           2471,2023,3096,2103,712,2304,1440,2180,2925,2432,
           1642,2058,1533,1102,1970,908,1372,1317,1341,776]

只是我的一些相关数据。考虑到每个配送中心只能访问10个成本而不是30个成本,我不确定我的成本数据是否应该是3个单独的集合。或者是否有办法将我的成本保持为一组,但要确保每个中心只能访问成本与自身相关,我不知道。

m = Model("WonderMarket")
#Variables
X = {}
for d in D:
    for s in S:
        X[d,s] = m.addVar()

声明我的目标变量。再次,我在这一点上盲目地迭代以产生某种效果。我以前从未编程过。但是我正在学习,并尽可能多地考虑这个问题。

#set objective
m.setObjective(quicksum(Costs[s] * X[d, s] * Demand[s] for d in D for s in S), GRB.MINIMIZE)

我的目标职能是根据商店的需求,尝试将从中心到商店的每次交付成本相乘,然后使最小值变为可能。我还没有非零约束。我最终需要一个吗?但是现在我要炸更大的鱼。

m.optimize()

我生成一个0行,30列,具有0个非零条目模型,该模型为我提供了0的解决方案。我需要设置程序,以便获得可以手动计算的值。我认为问题在于我对变量的一般性声明以及对迭代的了解不足,以及一般性的“问题所在”。只是为了学习练习需要很多思考!

感谢所有通读本书的人。感谢您提供任何提示或帮助。

1 个答案:

答案 0 :(得分:1)

您的目标为0,因为您尚未定义任何约束。默认情况下,所有变量的下限均为0,因此,为解决无约束问题,将所有变量都置于该下限。

一些评论:

除非您需要配送中心和商店的名称,否则可以按以下方式定义它们:

D = 3
S = 10
Distro = range(D)
Stores = range(S)

您可以将费用定义为二维数组,例如

Costs = [[1992,2666,977,1761,2933,1387,2307,1814,706,1162],
       [2471,2023,3096,2103,712,2304,1440,2180,2925,2432],
       [1642,2058,1533,1102,1970,908,1372,1317,1341,776]]

然后,从配送中心d到商店s的运输成本存储在Costs[d][s]中。

您可以一次添加所有变量,我假设您希望它们是二进制的:

X = m.addVars(D, S, vtype=GRB.BINARY)

(如果需要使用名称,也可以使用DistroStores代替DS

您对目标函数的定义将变为:

m.setObjective(quicksum(Costs[d][s] * X[d, s] * Demand[s] for d in Distro for s in Stores), GRB.MINIMIZE)

(这全部假设每个商店只能从一个配送中心发货,但是由于您的配送中心没有最大的运力,这似乎是一个公平的假设。)

您需要一些约束来确保实际满足商店的需求。为此,足以确保每个商店都是从一个配送中心交付的,即对于每个s,每个X[d, s]都是1。

m.addConstrs(quicksum(X[d, s] for d in Distro) == 1 for s in Stores)

当我对此进行优化时,我的确得到了值为150313的最优解决方案。