【问题标题】:Constrain the maximum allocation size using Mixed Integer Programming使用混合整数规划限制最大分配大小
【发布时间】:2018-08-29 02:12:38
【问题描述】:

我有 2 个设施,每个都有管道和安装费用。我还有16个客户需要服务,每个客户都有服务成本。我想为每个设施分配最多 10 个客户,以便将管道、安装和服务成本降至最低。

我已经实现了以下代码,但它不能正常工作。它应该将每个设施分配给它应该服务的客户数量并返回最低成本。但是,输出将井分配给所有设施(我认为)。

非常感谢您的帮助:

import numpy as np
from pulp import *
import random 
CUSTOMERS = range(1,17) ## generate random Customer Ids
FACILITY =['FAC 1','FAC 2'] # Number and Name of Facilities
randomCosts = random.sample(range(90, 100), 2) ## Generate Random Installation Costs 
actcost = dict(zip(FACILITY, randomCosts)) ## Assign installation cost to each facility
randompipelineCost = random.sample(range(5, 20), 2) ## Generate Random pipeline Costs
pipelineCost = dict(zip(FACILITY, randompipelineCost))## Assign pipeline cost to each facility
sizeOfPlatforms = [10,10] ## Size of Platforms
maxSizeOfPlatforms = dict(zip(FACILITY, sizeOfPlatforms)) ## Assign Size to each Facility
serviceRandom=[] 
serviceCosts = {}
for facility in FACILITY: ## Generate Random Service Costs for each customer
   serviceRandom=[]
   for i in range (16):
     serviceRandom.append(random.randrange(1, 101, 1))
   service = dict(zip(CUSTOMERS, serviceRandom))
   serviceCosts[facility]=service

print 'CUSTOMERS', CUSTOMERS
print 'FACILITY', FACILITY
print 'Facility Cost', actcost 
print 'pipeline Cost',pipelineCost 
print 'service Cost', serviceCosts 

prob = LpProblem("FacilityLocation",LpMinimize)


##Decision Variables

use_facility = LpVariable.dicts("UseFacility", FACILITY,0,1,LpBinary)

use_customer = LpVariable.dicts("UseCustomer",[(i,j) for i in CUSTOMERS for j in FACILITY],1)

## Objective Function 

prob += lpSum(actcost[j]*use_facility[j] for j in FACILITY) + lpSum(pipelineCost[j]*use_facility[j] for j in FACILITY)+ lpSum(serviceCosts[j][i]*use_customer[(i,j)] for i in CUSTOMERS for j in FACILITY)

# Constraints 

for j in FACILITY: 
   prob += lpSum(use_customer[(i,j)] for i in CUSTOMERS) <= maxSizeOfPlatforms[j]


for j in FACILITY: 
   prob += lpSum(use_facility[j] for j in FACILITY) <=1.0 ##Constraint 1 

##Solution 

prob.solve() 
print ("Status:", LpStatus[prob.status])

TOL = 0.00001 


## print Decision Variables
for i in FACILITY: 
   if use_facility[i].varValue > TOL:
     print("Establish Facility at Site",i)

for v in prob.variables():
  print(v.name,"=", v.varValue)


##optimal Solution
print ("The cost of production in dollars for one year=", value(prob.objective))

【问题讨论】:

  • 它在做什么,它应该做什么? mcve
  • 谢谢。我更新了问题以包括它应该做什么以及它现在在做什么。

标签: python mathematical-optimization linear-programming pulp mixed-integer-programming


【解决方案1】:

有 4 个不同的问题。

1)

use_customer = LpVariable.dicts("UseCustomer",[(i,j) for i in CUSTOMERS for j in FACILITY],1)

这相当于说每个变量都是小数并且应该大于一。也就是说,您正在设置lowBound=1。我猜你想在这里说变量是二进制的:

use_customer = LpVariable.dicts("UseCustomer",[(i,j) for i in CUSTOMERS for j in FACILITY], cat=LpBinary)

2)

第二个问题是您不限制客户被分配到至少一个设施(至少因为问题是最小化问题并且您的成本严格为正,客户永远不会被分配到多个设施设施,但在下面我将假设完全是一个

for i in CUSTOMERS: 
     prob += lpSum(use_customer[(i,j)] for j in FACILITY) == 1.0 

3)

我不确定你想在这里说什么:

for j in FACILITY: 
   prob += lpSum(use_facility[j] for j in FACILITY) <=1.0 ##Constraint 1 

每次您对所有设施求和并将其值的总和限制为最多为 1。我想这是一个错误。

4)

最后,您不要将变量 use_facilityuse_customer 链接在一起。也就是说,变量use_facility 的值永远不会大于0。由于它是二进制的,我假设use_facility[j] 代表激活成本。因此,您需要添加以激活设施,即 如果至少有一个客户使用设施 j,则会激活它

for j in FACILITY:
    for i in CUSTOMERS:
        prob += use_facility[j] >= lpSum(use_customer[(i,j)])

综合起来:

##Decision Variables

use_facility = LpVariable.dicts("UseFacility", FACILITY, cat=LpBinary)

use_customer = LpVariable.dicts("UseCustomer",[(i,j) for i in CUSTOMERS for j in FACILITY], cat=LpBinary)

## Objective Function 

prob += lpSum(actcost[j]*use_facility[j] for j in FACILITY) + lpSum(pipelineCost[j]*use_facility[j] for j in FACILITY)+ lpSum(serviceCosts[j][i]*use_customer[(i,j)] for i in CUSTOMERS for j in FACILITY)


# Constraints 
for j in FACILITY: 
   prob += lpSum(use_customer[(i,j)] for i in CUSTOMERS) <= maxSizeOfPlatforms[j]

for i in CUSTOMERS: 
   prob += lpSum(use_customer[(i,j)] for j in FACILITY) == 1

for j in FACILITY:
    for i in CUSTOMERS:
        prob += use_facility[j] >= lpSum(use_customer[(i,j)])

【讨论】:

  • 非常感谢,解决了我的问题,并清楚地解释了如何制定约束。
  • @M.Khaled 您应该通过选中答案左侧的框来接受解决您的问题的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-10
  • 2016-07-20
  • 2019-02-02
  • 1970-01-01
  • 1970-01-01
  • 2012-11-10
  • 1970-01-01
相关资源
最近更新 更多