def test_clear(self): cmap = ComponentMap() self.assertEqual(len(cmap), 0) cmap.update(self._components) self.assertEqual(len(cmap), len(self._components)) cmap.clear() self.assertEqual(len(cmap), 0)
def test_update(self): cmap = ComponentMap() self.assertEqual(len(cmap), 0) cmap.update(self._components) self.assertEqual(len(cmap), len(self._components)) for c, val in self._components: self.assertEqual(cmap[c], val)
def test_update(self): cmap = ComponentMap() self.assertEqual(len(cmap), 0) cmap.update(self._components) self.assertEqual(len(cmap), len(self._components)) for c, val in self._components: self.assertEqual(cmap[c], val)
def test_clear(self): cmap = ComponentMap() self.assertEqual(len(cmap), 0) cmap.update(self._components) self.assertEqual(len(cmap), len(self._components)) cmap.clear() self.assertEqual(len(cmap), 0)
def test_len(self): cmap = ComponentMap() self.assertEqual(len(cmap), 0) cmap.update(self._components) self.assertEqual(len(cmap), len(self._components)) cmap = ComponentMap(self._components) self.assertEqual(len(cmap), len(self._components)) self.assertTrue(len(self._components) > 0)
def test_iter(self): cmap = ComponentMap() self.assertEqual(list(iter(cmap)), []) cmap.update(self._components) ids_seen = set() for c in cmap: ids_seen.add(id(c)) self.assertEqual(ids_seen, set(id(c) for c, val in self._components))
def test_len(self): cmap = ComponentMap() self.assertEqual(len(cmap), 0) cmap.update(self._components) self.assertEqual(len(cmap), len(self._components)) cmap = ComponentMap(self._components) self.assertEqual(len(cmap), len(self._components)) self.assertTrue(len(self._components) > 0)
def test_iter(self): cmap = ComponentMap() self.assertEqual(list(iter(cmap)), []) cmap.update(self._components) ids_seen = set() for c in cmap: ids_seen.add(id(c)) self.assertEqual(ids_seen, set(id(c) for c,val in self._components))
def generate_names(self, active=None, descend_into=True, convert=str, prefix=""): """ Generate a container of fully qualified names (up to this container) for objects stored under this container. Args: active (:const:`True`/:const:`None`): Set to :const:`True` to indicate that only active components should be included. The default value of :const:`None` indicates that all components (including those that have been deactivated) should be included. *Note*: This flag is ignored for any objects that do not have an active flag. descend_into (bool): Indicates whether or not to include subcomponents of any container objects that are not components. Default is :const:`True`. convert (function): A function that converts a storage key into a string representation. Default is str. prefix (str): A string to prefix names with. Returns: A component map that behaves as a dictionary mapping component objects to names. """ assert active in (None, True) from pyomo.core.kernel.component_map import ComponentMap names = ComponentMap() # if not active, then no children can be active if (active is not None) and \ not getattr(self, _active_flag_name, True): return names name_template = (prefix + self._child_storage_delimiter_string + self._child_storage_entry_string) for child in self.children(): if (active is None) or \ getattr(child, _active_flag_name, True): names[child] = (name_template % convert(child.storage_key)) if descend_into and child._is_container and \ (not child._is_component): names.update( child.generate_names(active=active, descend_into=True, convert=convert, prefix=names[child])) return names
def fbbt(comp, deactivate_satisfied_constraints=False, update_variable_bounds=True, integer_tol=1e-4): """ Perform FBBT on a constraint, block, or model. For more control, use fbbt_con and fbbt_block. For detailed documentation, see the docstrings for fbbt_con and fbbt_block. Parameters ---------- comp: pyomo.core.base.constraint.Constraint or pyomo.core.base.block.Block or pyomo.core.base.PyomoModel.ConcreteModel deactivate_satisfied_constraints: bool If deactivate_satisfied_constraints is True and a constraint is always satisfied, then the constranit will be deactivated update_variable_bounds: bool If update_variable_bounds is True, then the bounds on variables will be automatically updated. integer_tol: float If the lower bound computed on a binary variable is less than or equal to integer_tol, then the lower bound is left at 0. Otherwise, the lower bound is increased to 1. If the upper bound computed on a binary variable is greater than or equal to 1-integer_tol, then the upper bound is left at 1. Otherwise the upper bound is decreased to 0. Returns ------- new_var_bounds: ComponentMap A ComponentMap mapping from variables a tuple containing the lower and upper bounds, respectively, computed from FBBT. """ new_var_bounds = ComponentMap() if comp.type() == Constraint: if comp.is_indexed(): for _c in comp.values(): _new_var_bounds = fbbt_con( comp, deactivate_satisfied_constraints= deactivate_satisfied_constraints, update_variable_bounds=update_variable_bounds, integer_tol=integer_tol) new_var_bounds.update(_new_var_bounds) else: _new_var_bounds = fbbt_con( comp, deactivate_satisfied_constraints= deactivate_satisfied_constraints, update_variable_bounds=update_variable_bounds, integer_tol=integer_tol) new_var_bounds.update(_new_var_bounds) elif comp.type() == Block: _new_var_bounds = fbbt_block( comp, deactivate_satisfied_constraints=deactivate_satisfied_constraints, update_variable_bounds=update_variable_bounds, integer_tol=integer_tol) new_var_bounds.update(_new_var_bounds) else: raise FBBTException( 'Cannot perform FBBT on objects of type {0}'.format(type(comp))) return new_var_bounds
def test_eq(self): cmap1 = ComponentMap() self.assertNotEqual(cmap1, set()) self.assertFalse(cmap1 == set()) self.assertNotEqual(cmap1, list()) self.assertFalse(cmap1 == list()) self.assertNotEqual(cmap1, tuple()) self.assertFalse(cmap1 == tuple()) self.assertEqual(cmap1, dict()) self.assertTrue(cmap1 == dict()) cmap1.update(self._components) self.assertNotEqual(cmap1, set()) self.assertFalse(cmap1 == set()) self.assertNotEqual(cmap1, list()) self.assertFalse(cmap1 == list()) self.assertNotEqual(cmap1, tuple()) self.assertFalse(cmap1 == tuple()) self.assertNotEqual(cmap1, dict()) self.assertFalse(cmap1 == dict()) self.assertTrue(cmap1 == cmap1) self.assertEqual(cmap1, cmap1) cmap2 = ComponentMap(self._components) self.assertTrue(cmap2 == cmap1) self.assertFalse(cmap2 != cmap1) self.assertEqual(cmap2, cmap1) self.assertTrue(cmap1 == cmap2) self.assertFalse(cmap1 != cmap2) self.assertEqual(cmap1, cmap2) del cmap2[self._components[0][0]] self.assertFalse(cmap2 == cmap1) self.assertTrue(cmap2 != cmap1) self.assertNotEqual(cmap2, cmap1) self.assertFalse(cmap1 == cmap2) self.assertTrue(cmap1 != cmap2) self.assertNotEqual(cmap1, cmap2)
def test_eq(self): cmap1 = ComponentMap() self.assertNotEqual(cmap1, set()) self.assertFalse(cmap1 == set()) self.assertNotEqual(cmap1, list()) self.assertFalse(cmap1 == list()) self.assertNotEqual(cmap1, tuple()) self.assertFalse(cmap1 == tuple()) self.assertEqual(cmap1, dict()) self.assertTrue(cmap1 == dict()) cmap1.update(self._components) self.assertNotEqual(cmap1, set()) self.assertFalse(cmap1 == set()) self.assertNotEqual(cmap1, list()) self.assertFalse(cmap1 == list()) self.assertNotEqual(cmap1, tuple()) self.assertFalse(cmap1 == tuple()) self.assertNotEqual(cmap1, dict()) self.assertFalse(cmap1 == dict()) self.assertTrue(cmap1 == cmap1) self.assertEqual(cmap1, cmap1) cmap2 = ComponentMap(self._components) self.assertTrue(cmap2 == cmap1) self.assertFalse(cmap2 != cmap1) self.assertEqual(cmap2, cmap1) self.assertTrue(cmap1 == cmap2) self.assertFalse(cmap1 != cmap2) self.assertEqual(cmap1, cmap2) del cmap2[self._components[0][0]] self.assertFalse(cmap2 == cmap1) self.assertTrue(cmap2 != cmap1) self.assertNotEqual(cmap2, cmap1) self.assertFalse(cmap1 == cmap2) self.assertTrue(cmap1 != cmap2) self.assertNotEqual(cmap1, cmap2)
def fbbt(comp, deactivate_satisfied_constraints=False, integer_tol=1e-5, infeasible_tol=1e-8): """ Perform FBBT on a constraint, block, or model. For more control, use fbbt_con and fbbt_block. For detailed documentation, see the docstrings for fbbt_con and fbbt_block. Parameters ---------- comp: pyomo.core.base.constraint.Constraint or pyomo.core.base.block.Block or pyomo.core.base.PyomoModel.ConcreteModel deactivate_satisfied_constraints: bool If deactivate_satisfied_constraints is True and a constraint is always satisfied, then the constranit will be deactivated integer_tol: float If the lower bound computed on a binary variable is less than or equal to integer_tol, then the lower bound is left at 0. Otherwise, the lower bound is increased to 1. If the upper bound computed on a binary variable is greater than or equal to 1-integer_tol, then the upper bound is left at 1. Otherwise the upper bound is decreased to 0. infeasible_tol: float If the bounds computed on the body of a constraint violate the bounds of the constraint by more than infeasible_tol, then the constraint is considered infeasible and an exception is raised. Returns ------- new_var_bounds: ComponentMap A ComponentMap mapping from variables a tuple containing the lower and upper bounds, respectively, computed from FBBT. """ new_var_bounds = ComponentMap() if comp.type() == Constraint: if comp.is_indexed(): for _c in comp.values(): _new_var_bounds = fbbt_con(comp, deactivate_satisfied_constraints=deactivate_satisfied_constraints, integer_tol=integer_tol, infeasible_tol=infeasible_tol) new_var_bounds.update(_new_var_bounds) else: _new_var_bounds = fbbt_con(comp, deactivate_satisfied_constraints=deactivate_satisfied_constraints, integer_tol=integer_tol, infeasible_tol=infeasible_tol) new_var_bounds.update(_new_var_bounds) elif comp.type() == Block: _new_var_bounds = fbbt_block(comp, deactivate_satisfied_constraints=deactivate_satisfied_constraints, integer_tol=integer_tol, infeasible_tol=infeasible_tol) new_var_bounds.update(_new_var_bounds) else: raise FBBTException('Cannot perform FBBT on objects of type {0}'.format(type(comp))) return new_var_bounds
def test_str(self): cmap = ComponentMap() self.assertEqual(str(cmap), "ComponentMap({})") cmap.update(self._components) str(cmap)
def test_str(self): cmap = ComponentMap() self.assertEqual(str(cmap), "ComponentMap({})") cmap.update(self._components) str(cmap)
def fbbt_block(m, tol=1e-4, deactivate_satisfied_constraints=False, integer_tol=1e-5, infeasible_tol=1e-8): """ Feasibility based bounds tightening (FBBT) for a block or model. This loops through all of the constraints in the block and performs FBBT on each constraint (see the docstring for fbbt_con()). Through this processes, any variables whose bounds improve by more than tol are collected, and FBBT is performed again on all constraints involving those variables. This process is continued until no variable bounds are improved by more than tol. Parameters ---------- m: pyomo.core.base.block.Block or pyomo.core.base.PyomoModel.ConcreteModel tol: float deactivate_satisfied_constraints: bool If deactivate_satisfied_constraints is True and a constraint is always satisfied, then the constranit will be deactivated integer_tol: float If the lower bound computed on a binary variable is less than or equal to integer_tol, then the lower bound is left at 0. Otherwise, the lower bound is increased to 1. If the upper bound computed on a binary variable is greater than or equal to 1-integer_tol, then the upper bound is left at 1. Otherwise the upper bound is decreased to 0. infeasible_tol: float If the bounds computed on the body of a constraint violate the bounds of the constraint by more than infeasible_tol, then the constraint is considered infeasible and an exception is raised. Returns ------- new_var_bounds: ComponentMap A ComponentMap mapping from variables a tuple containing the lower and upper bounds, respectively, computed from FBBT. """ new_var_bounds = ComponentMap() var_to_con_map = ComponentMap() var_lbs = ComponentMap() var_ubs = ComponentMap() for c in m.component_data_objects(ctype=Constraint, active=True, descend_into=True, sort=True): for v in identify_variables(c.body): if v not in var_to_con_map: var_to_con_map[v] = list() if v.lb is None: var_lbs[v] = -math.inf else: var_lbs[v] = value(v.lb) if v.ub is None: var_ubs[v] = math.inf else: var_ubs[v] = value(v.ub) var_to_con_map[v].append(c) for _v in m.component_data_objects(ctype=Var, active=True, descend_into=True, sort=True): if _v.is_fixed(): _v.setlb(_v.value) _v.setub(_v.value) new_var_bounds[_v] = (_v.value, _v.value) improved_vars = ComponentSet() for c in m.component_data_objects(ctype=Constraint, active=True, descend_into=True, sort=True): _new_var_bounds = fbbt_con( c, deactivate_satisfied_constraints=deactivate_satisfied_constraints, integer_tol=integer_tol, infeasible_tol=infeasible_tol) new_var_bounds.update(_new_var_bounds) for v, bnds in _new_var_bounds.items(): vlb, vub = bnds if vlb is not None: if vlb > var_lbs[v] + tol: improved_vars.add(v) var_lbs[v] = vlb if vub is not None: if vub < var_ubs[v] - tol: improved_vars.add(v) var_ubs[v] = vub while len(improved_vars) > 0: v = improved_vars.pop() for c in var_to_con_map[v]: _new_var_bounds = fbbt_con(c, deactivate_satisfied_constraints= deactivate_satisfied_constraints, integer_tol=integer_tol, infeasible_tol=infeasible_tol) new_var_bounds.update(_new_var_bounds) for _v, bnds in _new_var_bounds.items(): _vlb, _vub = bnds if _vlb is not None: if _vlb > var_lbs[_v] + tol: improved_vars.add(_v) var_lbs[_v] = _vlb if _vub is not None: if _vub < var_ubs[_v] - tol: improved_vars.add(_v) var_ubs[_v] = _vub return new_var_bounds
def fbbt_block(m, tol=1e-4, deactivate_satisfied_constraints=False, integer_tol=1e-5, infeasible_tol=1e-8): """ Feasibility based bounds tightening (FBBT) for a block or model. This loops through all of the constraints in the block and performs FBBT on each constraint (see the docstring for fbbt_con()). Through this processes, any variables whose bounds improve by more than tol are collected, and FBBT is performed again on all constraints involving those variables. This process is continued until no variable bounds are improved by more than tol. Parameters ---------- m: pyomo.core.base.block.Block or pyomo.core.base.PyomoModel.ConcreteModel tol: float deactivate_satisfied_constraints: bool If deactivate_satisfied_constraints is True and a constraint is always satisfied, then the constranit will be deactivated integer_tol: float If the lower bound computed on a binary variable is less than or equal to integer_tol, then the lower bound is left at 0. Otherwise, the lower bound is increased to 1. If the upper bound computed on a binary variable is greater than or equal to 1-integer_tol, then the upper bound is left at 1. Otherwise the upper bound is decreased to 0. infeasible_tol: float If the bounds computed on the body of a constraint violate the bounds of the constraint by more than infeasible_tol, then the constraint is considered infeasible and an exception is raised. Returns ------- new_var_bounds: ComponentMap A ComponentMap mapping from variables a tuple containing the lower and upper bounds, respectively, computed from FBBT. """ new_var_bounds = ComponentMap() var_to_con_map = ComponentMap() var_lbs = ComponentMap() var_ubs = ComponentMap() for c in m.component_data_objects(ctype=Constraint, active=True, descend_into=True, sort=True): for v in identify_variables(c.body): if v not in var_to_con_map: var_to_con_map[v] = list() if v.lb is None: var_lbs[v] = -math.inf else: var_lbs[v] = value(v.lb) if v.ub is None: var_ubs[v] = math.inf else: var_ubs[v] = value(v.ub) var_to_con_map[v].append(c) for _v in m.component_data_objects(ctype=Var, active=True, descend_into=True, sort=True): if _v.is_fixed(): _v.setlb(_v.value) _v.setub(_v.value) new_var_bounds[_v] = (_v.value, _v.value) improved_vars = ComponentSet() for c in m.component_data_objects(ctype=Constraint, active=True, descend_into=True, sort=True): _new_var_bounds = fbbt_con(c, deactivate_satisfied_constraints=deactivate_satisfied_constraints, integer_tol=integer_tol, infeasible_tol=infeasible_tol) new_var_bounds.update(_new_var_bounds) for v, bnds in _new_var_bounds.items(): vlb, vub = bnds if vlb is not None: if vlb > var_lbs[v] + tol: improved_vars.add(v) var_lbs[v] = vlb if vub is not None: if vub < var_ubs[v] - tol: improved_vars.add(v) var_ubs[v] = vub while len(improved_vars) > 0: v = improved_vars.pop() for c in var_to_con_map[v]: _new_var_bounds = fbbt_con(c, deactivate_satisfied_constraints=deactivate_satisfied_constraints, integer_tol=integer_tol, infeasible_tol=infeasible_tol) new_var_bounds.update(_new_var_bounds) for _v, bnds in _new_var_bounds.items(): _vlb, _vub = bnds if _vlb is not None: if _vlb > var_lbs[_v] + tol: improved_vars.add(_v) var_lbs[_v] = _vlb if _vub is not None: if _vub < var_ubs[_v] - tol: improved_vars.add(_v) var_ubs[_v] = _vub return new_var_bounds