使用混合整数规划限制最大分配大小
Constrain the maximum allocation size using Mixed Integer Programming
我有2个设施,每个都有管道和安装费用。我还有16个客户要服务,每个客户都有服务成本。我想为每个设施分配最多 10 个客户,以使管道成本、安装和服务成本最小化。
我已经实现了以下代码,但它不能正常工作。它应该将每个设施分配给它应该服务的客户数量和 returns 最低成本。但是,输出将水井分配给所有设施(我认为)。
非常感谢您的帮助:
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))
有 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)
最后,您不要 link 变量 use_facility
和 use_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)])
我有2个设施,每个都有管道和安装费用。我还有16个客户要服务,每个客户都有服务成本。我想为每个设施分配最多 10 个客户,以使管道成本、安装和服务成本最小化。
我已经实现了以下代码,但它不能正常工作。它应该将每个设施分配给它应该服务的客户数量和 returns 最低成本。但是,输出将水井分配给所有设施(我认为)。
非常感谢您的帮助:
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))
有 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)
最后,您不要 link 变量 use_facility
和 use_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)])