Ошибка "int object not callable" с использованием кода PuLP - PullRequest
3 голосов
/ 10 января 2020

Я только учусь, как работает библиотека PuLP, которая решает линейное программирование. Код, который я использую, был найден здесь: LINK . Он решает следующую задачу оптимизации (в данном случае, используя двоичные переменные x_ {ij}):

enter image description here

Это код из учебника:

import random
import pulp as plp

#Creating random constants for the model's input
n = 10
m = 5
set_I = range(1, n+1)
set_J = range(1, m+1)
c = {(i,j): random.normalvariate(0,1) for i in set_I for j in set_J}
a = {(i,j): random.normalvariate(0,5) for i in set_I for j in set_J}
l = {(i,j): random.randint(0,10) for i in set_I for j in set_J}
u = {(i,j): random.randint(10,20) for i in set_I for j in set_J}
b = {j: random.randint(0,30) for j in set_J}

opt_model = plp.LpProblem(name="Binary Model")


# if x is Binary
x_vars  = {(i,j):
plp.LpVariable(cat=plp.LpBinary, name="x_{0}_{1}".format(i,j)) 
for i in set_I for j in set_J}


# Less than equal constraints
constraints = {j : opt_model.addConstraint(
plp.LpConstraint(
             e=m(a[i,j] * x_vars[i,j] for i in set_I),
             sense=plp.plp.LpConstraintLE,
             rhs=b[j],
             name="constraint_{0}".format(j)))
       for j in set_J}

objective = plp.lpSum(x_vars[i,j] * c[i,j] 
                    for i in set_I 
                    for j in set_J)

# for minimization
opt_model.sense = plp.LpMinimize
opt_model.setObjective(objective)

И я получаю следующую ошибку, которую я не понимаю:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-20-08e33a7305cc> in <module>
     28              rhs=b[j],
     29              name="constraint_{0}"))
---> 30        for j in set_J}
     31 
     32 objective = plp.lpSum(x_vars[i,j] * c[i,j] 

<ipython-input-20-08e33a7305cc> in <dictcomp>(.0)
     28              rhs=b[j],
     29              name="constraint_{0}"))
---> 30        for j in set_J}
     31 
     32 objective = plp.lpSum(x_vars[i,j] * c[i,j] 

TypeError: 'int' object is not callable

1 Ответ

2 голосов
/ 10 января 2020

Ваш код содержит в качестве аргумента plp.LpConstraint следующее:

e=m(a[i,j] * x_vars[i,j] for i in set_I)

m определяется как int, но вызывается как функция. Вместо этого оно должно быть:

e=plp.lpSum(a[i,j] * x_vars[i,j] for i in set_I)

Это является причиной ошибки, и кажется, что это просто опечатка в вашем руководстве. Другая опечатка в том же выражении состоит в том, что plp.plp.LpConstraintLE должно быть просто plp.LpConstraintLE.

После того, как вы исправите эти две ошибки, вы должны быть разблокированы, и продолжение с opt_model.solve() решит модель.


Для решения этой проблемы в целлюлозной среде вы можете найти следующий код, более удобный для чтения, например, с использованием таких замечательных функций, как LpVariable.dicts. Что-то, что мне всегда нравилось в pulp, это то, что код создания модели на самом деле довольно читабелен.

import pulp

### Create n, m, set_I, set_J, c, a, l, u, and b as before

# Model
opt_mod = pulp.LpProblem(name="Binary_model", sense=pulp.LpMinimize)

# Variables from a dictionary
x_vars = pulp.LpVariable.dicts("x", c.keys(), cat=pulp.LpBinary)

# Constraints
for j in set_J:
    opt_mod += pulp.lpSum(a[i,j] * x_vars[i,j] for i in set_I) <= b[j]

# Objective
opt_mod += pulp.lpSum(c[i,j] * x_vars[i,j] for i,j in c)

# Solve
opt_mod.solve()

# Which variables are set?
print([x for x in x_vars if x_vars[x].varValue > 0.999])
...