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)
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