Python 使用混合整数规划约束最大分配大小

Python 使用混合整数规划约束最大分配大小,python,mathematical-optimization,linear-programming,pulp,mixed-integer-programming,Python,Mathematical Optimization,Linear Programming,Pulp,Mixed Integer Programming,我有2个设施,每个都有管道和安装费用。我还有16个客户需要服务,每个客户都有服务成本。我希望为每个设施分配最多10个客户,以便将管道、安装和服务成本降至最低 我已经实现了以下代码,但它不能正常工作。它应该将每个设施分配给它应该服务的客户数量,并返回最低成本。然而,产量将油井分配给所有设施(我认为) 非常感谢您的帮助: import numpy as np from pulp import * import random CUSTOMERS = range(1,17) ## generate r

我有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))
将numpy导入为np
从纸浆进口*
随机输入
客户=范围(1,17)##生成随机客户ID
设施=['FAC 1','FAC 2']#设施编号和名称
随机成本=随机。样本(范围(90100),2)##生成随机安装成本
actcost=dict(zip(设施,随机成本))35;#为每个设施分配安装成本
随机管道成本=随机。样本(范围(5,20),2)##生成随机管道成本
管道成本=dict(zip(设施,随机管道成本))35;#为每个设施分配管道成本
SizeOffplatforms=[10,10]##平台尺寸
MaxSizeOffplatforms=dict(zip(设施,SizeOffplatforms))35;#为每个设施分配大小
serviceRandom=[]
服务成本={}
对于设施中的设施:##为每个客户生成随机服务成本
serviceRandom=[]
对于范围(16)中的i:
serviceRandom.append(random.randrange(1101,1))
服务=dict(zip(客户、服务随机))
服务成本[设施]=服务
打印“客户”,客户
打印“设施”,设施
打印“设施成本”,实际成本
打印“管道成本”,管道成本
打印“服务成本”,服务成本
prob=LpProblem(“设施定位”,lp最小化)
##决策变量
use_facility=LpVariable.dicts(“usefcility”,facility,0,1,LpBinary)
use_customer=LpVariable.dicts(“UseCustomer”,[(i,j)代表i,代表j,代表j,1)
##目标函数
prob+=lpSum(实际成本[j]*使用_设施[j]用于j in设施)+lpSum(管道成本[j]*使用_设施[j]用于j in设施)+lpSum(服务成本[j][i]*使用_客户[(i,j)]用于i in客户用于j in设施)
#约束条件
对于j in设施:

prob+=lpSum(使用_customer[(i,j)]表示客户中的i)有4个不同的问题

(一)

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

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

第二个问题是,您没有约束客户至少被分配到一个设施(至少因为该问题是一个最小化问题,并且您的成本是严格正的,所以客户永远不会被分配到多个设施,但在下面我将假设正好是一个)

(三)

我不确定你是否理解了你在这里想说的话:

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

##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)])
决策变量 use_facility=LpVariable.dicts(“usefcility”,facility,cat=LpBinary) 使用_customer=LpVariable.dicts(“使用客户”,[(i,j)代表客户中的i代表工厂中的j],cat=LpBinary) ##目标函数 prob+=lpSum(实际成本[j]*使用_设施[j]用于j in设施)+lpSum(管道成本[j]*使用_设施[j]用于j in设施)+lpSum(服务成本[j][i]*使用_客户[(i,j)]用于i in客户用于j in设施) #约束条件 对于j in设施: prob+=lpSum(使用客户[(i,j)]表示客户中的i)=lpSum(使用客户[(i,j)])
它在做什么?它应该做什么?谢谢我更新了问题,包括它应该做什么以及它现在正在做什么。非常感谢,解决了我的问题,并向我明确解释了如何制定约束。@M.Khaled您应该接受一个答案,该答案通过选中答案左侧的框解决了您的问题。
for j in FACILITY: 
   prob += lpSum(use_facility[j] for j in FACILITY) <=1.0 ##Constraint 1 
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)])