4
$\begingroup$

I am trying to build my model up and keep running into this output from BARON: Clp0019I {x} variables/rows fixed as scaled bounds too close. I checked the BARON manual but I wasn't able to find anything that mentions this issue. I found another question where somebody had the exact same issue but I wasn't able to really solve the issue after studying that question for a little while. When I initiate the solve, the BARON output will spam me with that message until I manually stop the solver.

I am using PYOMO and the BARON solver, and below I have generated a minimal reproducible example ready to be copy-pasted, the output from BARON is also listed below.

When I do not include the second constraint, the model is able to solve and I do not run into any problems. However, once this constraint is introduced then I get the problem from above. If anybody can maybe shine some light on why this is occurring that would be great. There are also a couple of things that might be relevant to the error which I will note below:

  1. The model upper bound is 1E+52 --> This could be problematic and a red flag, but I also am not confident that this means anything in particular to the error that is occurring.
  2. If you remove the second constraint and solve the model, the solver is able to complete the solve during preprocessing --> This is just something I have noticed, I don't know if it's significant to the problem at hand.
  3. There might also be something going on with how I have formulated the second constraint that seems to not sit well with the solver.

Minimal Reproducible Example

from __future__ import division
from pyomo.environ import *
from MPBFunctions import *
from pyomo import environ as pym
from pyomo.util.infeasible import *
import pandas as pd
import time
#import math

model = ConcreteModel()
########################################################################################################################
# Set Declaration
########################################################################################################################
Imax = 3
Jmax = 3
Tmax = 1

model.Iset = RangeSet(1, Imax)
model.Jset = RangeSet(1, Jmax)
model.Tset = RangeSet(0, Tmax)
model.Tset2 = RangeSet(1, Tmax)

########################################################################################################################
# Parameter Declaration
########################################################################################################################
model.p = Param(initialize = 203.84)
model.tau = Param(initialize = 0.05)
model.hfee = Param(initialize = 10.69)
model.dfee = Param(initialize = 9.74)
model.c = Param(initialize=137)
model.c0 = Param(initialize = 0.0000349)
model.c1 = Param(initialize = 4)
model.alpha = Param(model.Iset, model.Jset, initialize = {(1, 1): 0.313876345630547,
                                                         (1, 2): 0.300292323327834,
                                                         (1, 3): 0.348387132466427,
                                                         (2, 1): 0.295435707228957,
                                                         (2, 2): 0.28522932311189,
                                                         (2, 3): 0.287451178160919,
                                                         (3, 1): 0.317860171471026,
                                                         (3, 2): 0.27807922348595,
                                                         (3, 3): 0.275393916055552})

model.TotalVol = Param(model.Iset, model.Jset, initialize = {(1, 1): 2190.59783126487,
                                                             (1, 2): 1207.90298253892,
                                                             (1, 3): 1050.0053718149,
                                                             (2, 1): 704.123722773656,
                                                             (2, 2): 1804.76078561487,
                                                             (2, 3): 443.906913433536,
                                                             (3, 1): 329.654678511934,
                                                             (3, 2): 278.458426872543,
                                                             (3, 3): 781.01472605762} )

def volume_sum(model):
    return sum(sum(model.TotalVol[i,j] for i in model.Iset) for j in model.Jset)
model.InitialVol = Param(initialize=volume_sum)

########################################################################################################################
# Variable Declaration
########################################################################################################################

# Control Variable & Initial Guess of Variable

model.L = Var(model.Iset, model.Jset, model.Tset, bounds = (0,1), initialize = {(1, 1, 1): 0.5,
                                                                                 (1, 2, 1): 0.24,
                                                                                 (1, 3, 1): 0.2,
                                                                                 (2, 1, 1): 0.3,
                                                                                 (2, 2, 1): 0.09,
                                                                                 (2, 3, 1): 0.4,
                                                                                 (3, 1, 1): 0.1,
                                                                                 (3, 2, 1): 0.14,
                                                                                 (3, 3, 1): 0.8})

model.incell_weight = Var(model.Iset, model.Jset, model.Tset, bounds=(0,1), initialize=None)

# State Variables - Initially fixed, but governed by biological constraints

model.susceptible = Var(model.Iset, model.Jset, model.Tset, bounds=(0,8000), initialize =   {(1, 1, 0): 6979.1746391853,
                                                                                             (1, 2, 0): 4022.4237807779,
                                                                                             (1, 3, 0): 3013.90399921295,
                                                                                             (2, 1, 0): 2383.33994688046,
                                                                                             (2, 2, 0): 6327.40268751015,
                                                                                             (2, 3, 0): 1544.28628984443,
                                                                                             (3, 1, 0): 1037.10596073212,
                                                                                             (3, 2, 0): 1001.36365234999,
                                                                                             (3, 3, 0): 2835.9912130378})


model.G_PostTreatment = Var(model.Iset, model.Jset, model.Tset, bounds=(0,200), initialize =    {(1, 1, 0): 0.0,
                                                                                                 (1, 2, 0): 0.0,
                                                                                                 (1, 3, 0): 14.0,
                                                                                                 (2, 1, 0): 14.0,
                                                                                                 (2, 2, 0): 0.0,
                                                                                                 (2, 3, 0): 3.0,
                                                                                                 (3, 1, 0): 9.0,
                                                                                                 (3, 2, 0): 0.0,
                                                                                                 (3, 3, 0): 0.0})

model.G_NewGrowth = Var(model.Iset, model.Jset, model.Tset, bounds=(0,200), initialize =    {(1, 1, 0): 0.0,
                                                                                             (1, 2, 0): 0.0,
                                                                                             (1, 3, 0): 14.0,
                                                                                             (2, 1, 0): 14.0,
                                                                                             (2, 2, 0): 0.0,
                                                                                             (2, 3, 0): 3.0,
                                                                                             (3, 1, 0): 9.0,
                                                                                             (3, 2, 0): 0.0,
                                                                                             (3, 3, 0): 0.0})


# Fix State Variables

[model.susceptible[i,j,0].fix() for i in model.Iset for j in model.Jset]
[model.G_PostTreatment[i,j,0].fix() for i in model.Iset for j in model.Jset]
[model.G_NewGrowth[i,j,0].fix() for i in model.Iset for j in model.Jset]

# Variables without initial values. 

model.incell_weight = Var(model.Iset, model.Jset, model.Tset, bounds=(0,1))

########################################################################################################################
# Objective Function
########################################################################################################################
def objective_rule(model):
    return (model.p * model.tau + model.hfee)*model.InitialVol - \
           sum (sum (sum ((model.dfee*model.alpha[i, j])*model.G_PostTreatment[i, j, t] + model.c*model.L[i, j, t]*model.G_NewGrowth[i, j, t] \
                          for i in model.Iset ) for j in model.Jset ) for t in model.Tset2 )
model.damages = Objective(rule=objective_rule, sense=minimize)

#########################################################################################################################
## Constraint Declaration
#########################################################################################################################

def susceptible_rule(model,i,j,t):
    if t == 0:
        return Constraint.Skip
    else:
        return model.susceptible[i,j,t] == model.susceptible[i,j,t-1] - model.G_NewGrowth[i,j,t-1]
model.susceptible_constraint = Constraint(model.Iset, model.Jset, model.Tset, rule = susceptible_rule)

def incell_weight_rule(model,i,j,t):
    if t == 0:
        return Constraint.Skip
    else:
        return model.incell_weight[i,j,t] == 1 - exp( -1 * (model.c0 * model.susceptible[i,j,t])**model.c1 )
model.incell_weight_rules = Constraint(model.Iset, model.Jset, model.Tset, rule = incell_weight_rule)

########################################################################################################################
# Solving The Model 
########################################################################################################################
solver = SolverFactory('baron')
results = solver.solve(model, tee=True)
model.pprint()
print(results)

Expected Output

===========================================================================
 BARON version 20.4.14. Built: WIN-64 Tue Apr 14 21:23:22 EDT 2020

 BARON is a product of The Optimization Firm.
 For information on BARON, see https://minlp.com/about-baron
 Changing option LPSol to 8 (CLP) and continuing.

 If you use this software, please cite publications from
 https://minlp.com/baron-publications, such as: 

 Khajavirad, A. and N. V. Sahinidis,
 A hybrid LP/NLP paradigm for global optimization relaxations,
 Mathematical Programming Computation, 10, 383-421, 2018.
===========================================================================
 This BARON run may utilize the following subsolver(s)
 For LP/MIP/QP: CLP/CBC                                         
 For NLP: IPOPT, FILTERSD, FILTERSQP
===========================================================================
 Doing local search
 Unable to find/load CPLEX library cplex12100.dll.
 Unable to find/load CPLEX library cplex1290.dll.
 Solving bounding LP
 Starting multi-start local search
 Done with local search
===========================================================================
  Iteration    Open nodes         Time (s)    Lower bound      Upper bound
          1             1             0.06    -68301.8         0.100000E+52
Clp0019I 1 variables/rows fixed as scaled bounds too close

....
....

Clp0019I 36 variables/rows fixed as scaled bounds too close
$\endgroup$
3
  • $\begingroup$ The message is apparently coming from CLP, which is being called by BARON to solve subproblems. The upper bound of 0.100000E+52 is BARON's "infinity", so that means that no feasible solution has been found as of the iteration being reported. In general with BARON, as with other B&B global optimizers, the tighter the constraints provided, the better (but not always), and that is certainly the case for lower and upper bounds on variables (so include the tightest bound constraints you can). if you are able to install CPLEX, BARON will utilize it instead of CLP, and probably perform better. $\endgroup$ – Mark L. Stone Apr 17 '20 at 22:31
  • $\begingroup$ @MarkL.Stone I was reading some documentation and thought that maybe there is an issue with how things are scaled. You'll notice that the "susceptible" variable is around 4-6000 while the "new_growth" and "post_treatment" vars are significantly smaller. When I scaled the susceptibles down (dividing by 100), I was able to get a reasonable bound and solve the model. I am going to probe this a bit further and see what I can find. $\endgroup$ – GrayLiterature Apr 18 '20 at 1:26
  • $\begingroup$ Yes, good scaling is important. BARON is not scale-invariant. Try to get non-zero coefficients as close in magnitude to 1 as possible. $\endgroup$ – Mark L. Stone Apr 18 '20 at 1:41
2
$\begingroup$

BARON is having trouble finding a feasible local solution.

The $0.100000E+52$ number is the default number used before the first feasible solution is found.

The word "scaled" can be misleading here, Clp's output hints that your model's constraints are likely overdefined, which causes numerical instability in both the linear and non-linear solvers.

The fact that both solvers have trouble further indicates that the issue is with your linear constraints.

This is typically easily resolved by presolving the problem, although I don't know what linear presolving techniques are implemented in BARON (if any).

If you have access to BARON through AMPL or AIMMS, they will do the linear presolving for you before passing the problem to BARON. Since you are using PYOMO I'm guessing you don't, so your other option would be to try and do some of it yourself - AIMMS have documented the basic algorithms quite nicely.

As a first-order approach, just try the most basic thing first, which is called Singleton reduction. Detect if a variable is fixed (or nearly fixed), remove that variable from your model completely, and substitute it for that number everywhere in the problem. You should also save the number you used because, at the end of the solving process, you'll have to restore the problem to its original dimensionality to retrieve your solution.

$\endgroup$
2
  • $\begingroup$ Could you elaborate on what you mean by "overdefined"? $\endgroup$ – GrayLiterature Apr 20 '20 at 13:59
  • $\begingroup$ I mean a system too tightly constrained, with too many hyperplanes intersecting at the same vertex. $\endgroup$ – Nikos Kazazakis Apr 22 '20 at 16:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.