예제 #1
0
    def test_init_from_constraints_as_functions(self):
        domain = list(range(3))
        x1 = Variable('x1', domain)
        x2 = Variable('x2', domain)

        @AsNAryFunctionRelation(x1, x2)
        def phi(x1_, x2_):
            return x1_ + x2_

        g = GdbaComputation(x1, [phi], comp_def=MagicMock())

        m = NAryMatrixRelation.from_func_relation(phi)
        (c_mat, mini, maxi) = g.__constraints__[0]
        self.assertEqual(c_mat, m)
        self.assertEqual(mini, 0)
        self.assertEqual(maxi, 4)
예제 #2
0
    def __init__(self,
                 variable: Variable,
                 constraints: Iterable[RelationProtocol],
                 mode='min',
                 modifier='A',
                 violation='NZ',
                 increase_mode='E',
                 msg_sender=None,
                 logger=None,
                 comp_def=None):
        """
        :param variable: a variable object for which this computation is
        responsible
        :param constraints: the list of constraints involving this variable
        :param modifier: The manner to modify costs. 'A' (resp. 'M') for
        additive (resp. multiplicative) manner. Defaults to 'A'
        :param violation: The criteria to determine a constraint violation.
        Defaults to 'NZ'
        :param increase_mode: The increase mode of a constraint cost
        describes which modifiers should be increased.
        Defaults to 'E'
        """

        super().__init__(variable, comp_def)
        self._msg_handlers['gdba_ok'] = self._on_ok_msg
        self._msg_handlers['gdba_improve'] = self._on_improve_message

        self._msg_sender = msg_sender
        self.logger = logger if logger is not None \
            else logging.getLogger('pydcop.algo.gdba.' + variable.name)

        # Handling messages arriving during wrong mode
        self.__postponed_improve_messages__ = []
        self.__postponed_ok_messages__ = []

        self._waiting_mode = 'starting'
        self._mode = mode
        self._modifier_mode = modifier
        self._violation_mode = violation
        self._increase_mode = increase_mode
        base_modifier = 0 if self._modifier_mode == 'A' else 1
        self.__constraints__ = list()
        self.__constraints_modifiers__ = dict()
        # Transform the constraints in matrices, with also the min and max
        # values recorded
        for c in constraints:
            if type(c) != NAryMatrixRelation:
                rel_mat = NAryMatrixRelation.from_func_relation(c)
                c_array = rel_mat._m.flat
                maxi = c_array[0]
                mini = c_array[0]
                for i in c_array:
                    if i > maxi:
                        maxi = i
                    if i < mini:
                        mini = i
                rel = (rel_mat, mini, maxi)
            else:
                c_array = c._m.flat
                maxi = c_array[0]
                mini = c_array[0]
                for i in c_array:
                    if i > maxi:
                        maxi = i
                    if i < mini:
                        mini = i
                rel = (c, mini, maxi)
            self.__constraints__.append(rel)
            # The modifiers for constraints. It is a Dictionary of dictionary
            # (of dictionary ... regarding the arity of each constraint). It
            # represents the value of the modifier for each constraint asgt.
            self.__constraints_modifiers__[rel[0]] = defaultdict(
                lambda: base_modifier)

        self._violated_constraints = []
        # some constraints might be unary, and our variable can have several
        # constraints involving the same variable
        self._neighbors = set(
            [v for c in constraints for v in c.dimensions if v != variable])
        # Agent view of its neighbors resp. for ok and improve modes
        self._neighbors_values = {}
        self._neighbors_improvements = {}
        self._my_improve = 0  # Possible improvement the agent can realize
        self._new_value = None