Search code examples
pythonoptimizationpyomo

Pyomo find minimal sum of list values


I want to have an indexed binary variable so pyomo optimises it to minimise the total sum of the list while picking at least 2 elements. When I remove the (imo redundant) model.q I receive:

ValueError: No variables appear in the Pyomo model constraints or objective. This is not supported by the NL file interface

and the solution pyomo gives me with model.q contains q=0 which violates constraint c1.

5 Declarations: i x q y objective
q 0.0
y[0] 1
y[1] 1
y[2] 1
from pyomo.environ import *


# create a model instance
model = ConcreteModel()

#Parameters
model.i = RangeSet(0, 2)

model.x = Param(model.i, initialize=[5,1,2])

#Variables
model.q = Var(domain=Binary, initialize=1)

model.y = Var(model.i, domain=Binary)

#Constraints
model.c1 = model.Constraint(expr=model.q == 1)
model.c2 = model.Constraint(expr=sum(model.y[i] for i in model.i) >= 2)

#Objective function
model.objective = Objective(expr = sum(model.x[i]*model.y[i]*model.q for i in model.i), sense=minimize)

# compute a solution
results = SolverFactory('mindtpy').solve(model, mip_solver='glpk', nlp_solver='ipopt', tee=True)
model.pprint()

Solution

  • Welcome to the site.

    You have a couple errors that are causing you problems.

    1. when you construct your parameter, you need to pass in a dictionary so that pyomo can associate the items in the set to the values. You cannot pass in a list and assume things happen sequentially... The set could have any ordering, etc.

    2. You have a hideous typo when making your constraint C2. See my note in code comment

    3. Your variable q is totally unnecessary. And, by multiplying q times y you are making the problem non-linear by multiplying variables.

    A little fixed up:

    from pyomo.environ import *
    
    
    # create a model instance
    model = ConcreteModel()
    
    #Parameters
    model.i = RangeSet(0, 2)
    
    values = {0:5, 1:1, 2:2}
    
    model.x = Param(model.i, initialize=values)
    
    #Variables
    #model.q = Var(domain=Binary, initialize=1)
    
    model.y = Var(model.i, domain=Binary)
    
    #Constraints
    #model.c1 = model.Constraint(expr=model.q == 1)
    
    # NOTE:  you mistakenly had "model.Constraint" which is a sneaky & bad typo!!
    model.c2 = Constraint(expr=sum(model.y[i] for i in model.i) >= 2)
    
    #Objective function
    model.objective = Objective(expr = sum(model.x[i]*model.y[i] for i in model.i), sense=minimize)
    
    # compute a solution
    results = SolverFactory('glpk').solve(model) #, mip_solver='glpk', nlp_solver='ipopt', tee=True)
    print(results)
    model.display()
    model.pprint()
    

    produces (a little long but I think it will help you to look at ALL 3 of these items...

    Problem: 
    - Name: unknown
      Lower bound: 3.0
      Upper bound: 3.0
      Number of objectives: 1
      Number of constraints: 2
      Number of variables: 4
      Number of nonzeros: 4
      Sense: minimize
    Solver: 
    - Status: ok
      Termination condition: optimal
      Statistics: 
        Branch and bound: 
          Number of bounded subproblems: 1
          Number of created subproblems: 1
      Error rc: 0
      Time: 0.006919145584106445
    Solution: 
    - number of solutions: 0
      number of solutions displayed: 0
    
    Model unknown
    
      Variables:
        y : Size=3, Index=i
            Key : Lower : Value : Upper : Fixed : Stale : Domain
              0 :     0 :   0.0 :     1 : False : False : Binary
              1 :     0 :   1.0 :     1 : False : False : Binary
              2 :     0 :   1.0 :     1 : False : False : Binary
    
      Objectives:
        objective : Size=1, Index=None, Active=True
            Key  : Active : Value
            None :   True :   3.0
    
      Constraints:
        c2 : Size=1
            Key  : Lower : Body : Upper
            None :   2.0 :  2.0 :  None
    1 RangeSet Declarations
        i : Dimen=1, Size=3, Bounds=(0, 2)
            Key  : Finite : Members
            None :   True :   [0:2]
    
    1 Param Declarations
        x : Size=3, Index=i, Domain=Any, Default=None, Mutable=False
            Key : Value
              0 :     5
              1 :     1
              2 :     2
    
    1 Var Declarations
        y : Size=3, Index=i
            Key : Lower : Value : Upper : Fixed : Stale : Domain
              0 :     0 :   0.0 :     1 : False : False : Binary
              1 :     0 :   1.0 :     1 : False : False : Binary
              2 :     0 :   1.0 :     1 : False : False : Binary
    
    1 Objective Declarations
        objective : Size=1, Index=None, Active=True
            Key  : Active : Sense    : Expression
            None :   True : minimize : 5*y[0] + y[1] + 2*y[2]
    
    1 Constraint Declarations
        c2 : Size=1, Index=None, Active=True
            Key  : Lower : Body               : Upper : Active
            None :   2.0 : y[0] + y[1] + y[2] :  +Inf :   True
    
    5 Declarations: i x y c2 objective
    [Finished in 564ms]