''TempConstr' object is not iterable

Hoping someone could point me in the direction of the error in the following code. I am trying to minimise the overall cost of taking a survey but am having loads of errors pop up.

N_investors = 2000
groups = [1,2,3,4]
telephone = pd.Series([15, 12, 20, 18], index = groups)
personal = pd.Series([35, 30, 50, 40], index = groups)
methods = [1,2] #1 is telephone #2 is personal

mod = gp.Model('Gladstone')
mod.setParam('LogToConsole', 0)
mod.setParam('OutputFlag', 0)
    
   #Add variables
x = mod.addVars([(i,j)for i in groups for j in methods], lb=0, vtype=GRB.CONTINUOUS) #the total number of people being surveyed in group i by method j
g = mod.addVars(groups, lb=0, vtype=GRB.CONTINUOUS, name = 'g') #the number of people being surveyed in group i
y = mod.addVars(methods, lb=0, vtype=GRB.CONTINUOUS, name = 'y') #the number of people getting surveyed by method j
    
mod.addConstr( (g[1] + g[2]) >= 0.5 * (gp.quicksum(x[i,j] for j in methods for i in groups)))
    
mod.addConstr(y[2] >= (0.25 * (gp.quicksum(x[i,j] for j in methods for i in groups))))
                     
mod.addConstr((g[2] + g[4]) <= 0.4 *(gp.quicksum(x[i,j] for j in methods for i in groups)))
    
mod.addConstrs((g[i] for i in groups >= 0.1 * (gp.quicksum(x[i,j] for j in methods for i in groups))))
                                              
mod.addConstrs((g[i] for i in groups <= 0.5 * (gp.quicksum(x[i,j] for j in methods for i in groups))))                  
                               
mod.addConstrs((gp.quicksum(x[i,j]for i in groups for j in methods) == N_investors))
                       
mod.addConstrs(((g[i] for i in groups) + (y[j] for j in methods)) == x[i,j] for i in groups for j in methods)
    
mod.addConstr((0.5*g[1] >= y[2]))
mod.addConstr((0.25*(g[1] + g[2]) <= y[2]))  
mod.addConstr((g[i] == x[i,1] + x[i,2]))
    
    #objective
costs = gp.quicksum((telephone[i] * x[i,1] for i in groups) +  gp.quicksum(personal[i] * x[i,0] for i in groups))
mod.setObjective(costs, sense = GRB.MINIMIZE)
    
mod.update()
mod.optimise()
    
print(mod.objval)
print('minimum cost:', mod.objval)

The Error I am getting is:

TypeError                                 Traceback (most recent call last)
\<ipython-input-120-285afeb1ec31\> in \<module\>
25 mod.addConstr((g\[2\] + g\[4\]) \<= 0.4 \*(gp.quicksum(x\[i,j\] for j in methods for i in groups)))
26
\---\> 27 mod.addConstrs((g\[i\] for i in groups \>= 0.1 \* (gp.quicksum(x\[i,j\] for j in methods for i in groups))))
28
29 mod.addConstrs((g\[i\] for i in groups \<= 0.5 \* (gp.quicksum(x\[i,j\] for j in methods for i in groups))))

TypeError: 'TempConstr' object is not iterable

I have tried making it a large for loop but this doesn't seem to work either. I am unsure if I am using Gp.Quicksum wrong or what is happening here!



Solution 1:[1]

I think the line mod.addConstrs((gp.quicksum(x[i,j]for i in groups for j in methods) == N_investors)) contains a mistake. addConstrs expect a generator but the == N_investors certainly prevent that. Here is a version where the parenthesis are more clearly matched:

mod.addConstrs(
    (
        # `gp.quicksum(...) == N_investors` is not a generator
        gp.quicksum(
            x[i,j] for i in groups for j in methods
        ) == N_investors
    )
)

I do not know what you meant to do (nor what gp.quicksum does), but maybe you can just provide a list containing the result of the equality:

mod.addConstrs(
    [ # this list is iterable
        gp.quicksum(
            x[i,j] for i in groups for j in methods
        ) == N_investors
    ]
)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jérôme Richard