FelipeMedLev
FelipeMedLev

Reputation: 57

"int object is not callable" error using PuLP code

I'm just learning how the PuLP library works, which is a linear programming solver. The code I'm using was found here: LINK. It solves the following optimization problem (in this case, using binary variables x_{ij}):

enter image description here

This is the code from the tutorial:

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)

And I'm getting the following error that I don't understand:

---------------------------------------------------------------------------
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

Upvotes: 3

Views: 611

Answers (1)

josliber
josliber

Reputation: 44340

Your code contains the following as an argument to plp.LpConstraint:

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

m is defined as an int, but is being called as a function. It should instead be:

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

This is the cause of the error, and appears to just be a typo in your guide. Another typo in the very same expression is that plp.plp.LpConstraintLE should just be plp.LpConstraintLE.

Once you clean up those two errors, you should be unblocked, and continuing with opt_model.solve() will solve the model.


You might find the following to be more readable code to work with to solve this problem in pulp, for instance using nice pulp features like LpVariable.dicts. Something I've always liked about pulp is that the model creation code is actually pretty readable.

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])

Upvotes: 2

Related Questions