diff --git a/pyomo/contrib/mindtpy/algorithm_base_class.py b/pyomo/contrib/mindtpy/algorithm_base_class.py index c254c5d3f3d..836df9fff78 100644 --- a/pyomo/contrib/mindtpy/algorithm_base_class.py +++ b/pyomo/contrib/mindtpy/algorithm_base_class.py @@ -56,7 +56,6 @@ SuppressInfeasibleWarning, _DoNothing, lower_logger_level_to, - copy_var_list_values, get_main_elapsed_time, time_code, ) @@ -81,6 +80,7 @@ set_solver_mipgap, set_solver_constraint_violation_tolerance, update_solver_timelimit, + copy_var_list_values ) single_tree, single_tree_available = attempt_import('pyomo.contrib.mindtpy.single_tree') @@ -866,12 +866,14 @@ def init_rNLP(self, add_oa_cuts=True): self.rnlp.MindtPy_utils.variable_list, self.mip.MindtPy_utils.variable_list, config, + ignore_integrality=True ) if config.init_strategy == 'FP': copy_var_list_values( self.rnlp.MindtPy_utils.variable_list, self.working_model.MindtPy_utils.variable_list, config, + ignore_integrality=True ) self.add_cuts( dual_values=dual_values, diff --git a/pyomo/contrib/mindtpy/single_tree.py b/pyomo/contrib/mindtpy/single_tree.py index 9776920f434..f3be27cbc4c 100644 --- a/pyomo/contrib/mindtpy/single_tree.py +++ b/pyomo/contrib/mindtpy/single_tree.py @@ -16,9 +16,8 @@ from pyomo.repn import generate_standard_repn import pyomo.core.expr as EXPR from math import copysign -from pyomo.contrib.mindtpy.util import get_integer_solution +from pyomo.contrib.mindtpy.util import get_integer_solution, copy_var_list_values from pyomo.contrib.gdpopt.util import ( - copy_var_list_values, get_main_elapsed_time, time_code, ) diff --git a/pyomo/contrib/mindtpy/util.py b/pyomo/contrib/mindtpy/util.py index 068cd61aba1..59490248e49 100644 --- a/pyomo/contrib/mindtpy/util.py +++ b/pyomo/contrib/mindtpy/util.py @@ -23,6 +23,7 @@ RangeSet, ConstraintList, TransformationFactory, + value ) from pyomo.repn import generate_standard_repn from pyomo.contrib.mcpp.pyomo_mcpp import mcpp_available, McCormick @@ -964,3 +965,31 @@ def generate_norm_constraint(fp_nlp_model, mip_model, config): mip_model.MindtPy_utils.discrete_variable_list, ): fp_nlp_model.norm_constraint.add(nlp_var - mip_var.value <= rhs) + +def copy_var_list_values(from_list, to_list, config, + skip_stale=False, skip_fixed=True, + ignore_integrality=False): + """Copy variable values from one list to another. + Rounds to Binary/Integer if necessary + Sets to zero for NonNegativeReals if necessary + """ + for v_from, v_to in zip(from_list, to_list): + if skip_stale and v_from.stale: + continue # Skip stale variable values. + if skip_fixed and v_to.is_fixed(): + continue # Skip fixed variables. + var_val = value(v_from, exception=False) + rounded_val = int(round(var_val)) + if var_val in v_to.domain: + v_to.set_value(value(v_from, exception=False)) + elif ignore_integrality and v_to.is_integer(): + v_to.set_value(value(v_from, exception=False)) + elif abs(var_val) <= config.zero_tolerance and 0 in v_to.domain: + v_to.set_value(0) + elif v_to.is_integer() and (math.fabs(var_val - rounded_val) <= + config.integer_tolerance): + print('var_val', var_val) + v_to.pprint() + v_to.set_value(rounded_val) + else: + raise