Skip to main content
 首页 » 编程设计

python之使用 PuLP 进行整数线性优化

2025年05月04日21pengyingh

我必须解决 PuLP 的整数线性优化问题。我解决了这个问题并获得等于 42 的优化值。但是当我编写更通用的代码时,比如在循环内声明变量、在循环内定义约束以及使用 lpSum 函数定义优化,我没有得到解决方案。 我认为我的问题在于定义下一个约束。

for a in itemset_dict.keys(): 
    for b in itemset_dict[a][0]: 
        my_lp_program +=b  >=  a, "2Constraint" 

我收到了下一个警告:

C:\Program Files\Python36\lib\site-packages\pulp\pulp.py:1353: UserWarning: Overwriting previously set objective. 
  warnings.warn("Overwriting previously set objective.") 
Status: Optimal 
Total Optimum= None 
__dummy = None 
products_beer = 0.0 
products_cheese = 0.0 
products_cola = 0.0 
products_peanuts = 0.0 
The thread 'MainThread' (0xb30) has exited with code 0 (0x0). 
The program '[10140] python.exe' has exited with code 0 (0x0). 

谢谢。

      from pulp import * 
 
# defining list of products 
products = ['cola','peanuts', 'cheese', 'beer'] 
itemsets = ['x1','x2', 'x3'] 
 
#disctionary of the costs of each of the products is created 
costs = {'cola' : 5, 'peanuts' : 3, 'cheese' : 1, 'beer' : 4 } 
 
# dictionary of frequent itemsets 
itemset_dict = { "x1" : (("cola", "peanuts"),10), 
           "x2" : (("peanuts","cheese"),20), 
           "x3" : (("peanuts","beer"),30) 
           } 
 
products_var=LpVariable.dicts("Products", products, 0) 
itemsets_var=LpVariable.dicts("Itemsets", itemsets, 0) 
 
# defining itemsets variables 
''' 
for x in itemsets: 
    x = LpVariable('x', lowBound=0, upBound=1, cat='Binary') 
    ''' 
#x = LpVariable.dicts("x", itemsets, lowBound=0, upBound=1, cat='Binary') 
 
 
#option2 
i1=LpVariable.dict("itemsets", itemsets, lowBound=0, upBound=1, cat='Binary')  
#print(i1); 
#print(i1['x1']) 
#print(type(i1['x1'])) 
 
''' 
x1 = LpVariable('x1', lowBound=0, upBound=1, cat='Binary') 
x2 = LpVariable('x2', lowBound=0, upBound=1, cat='Binary') 
x3 = LpVariable('x3', lowBound=0, upBound=1, cat='Binary') 
''' 
 
 
# defining products variables 
''' 
for p in products: 
    p = LpVariable(p, lowBound=0, upBound=1, cat='Binary') 
    ''' 
 
#p = [LpVariable.dicts("p", i, lowBound=0, upBound=1, cat='Binary') for i in products] 
 
''' 
option1 
p=[LpVariable(i, lowBound=0, upBound=1, cat='Binary') for i in products] 
print(p[2]) 
print(type(p[2])) 
''' 
 
 
#option2 
p1=LpVariable.dict("products", products, lowBound=0, upBound=1, cat='Binary')  
#print(p1); 
#print(p1['cola']) 
#print(type(p1['cola'])) 
 
''' 
cola = LpVariable('cola', lowBound=0, upBound=1, cat='Binary') 
peanuts = LpVariable('peanuts', lowBound=0, upBound=1, cat='Binary') 
cheese = LpVariable('cheese', lowBound=0, upBound=1, cat='Binary') 
beer = LpVariable('beer', lowBound=0, upBound=1, cat='Binary') 
''' 
 
 
my_lp_program = LpProblem('My LP Problem', LpMaximize) 
 
#my_lp_program += 10*x1+20*x2+30*x3-5*p1-3*p2-1*p3-4*p4 , "Maximization" 
#my_lp_program += 10*x1+20*x2+30*x3 - lpSum([costs[i] * p1[i] for i in products]) , "Maximization" 
my_lp_program += lpSum([itemset_dict[i][1] * i1[i] for i in itemsets]) - lpSum([costs[i] * p1[i] for i in products]) , "Maximization" 
#my_lp_program += lpSum([itemset_dict[i][1] * itemsets_var[i] for i in itemsets]) - lpSum([costs[i] * products_var[i] for i in products]) , "Maximization" 
 
 
#my_lp_program +=cola+peanuts+cheese+beer<=3, "1Constained" 
 
 
my_lp_program +=lpSum([p1[i] for i in products]) <= 3, "1Constaint" 
 
 
''' 
my_lp_program +=cola>=x1, "2Constained" 
my_lp_program +=peanuts>=x1, "3Constained" 
my_lp_program +=peanuts>=x2, "4Constained" 
my_lp_program +=cheese>=x2, "5Constained" 
my_lp_program +=peanuts>=x3, "6Constained" 
my_lp_program +=beer>=x3, "7Constained" 
''' 
 
 
for a in itemset_dict.keys(): 
    for b in itemset_dict[a][0]: 
        my_lp_program +=b  >=  a, "2Constraint" 
 
 
my_lp_program.writeLP("CheckLpProgram.lp") 
my_lp_program.solve() 
 
print("Status:", LpStatus[my_lp_program.status]) 
 
print("Total Optimum=", value(my_lp_program.objective)) 
 
for v in my_lp_program.variables(): 
    print(v.name, "=", v.varValue) 

请您参考如下方法:

我在这里重写了您的代码,提供了一个可行的解决方案。请查看评论,其中提供了一些关于调试此类模型有用的提示。

from pulp import * 
 
# defining list of products 
products = ['cola','peanuts', 'cheese', 'beer'] 
itemsets = ['x1','x2', 'x3'] 
 
#disctionary of the costs of each of the products is created 
costs = {'cola' : 5, 'peanuts' : 3, 'cheese' : 1, 'beer' : 4 } 
 
# dictionary of frequent itemsets 
# ~~> This is hard to maintain - I would select a different data structure 
# it gets really complicated below as you will see! 
itemset_dict = { "x1" : (("cola", "peanuts"),10), 
           "x2" : (("peanuts","cheese"),20), 
           "x3" : (("peanuts","beer"),30) 
           } 
 
# Good practice to first define your problem 
my_lp_program = LpProblem('My LP Problem', LpMaximize)   
 
# ~~>You do not need bounds for binary variables, they are automatically 0/1 
products_var=LpVariable.dicts("Products", products, cat='Binary') 
itemsets_var=LpVariable.dicts("Itemsets", itemsets, cat='Binary') 
 
# ~~> Not necessary - commended out 
# defining itemsets variables 
# for x in itemsets: 
#     x = LpVariable(x, lowBound=0, upBound=1, cat='Binary') 
 
''' 
x1 = LpVariable('x1', lowBound=0, upBound=1, cat='Binary') 
x2 = LpVariable('x2', lowBound=0, upBound=1, cat='Binary') 
x3 = LpVariable('x3', lowBound=0, upBound=1, cat='Binary') 
''' 
 
# ~~> Not necessary - commended out 
# defining products variables 
# for p in products: 
#     p = LpVariable(p, lowBound=0, upBound=1, cat='Binary') 
 
''' 
cola = LpVariable('cola', lowBound=0, upBound=1, cat='Binary') 
peanuts = LpVariable('peanuts', lowBound=0, upBound=1, cat='Binary') 
cheese = LpVariable('cheese', lowBound=0, upBound=1, cat='Binary') 
beer = LpVariable('beer', lowBound=0, upBound=1, cat='Binary') 
''' 
 
# ~~> Not necessary - commended out, see below 
#my_lp_program += 10*x1+20*x2+30*x3-5*p1-3*p2-1*p3-4*p4 , "Maximization" 
# my_lp_program += lpSum([itemset_dict[i][1] * itemsets_var[i] for i in itemsets]) - lpSum([costs[i] * products_var[i] for i in products]) , "Maximization" 
 
# ~~> Use an affine expression to define your objective. 
# ~~> Even better, define two objects as LpAffineExpression and add them,  
# ~~> it keeps the code cleaner 
my_lp_program += LpAffineExpression([( 
    itemsets_var[x], itemset_dict[x][1])  for x in itemsets_var]) + \ 
    LpAffineExpression([( 
    products_var[x], -costs[x])  for x in products_var]) 
 
# ~~> Not necessary - commended out 
#my_lp_program +=cola+peanuts+cheese+beer<=3, "1Constained" 
# my_lp_program +=lpSum([products_var[i] for i in products]) <= 3, "1Constaint" 
# ~~> This is the right way to enter this constraint. 
# ~~> I do not like the naming though.. 
my_lp_program += lpSum(products_var) <= 3, '1Constraint' 
 
''' 
my_lp_program +=cola>=x1, "2Constained" 
my_lp_program +=peanuts>=x1, "3Constained" 
my_lp_program +=peanuts>=x2, "4Constained" 
my_lp_program +=cheese>=x2, "5Constained" 
my_lp_program +=peanuts>=x3, "6Constained" 
my_lp_program +=beer>=x3, "7Constained" 
''' 
# ~~> Here are your constraints 
counter = 1 
for a in itemset_dict.keys(): 
    item = itemsets_var[a] 
    for b in itemset_dict[a][0]: 
        product = products_var[b] 
        counter +=1 
        my_lp_program += product  >= item, "{}Constraint".format(counter) 
 
# ~~> Great that you export the lp! If you look at the file you can 
# ~~> spot a lot of issues with the model during debugging 
my_lp_program.writeLP("CheckLpProgram.lp") 
my_lp_program.solve() 
 
print("Status:", LpStatus[my_lp_program.status]) 
 
print("Total Optimum=", value(my_lp_program.objective)) 
 
for v in my_lp_program.variables(): 
    print(v.name, "=", v.varValue) 

输出:

('Status:', 'Optimal') 
('Total Optimum=', 42.0) 
('Itemsets_x1', '=', 0.0) 
('Itemsets_x2', '=', 1.0) 
('Itemsets_x3', '=', 1.0) 
('Products_beer', '=', 1.0) 
('Products_cheese', '=', 1.0) 
('Products_cola', '=', 0.0) 
('Products_peanuts', '=', 1.0)