我正在编写代码,以解决管道数量的直径尺寸的最佳组合。目标功能是找到六个管道中的最小压降总和。
因为我有15种离散直径选择,它们可以用于[2,4,6,8,12,16,20,24,30,36,40,42,50,60,80]我在系统中拥有的六个管道中的任何一个,可能的解决方案列表都变为15 ^ 6,等于11,390,625
为解决此问题,我使用了使用Pulp软件包的混合整数线性编程。我能够找到相同直径的组合的解决方案(例如[2,2,2,2,2,2,2]或[4,4,4,4,4,4,4]),但我需要做的是通过所有组合(例如[2,4,2,2,4,2]或[4,2,4,2,4,2]来找到最小值。我尝试这样做,但是过程花费了很长时间进行所有组合的时间。有没有更快的方法?
请注意,我无法计算每个管道的压降,因为直径的选择会影响系统中的总压降。因此,我随时都需要计算系统中每种组合的压降。
我还需要约束该问题,以使管道面积的比率/横截面>2。
非常感谢您的帮助。
我的代码的第一次尝试如下:
from pulp import *
import random
import itertools
import numpy
rate = 5000
numberOfPipelines = 15
def pressure(diameter):
diameterList = numpy.tile(diameter,numberOfPipelines)
pressure = 0.0
for pipeline in range(numberOfPipelines):
pressure += rate/diameterList[pipeline]
return pressure
diameterList = [2,4,6,8,12,16,20,24,30,36,40,42,50,60,80]
pipelineIds = range(0,numberOfPipelines)
pipelinePressures = {}
for diameter in diameterList:
pressures = []
for pipeline in range(numberOfPipelines):
pressures.append(pressure(diameter))
pressureList = dict(zip(pipelineIds,pressures))
pipelinePressures[diameter] = pressureList
print 'pipepressure', pipelinePressures
prob = LpProblem("Warehouse Allocation",LpMinimize)
use_diameter = LpVariable.dicts("UseDiameter", diameterList, cat=LpBinary)
use_pipeline = LpVariable.dicts("UsePipeline", [(i,j) for i in pipelineIds for j in diameterList], cat = LpBinary)
## Objective Function:
prob += lpSum(pipelinePressures[j][i] * use_pipeline[(i,j)] for i in pipelineIds for j in diameterList)
## At least each pipeline must be connected to a diameter:
for i in pipelineIds:
prob += lpSum(use_pipeline[(i,j)] for j in diameterList) ==1
## The diameter is activiated if at least one pipelines is assigned to it:
for j in diameterList:
for i in pipelineIds:
prob += use_diameter[j] >= lpSum(use_pipeline[(i,j)])
## run the solution
prob.solve()
print("Status:", LpStatus[prob.status])
for i in diameterList:
if use_diameter[i].varValue> pressureTest:
print("Diameter Size",i)
for v in prob.variables():
print(v.name,"=",v.varValue)
这是我花了很长时间为组合部分做的。
xList = np.array(list(itertools.product(diameterList,repeat = numberOfPipelines)))
print len(xList)
for combination in xList:
pressures = []
for pipeline in range(numberOfPipelines):
pressures.append(pressure(combination))
pressureList = dict(zip(pipelineIds,pressures))
pipelinePressures[combination] = pressureList
print 'pipelinePressures',pipelinePressures
答案 0 :(得分:2)
我会遍历所有组合,我想您会遇到内存问题,否则会尝试在MIP中为所有组合建模。
如果您遍历问题,也许使用多处理库来使用所有内核,那应该花很长时间,只记得只保存到目前为止的最佳组合信息,而不是一次又一次尝试生成所有组合评估他们。
如果问题变得更大,则应考虑使用动态编程算法或将纸浆用于色谱柱生成。