Skip to content

Commit 8c194c9

Browse files
committed
feat: branch and perform obbt only on quadratic vars
1 parent 39575cb commit 8c194c9

File tree

6 files changed

+27
-19
lines changed

6 files changed

+27
-19
lines changed

galini/branch_and_cut/bound_reduction.py

+10-6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import numpy as np
1919
import pyomo.environ as pe
2020
from coramin.relaxations.iterators import relaxation_data_objects
21+
from galini.branch_and_cut.branching import BILINEAR_RELAXATIONS_TYPES
2122
from galini.math import is_close
2223
from galini.pyomo import safe_set_bounds
2324
from galini.pyomo.util import update_solver_options
@@ -72,13 +73,14 @@ def perform_obbt_on_model(solver, model, linear_model, upper_bound, timelimit, r
7273
# collect variables in nonlinear constraints
7374
nonlinear_variables = ComponentSet()
7475
for relaxation in relaxation_data_objects(linear_model, active=True, descend_into=True):
75-
for var in relaxation.get_rhs_vars():
76-
# Coramin will complain about variables that are fixed
77-
if not var.has_lb() or not var.has_ub():
78-
nonlinear_variables.add(var)
79-
else:
80-
if not np.abs(var.ub - var.lb) < mc.epsilon:
76+
if not isinstance(relaxation, BILINEAR_RELAXATIONS_TYPES):
77+
for var in relaxation.get_rhs_vars():
78+
# Coramin will complain about variables that are fixed
79+
if not var.has_lb() or not var.has_ub():
8180
nonlinear_variables.add(var)
81+
else:
82+
if not np.abs(var.ub - var.lb) < mc.epsilon:
83+
nonlinear_variables.add(var)
8284

8385
time_left = timelimit - seconds_elapsed_since(obbt_start_time)
8486
nonlinear_variables = list(nonlinear_variables)
@@ -140,6 +142,8 @@ def perform_obbt_on_model(solver, model, linear_model, upper_bound, timelimit, r
140142

141143
for var, new_lb, new_ub in zip(nonlinear_variables, *result):
142144
original_var = model.find_component(var.getname(fully_qualified=True))
145+
if original_var is None:
146+
continue
143147
new_lb = best_lower_bound(var, new_lb, var.lb, eps)
144148
new_ub = best_upper_bound(var, new_ub, var.ub, eps)
145149
if np.abs(new_ub - new_lb) < eps:

galini/branch_and_cut/branching.py

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import numpy as np
1818
import pyomo.environ as pe
19+
from coramin.relaxations.mccormick import PWMcCormickRelaxation
1920

2021
from galini.branch_and_bound.branching import BranchingPoint
2122
from galini.branch_and_bound.strategy import BranchingStrategy
@@ -24,6 +25,9 @@
2425
from galini.math import is_close, is_inf
2526

2627

28+
BILINEAR_RELAXATIONS_TYPES = (PWMcCormickRelaxation,)
29+
30+
2731
class BranchAndCutBranchingStrategy(BranchingStrategy):
2832
def __init__(self, algorithm):
2933
pass
@@ -162,6 +166,8 @@ def compute_nonlinear_infeasiblity_components(linear_problem, mip_solution):
162166
}
163167

164168
for relaxation in linear_problem.galini_nonlinear_relaxations:
169+
if not isinstance(relaxation, BILINEAR_RELAXATIONS_TYPES):
170+
continue
165171
rhs_vars = relaxation.get_rhs_vars()
166172

167173
if len(rhs_vars) > 2:

galini/branch_and_cut/node_storage.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
from pyomo.contrib.fbbt.fbbt import compute_bounds_on_expr
2020

2121
from galini.branch_and_bound.branching import branch_at_point
22-
from galini.relaxations.relax import RelaxationData
2322
from galini.cuts.pool import CutNodeStorage, CutPool
2423
from galini.pyomo import safe_setlb, safe_setub
24+
from galini.relaxations.relax import RelaxationData
2525

2626

2727
class BranchingDecision:

galini/relaxations/expressions.py

+4-7
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,11 @@
1515
"""Functions to relax nonlinear pyomo expresions."""
1616

1717
import networkx as nx
18-
19-
from suspect.pyomo.quadratic import QuadraticExpression
20-
import pyomo.environ as pe
21-
from suspect.convexity.rules.quadratic import QuadraticRule
22-
from pyomo.contrib.fbbt.fbbt import compute_bounds_on_expr
23-
from coramin.utils.coramin_enums import RelaxationSide, FunctionShape
18+
from coramin.utils.coramin_enums import RelaxationSide
2419
from galini.relaxations.multivariate import FactorableConvexExpressionRelaxation
25-
from coramin.relaxations.auto_relax import replace_sub_expression_with_aux_var
20+
from pyomo.contrib.fbbt.fbbt import compute_bounds_on_expr
21+
from suspect.convexity.rules.quadratic import QuadraticRule
22+
from suspect.pyomo.quadratic import QuadraticExpression
2623

2724
_convexity_rule = QuadraticRule()
2825

galini/relaxations/multivariate.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@
1414

1515
"""Relaxation that replaces a convex function with an auxiliary variable."""
1616

17-
from coramin.utils.coramin_enums import RelaxationSide, FunctionShape
17+
import math
18+
19+
import pyomo.environ as pe
1820
from coramin.relaxations.custom_block import declare_custom_block
1921
from coramin.relaxations.relaxations_base import BaseRelaxationData, ComponentWeakRef
22+
from coramin.utils.coramin_enums import RelaxationSide
2023
from pyomo.core.expr.visitor import identify_variables
21-
import math
22-
import pyomo.environ as pe
23-
from coramin.relaxations._utils import _get_bnds_list
2424

2525

2626
@declare_custom_block(name='FactorableConvexExpressionRelaxation')

galini/relaxations/relax.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
_relax_root_to_leaf_SumExpression,
2222
_relax_expr,
2323
)
24+
from coramin.relaxations import PWXSquaredRelaxation, PWUnivariateRelaxation
2425
from coramin.utils.coramin_enums import RelaxationSide
2526
from pyomo.core.expr.numvalue import polynomial_degree
2627
from suspect.pyomo.quadratic import QuadraticExpression
@@ -164,7 +165,7 @@ def relax(model, data, use_linear_relaxation=True):
164165

165166
assert obj.is_minimizing()
166167

167-
relaxation_side = RelaxationSide.UNDER
168+
# relaxation_side = RelaxationSide.UNDER
168169
relaxation_side = RelaxationSide.BOTH
169170

170171
new_body = relax_expression(model, obj.expr, relaxation_side, data)

0 commit comments

Comments
 (0)