Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
混合整数规划-仓库位置(Python+;GLPK)_Python_Optimization_Linear Programming_Glpk - Fatal编程技术网

混合整数规划-仓库位置(Python+;GLPK)

混合整数规划-仓库位置(Python+;GLPK),python,optimization,linear-programming,glpk,Python,Optimization,Linear Programming,Glpk,我在优化方面相对较新,我正在尝试优化一个关于仓库位置的问题(来自Coursera的pas课程,2年前)。问题是,它已经运行了6个多小时,并且仍然在一个拥有100个仓库和1000个客户的实例上运行 问题如下。我有一套仓库,我可以打开也可以不打开。打开每一个都有成本。而且,它们都有一个最大容量,cap_w。 另一方面,有一组客户机,所有客户机都必须连接到一个(并且只有一个)开放仓库。他们每个人都有一个需求d_c,对于每个客户,每个仓库t_wc都有一个运输成本。 很明显,我想要的是使总成本最小化 因此

我在优化方面相对较新,我正在尝试优化一个关于仓库位置的问题(来自Coursera的pas课程,2年前)。问题是,它已经运行了6个多小时,并且仍然在一个拥有100个仓库和1000个客户的实例上运行

问题如下。我有一套仓库,我可以打开也可以不打开。打开每一个都有成本。而且,它们都有一个最大容量,cap_w。 另一方面,有一组客户机,所有客户机都必须连接到一个(并且只有一个)开放仓库。他们每个人都有一个需求d_c,对于每个客户,每个仓库t_wc都有一个运输成本。 很明显,我想要的是使总成本最小化

因此,我有一个数组,其大小等于仓库总数x。每个x[w]是一个整数{0,1},定义仓库w是否打开。 我还有一个0和1的矩阵,定义了哪个仓库交付给每个客户。因此,行数与客户数相同,列数与仓库数相同。这个矩阵叫做y。如果waregouse w交付客户c,则y[c][w]为1,否则为0

到目前为止还不错。这被认为是一个MIP问题。 为了编写代码,我使用PuPL lib()和GLPK在Python中解决它

现在,这是我的模型:

#!/usr/bin/python
# -*- coding: utf-8 -*-

from pulp import *

def solveIt(inputData):

# parse the input
lines = inputData.split('\n')

parts = lines[0].split()
warehouseCount = int(parts[0])
customerCount = int(parts[1])

warehouses = []
for i in range(1, warehouseCount+1):
    line = lines[i]
    parts = line.split()
    warehouses.append((int(parts[0]), float(parts[1])))

customerDemands = []
customerCosts = []

lineIndex = warehouseCount+1
for i in range(0, customerCount):
    customerDemand = int(lines[lineIndex+2*i])
    customerCost = map(float, lines[lineIndex+2*i+1].split())
    customerDemands.append(customerDemand)
    customerCosts.append(customerCost)



x = [LpVariable("x"+str(w),0,1,cat='Integer') for w in range(0,warehouseCount)]
y = [[LpVariable("y"+str(c)+","+str(w),0,1,cat='Integer') for w in range(0,warehouseCount)] for c in range(0,customerCount)]

prob = LpProblem("Warehouse Location",LpMinimize)

#Constraints
# y_cw <= x_w makes sure that no client is delivered by a closed warehouse
for w in range(0,warehouseCount):
    for c in range(0,customerCount):
        prob += y[c][w] <= x[w]

#A client is served by exactly one warehouse
for c in range(0,customerCount):
    affineExpression = []
    for w in range(0,warehouseCount):
        affineExpression.append((y[c][w],1))
    prob += LpAffineExpression(affineExpression) == 1

#For each warehouse, the sum of demand of all the clients it serves is lower than its capacity
for w in range(0,warehouseCount):
    affineExpression = []
    for c in range(0,customerCount):
        affineExpression.append((y[c][w],customerDemands[c]))
    prob += LpAffineExpression(affineExpression) <= warehouses[w][0]

#Objective
#The sum of all the warehouses opening plus the transportation costs has to be minimal
affineExpression = []
for w in range(0,warehouseCount):
    affineExpression.append((x[w],warehouses[w][1]))
    for c in range(0,customerCount):
        affineExpression.append((y[c][w],customerCosts[c][w]))

prob += LpAffineExpression(affineExpression)

print "#######################START SOLVING"
status = prob.solve(GLPK(mip=1,msg = 1))
print LpStatus[status]
for w in range(0,warehouseCount):
    print value(x[w])

solution = []
for c in range(0,customerCount):
    string = ""
    whichOne = -1
    for w in range(0,warehouseCount):
        string += str(value(y[c][w])) + " "
        if value(y[c][w]) == 1:
            whichOne = w
            solution.append(w)
    print string+ "   "+str(whichOne)


# calculate the cost of the solution
obj = sum([warehouses[x][1]*x[w] for x in range(0,warehouseCount)])
for c in range(0, customerCount):
    obj += customerCosts[c][solution[c]]

# prepare the solution in the specified output format
outputData = str(obj) + ' ' + str(0) + '\n'
outputData += ' '.join(map(str, solution))

return outputData
我相信这意味着它解决了LP,现在它得到了整数。。。但这已经有6个小时左右了,而且一直在进步,现在仍然如此,但还没有结束。 在较小的情况下,它运行良好

我想我的问题是。。。我的模型有问题吗?我忘记了一些优化?还是这个问题就那么大

此外,关于计算机,它是一个相当差的:英特尔原子和1GB的内存只有

谢谢你的帮助

编辑: 日期如下: 格式为:

NumberOfWarehouses NumberOfCustomers
CapacityWarehouse1 OpeningCostWarehouse1
CapacityWarehouse2 OpeningCostWarehouse2
.....
CapacityWarehouseN OpeningCostWarehouseN
DemandCustomer1
TransportCostW1_C1 TransportCostW2_C1 ....... TransportCostWN_C1
DemandCustomer2
TransportCostW1_C2 TransportCostW2_C2 ....... TransportCostWN_C2
.....
DemandCustomerN
TransportCostW1_CM TransportCostW2_CM ....... TransportCostWN_CM

这实际上并不是一个大问题——有专门的代码来解决比这个更大的仓库位置实例,像CPLEX这样的现成的解决方案也可以很容易地解决这个问题。我不知道GLPK/PuPL的效率有多高,但很可能是它们使用简单的LP/branch和bound花费了太长的时间(这就是它们所做的)


您可以尝试的一件事是允许y变量是连续的(0输入数据是什么?这实际上是一个很大的问题(就变量的数量而言)我怀疑glpk在这里是否有效。你可以试着选择一组仓库打开,看看glpk需要多长时间才能找到最佳的客户分配到仓库。对于这种规模的问题,我也会尝试本地搜索。您好,谢谢您的回答。事实上,数据文件太大了,我无法发布它在Stackoverlow上…这里有上传文件的方法吗?谢谢,我也考虑过本地搜索…但我不确定怎么做。尝试所有仓库组合(这里100!)对于每次尝试分配客户和本地尝试导入每个客户或类似的东西?容量限制实际上是使我感到困难的因素…我个人。再次感谢!!我看到的一个解算器使用满足的MIP限制的数量作为评分函数。本地搜索是通过选择一个约束来执行的不是,考虑该约束中的每个变量,并确定如果该变量被翻转,分数将如何变化。然后,您进行基本爬山-也许是随机向后移动以离开局部极大值等,或者可能使用Obj.Fulk+C*约束数作为评分函数。你能说这更像是解算器的错误而不是模型吗?我只能尝试GLPK…这是我安装的唯一一个…我尝试将y变量变成现实,但它似乎没有改善,它已经工作了2个多小时,还没有结束。我也认为它应该使它更快,但实际上似乎没有改善太多。。.谢谢!这个模型对我来说似乎是正确的(虽然我没有仔细检查)。至于这是否是解算器的“错误,”我想这是主观的——解算器没有做错任何事情,对于这样的解算器来说,这只是一个难题。如果你愿意接受好的但不是最优的解决方案,这个问题有很好的启发式方法。如果你愿意做一些编码,还有其他很好的精确算法。
NumberOfWarehouses NumberOfCustomers
CapacityWarehouse1 OpeningCostWarehouse1
CapacityWarehouse2 OpeningCostWarehouse2
.....
CapacityWarehouseN OpeningCostWarehouseN
DemandCustomer1
TransportCostW1_C1 TransportCostW2_C1 ....... TransportCostWN_C1
DemandCustomer2
TransportCostW1_C2 TransportCostW2_C2 ....... TransportCostWN_C2
.....
DemandCustomerN
TransportCostW1_CM TransportCostW2_CM ....... TransportCostWN_CM