如何在不使用 exec 的情况下生成 PuLP 变量和约束?

问题描述 投票:0回答:2

我使用 PuLP 库编写了以下 Python 代码,用于使用整数规划公式解决背包问题。我使用字符串生成 LpVariable 命令并添加约束,然后使用 eval 执行它们。有没有办法在不使用 eval 的情况下做到这一点?

from pulp import *

#Knapsack problem

items = input ('Enter the number of items :')

items = int(items)

#print('Enter %d items one by one')

print ('Enter {0} items profit one by one'.format(items))

obj = []
weight = []
knapweight = 0


for i in range(0,items):
    print('Enter {0} item profit : '.format(i+1))
    obj.append(input())

for i in range(0, items):
    print('The profit at {0} is {1}'.format(i, obj[i]))

print ('\nEnter {0} items weights one by one'.format(items))


for i in range(0, items):
    print('Enter {0} item weight'.format(i+1))
    weight.append(input())

for i in range(0, items):
    print('The profit at {0} is {1}'.format(i, weight[i]))

print ('\nEnter the weight of the knapsack :')
knapweight = input()

print ('The weight of the knapsack is : {0}'.format(knapweight))


#generating variables
for i in range(0, items):
    str = 'x{0} = LpVariable("x{1}", cat=\'Binary\')'.format(i+1,i+1)
    print (str)
    exec(str)

prob = LpProblem('Knapsack', LpMaximize)

print ('\nDynamic Generaion\n')

#weight constraint generation
str = "prob += "

for i in range(0, items):
    if i == (items-1):
        str = str + weight[i] + '*x{0}'.format(i+1)
    else:
        str = str + weight[i] + '*x{0}'.format(i+1) + '+'

str = str + '<=' + knapweight
exec(str)
print(str)

#objective function generation
str = "prob += "

for i in range(0, items):
    if i == (items-1):
        str = str + obj[i] + '*x{0}'.format(i+1)
    else:
        str = str + obj[i] + '*x{0}'.format(i+1) + '+'

exec(str)
print(str)

status = prob.solve()
print(LpStatus[status])

print ('\nThe values of the variables : \n')

for i in range(0, items):
    print('x{0} = {1}'.format(i+1, value(eval('x{0}'.format(i+1)))))
python linear-programming pulp
2个回答
5
投票

关键是要认识到拥有一个对象(例如列表或字典中的一个对象)是可以的,但您没有显式地将其绑定到名称。您可以创建一个对象,将其附加到列表中,并且仅将其称为

some_list[2]
。一旦您允许自己获得这种自由,您的代码就会变得更加简单。

这里我对输入进行了硬编码,因为这并不重要:

from pulp import *

objs = [2,3,2,5,3]
weights = [1,2,2,1,3]
knapweight = 5

prob = LpProblem('Knapsack', LpMaximize)
xs = [LpVariable("x{}".format(i+1), cat="Binary") for i in range(len(objs))]

# add objective
total_prof = sum(x * obj for x,obj in zip(xs, objs))
prob += total_prof

# add constraint
total_weight = sum(x * w for x,w in zip(xs, weights))
prob += total_weight <= knapweight

status = prob.solve()
print(LpStatus[status])
print("Objective value:", value(prob.objective))
print ('\nThe values of the variables : \n')
for v in prob.variables():
    print(v.name, "=", v.varValue)

这给了我

Optimal
Objective value: 10.0

The values of the variables : 

x1 = 1.0
x2 = 1.0
x3 = 0.0
x4 = 1.0
x5 = 0.0

这里我正在列表理解中构建 LpVariables

xs = [LpVariable("x{}".format(i+1), cat="Binary") for i in range(len(objs))]

对象就位于列表中

xs

>>> xs
[x1, x2, x3, x4, x5]
>>> xs[3]
x4
>>> type(xs[3])
<class 'pulp.pulp.LpVariable'>

0
投票

相对于我的评论已接受的代码 - 我的版本:

from pulp import *

prob = LpProblem("Knapsack_problem", LpMaximize)

cost = [2,3,2,5,3]
cap = [1,2,2,1,3]
cnt= len(cost);
knapweight = 5

x = LpVariable.dicts('x',range(1,5),lowBound=0,upBound=10,cat=LpInteger)

prob += pulp.lpSum([cost[ix]*x[ix] for ix in range(1,cnt)]), "obj"
prob += pulp.lpSum([cap[ix]*x[ix] for ix in range(1,cnt)]) == knapweight, "c1"
prob.solve()

status = LpStatus[prob.status]
if status == "Optimal":
    for v in prob.variables():
        if v.varValue>0.0001:
            print (v.name, "=", v.varValue)

    print ("objective = %s" % value(prob.objective))
© www.soinside.com 2019 - 2024. All rights reserved.