4

I have the following boolean and continuous variables, where only some of the 'percents' have a status of 1.

status[i] = m.Array(m.Var, p, lb=0, ub=1, integer=True)
percent[i] = m.Array(m.FV, p, value=1, lb=0.6, ub=1.1)

I've used some intermediaries that use the min2 option that are fed into my contraint equation.

My objective is a linear summation of status, percent and a constant.

I am using the following solver options:

m = GEKKO(remote=False)
    # Options
    m.options.SOLVER = 1
    m.options.LINEAR = 0

    # optional solver settings with APOPT
    m.solver_options = ['minlp_maximum_iterations 10000',
                    'minlp_max_iter_with_int_sol 500',
                    'minlp_gap_tol 0.01',
                    'nlp_maximum_iterations 500',
                    'minlp_as_nlp 0',
                    'minlp_interger_leaves = 0',
                    'minlp_branch_method 1',
                    'minlp_integer_tol 0.01',
                    'minlp_print_level 2'
                    ]

My returned objective is: 2140.05, none of the constraints are violated and the solution is very good. However, by reducing the 'nlp_maximum_iterations' to 10, I can get an even better solution of 2138.67.

I would expect that my minimum would improve with increasing iterations. My plan was to find a balance between runtime and optimal cost, with the expectation that a long runtime would lead to a solution close to the global minimum, that I could use as a baseline.

In my testing of the problem, it seems that the nlp_max_iterations is the controlling factor on weather or not it finds the lower of the two costs. minlp_maximum_iterations, minlp_max_iter_with_int_sol,and minlp_gap_tol, did not seem to have an affect on the solution.

Any explanation of this behavior would be appreciated greatly.

1 Answers1

2

Here are a few tips that may help:

  • Use min3 instead of min2. This uses a binary variable form instead of the MPCC form that can give false solutions.
  • APOPT should keep the best integer solution and return that if it reaches maximum iterations. Is the solution with objective 2138.67 an integer solution?
  • If it is a maximization problem then 2140.05 would be a better solution. Could you confirm that you are using m.Minimize() instead of m.Maximize()?

The APOPT solver uses a branch and bound method that solves Nonlinear Programming (NLP) problems while successively bounding variables at integer constraints. Here are methods for declaring binary, integer, and special ordered sets.

John Hedengren
  • 12,068
  • 1
  • 21
  • 25
  • 2
    It appears that switching from min2 to min3 solved the issue. I will confirm that is the case with some more testing. Both solutions returned were integer solutions. Both solutions were returned with a success message from the solver. The solver was using the default of minimize and the solution matched my expectations (i.e. clearly a local minimum for the problem). – Jordon French May 29 '20 at 15:25
  • I'm glad it helped to switch to `min3`. If you want to check the `min2` solution, I'd recommend that you verify that each equation is satisfied. I typically don't use the `min2`, `sign2`, `max2`, `if2`, or other MPCC functions unless there are no competing objectives that can sometimes lead to false solutions. – John Hedengren May 29 '20 at 17:51
  • 1
    One issue that I noticed with the min function is that it creates a 'helper variable' and 2 constraints to obtain a minimum. The helper variable is subject to the same integer tolerances, letting the min function return a variable up to 1% off the input variable (using the default tolerance). If there is an inequality constraint that has a min/max function it can fudge a solution by 1% regardless of the inequality constraint tolerance. – Jordon French Jun 04 '20 at 22:48
  • Here is more information on how those functions work. https://apmonitor.com/me575/index.php/Main/LogicalConditions Does it help to set the default tolerance tighter such as 'minlp_integer_tol 0.0001'? – John Hedengren Jun 05 '20 at 01:16