Search code examples
gekko

Unexpected results from sum using gekko variable


I am optimizing a simple problem where I am summing intermediate variables for a constraint where the sum needs to be lower than a certain budget.

When I print the sum, either using sum or np.sum, I get the following results:(((((((((((((((((((((((((((((i429+i430)+i431)+i432)+i433)+i434)+i435)+i436)+i437)+i438)+i439)+i440)+i441)+i442)+i443)+i444)+i445)+i446)+i447)+i448)+i449)+i450)+i451)+i452)+i453)+i454)+i455)+i456)+i457)+i458)

Here is the command to create the variables and the sum.

x = m.Array(m.Var, (len(bounds)),integer=True) 
sums = [m.Intermediate(objective_inverse2(x,y)) for x,y in zip(x,reg_feats)]

My understanding of the intermediate variable is a variable which is dynamically calculated based on the value of x, which are decision variables.

Here is the summing function for the max budget constraint.

m.Equation(np.sum(sums) < max_budget)

Solving the problem returns an error saying there are no feasible solution, even through trivial solutions exist. Furthermore, removing this constraint returns a solution which naturally does not violate the max budget constraint.

What am I misunderstanding about the intermediate variable and how to sum them.


Solution

  • It is difficult to diagnose the problem without a complete, minimal problem. Here is an attempt to recreate the problem:

    from gekko import GEKKO
    import numpy as np
    
    m = GEKKO()
    nb = 5
    x = m.Array(m.Var,nb,value=1,lb=0,ub=1,integer=True)
    y = m.Array(m.Var,nb,lb=0)
    
    i = []  # intermediate list
    for xi,yi in zip(x,y):
        i.append(m.Intermediate(xi*yi))
    m.Maximize(m.sum(i))
    m.Equation(m.sum(i)<=100)
    
    m.options.SOLVER = 1
    m.solve()
    
    print(x)
    print(y)
    

    Instead of creating a list of Intermediates, the summation can also happen with the result of the list comprehension. This way, only one Intermediate value is created.

    from gekko import GEKKO
    import numpy as np
    
    m = GEKKO()
    nb = 5
    x = m.Array(m.Var,nb,value=1,lb=0,ub=1,integer=True)
    y = m.Array(m.Var,nb,lb=0)
    sums = m.Intermediate(m.sum([xi*yi for xi,yi in zip(x,y)]))
    m.Maximize(sums)
    m.Equation(sums<=100)
    
    m.options.SOLVER = 1
    m.solve()
    
    print(sums.value)
    print(x)
    print(y)
    

    In both cases, the optimal solution is:

     ---------------------------------------------------
     Solver         :  APOPT (v1.0)
     Solution time  :   1.560000001336448E-002 sec
     Objective      :   -100.000000000000     
     Successful solution
     ---------------------------------------------------
     
    [100.0]
    [[1.0] [1.0] [1.0] [1.0] [1.0]]
    [[20.0] [20.0] [20.0] [20.0] [20.0]]
    

    Try using the Gekko m.sum() function to improve solution efficiency, especially for large problems.