Beispiel #1
0
 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)
Beispiel #2
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)
Beispiel #3
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)
Beispiel #4
0
 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)
Beispiel #5
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)
Beispiel #6
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))
Beispiel #7
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)
Beispiel #8
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))
Beispiel #9
0
    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
Beispiel #10
0
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
Beispiel #11
0
    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)
Beispiel #12
0
    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)
Beispiel #13
0
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
Beispiel #14
0
 def test_str(self):
     cmap = ComponentMap()
     self.assertEqual(str(cmap), "ComponentMap({})")
     cmap.update(self._components)
     str(cmap)
Beispiel #15
0
 def test_str(self):
     cmap = ComponentMap()
     self.assertEqual(str(cmap), "ComponentMap({})")
     cmap.update(self._components)
     str(cmap)
Beispiel #16
0
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
Beispiel #17
0
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