def test_multiple_issues_can_get_constrained(self): low_util_dict = {"issue2_0": -1000, "issue0_1": -1000} self.generator.add_utilities(low_util_dict) self.assertTrue( {AtomicConstraint("issue2", "0"), AtomicConstraint("issue0", "1")}.issubset(self.generator.constraints))
def test_wont_add_violating_offers_to_the_queue(self): self.neg_space, self.utilities, _ = neg_scenario_from_util_matrices( arange(6).reshape((1, 6))**2, arange(6).reshape((1, 6))) self.arbitrary_reservation_value = 0 self.non_agreement_cost = -1000 self.max_util = 6**2 self.constr_value = -2 * self.max_util self.uniform_weights = { issue: 1 / len(self.neg_space.keys()) for issue in self.neg_space.keys() } self.evaluator = ConstrainedLinearEvaluator( self.utilities, self.uniform_weights, self.non_agreement_cost, self.constr_value, {AtomicConstraint("issue0", "2")}) self.generator = ConstrainedEnumGenerator( self.neg_space, self.utilities, self.evaluator, self.arbitrary_reservation_value, self.constr_value, {AtomicConstraint("issue0", "2")}) offer_list = [] for i in range(5): offer_list.append(self.generator.generate_offer()) self.assertTrue( all([ self.generator.satisfies_all_constraints(offer) for offer in offer_list ])) with self.assertRaises(StopIteration): self.generator.generate_offer()
def test_multiple_issues_can_get_constrained(self): low_util_dict = {"integer_4": -100000, "'float_0.9'": -100000} self.generator.add_utilities(low_util_dict) self.assertTrue({ AtomicConstraint("integer", "4"), AtomicConstraint("float", "0.9") }.issubset(self.generator.constraints))
class TestAtomicConstraint(unittest.TestCase): def setUp(self): self.test_atomic_constraint = AtomicConstraint("dummy1", "True") def test_no_good_with_different_issue_are_unequal(self): other = AtomicConstraint("Dummy1", "True") self.assertFalse(self.test_atomic_constraint == other) def test_no_good_with_different_value_are_unequal(self): other = AtomicConstraint("dummy1", "False") self.assertFalse(self.test_atomic_constraint == other) def test_equal_no_goods_are_equal(self): self.assertTrue(self.test_atomic_constraint, self.test_atomic_constraint) def test_dict_of_no_good_contains_it(self): d = {self.test_atomic_constraint: "hello World"} self.assertTrue(self.test_atomic_constraint in d.keys()) def test_satisfying_value_returns_true(self): self.assertTrue( self.test_atomic_constraint.is_satisfied_by_assignment( "dummy1", "False")) def test_non_satisfying_value_returns_false(self): self.assertFalse( self.test_atomic_constraint.is_satisfied_by_assignment( "dummy1", "True")) def test_no_good_is_not_equal_to_other_type_object(self): self.assertFalse(self.test_atomic_constraint == "string")
def setUp(self): self.generic_offer = Offer({ "first": { "True": 1 }, "second": { "False": 1 }, "third": { "-3": 1 }, "forth": { "1.8": 1 } }) self.empty_message = Message("A", "B", MessageType.EMPTY, None) self.accept_message = Message("A", "B", MessageType.ACCEPT, self.generic_offer) self.termination_message = Message("A", "B", MessageType.EXIT, None) self.constraint_message = Message("A", "B", MessageType.OFFER, self.generic_offer, AtomicConstraint("dummy1", "True")) self.offer_message = Message("A", "B", MessageType.OFFER, self.generic_offer) self.offer_string = "[first->True, second->False, third->-3, forth->1.8]" self.offer_message_string = "(A=>B;OFFER;{offer})".format( offer=self.offer_string) self.empty_message_string = "(A=>B;EMPTY)".format( offer=self.offer_string) self.accept_message_string = "(A=>B;ACCEPT;{})".format( self.offer_string) self.constraint_message_string = "(A=>B;OFFER;{offer};{constraint})".format( offer=self.offer_string, constraint=AtomicConstraint("dummy1", "True")) self.termination_message_string = "(A=>B;EXIT)"
def test_responds_to_violating_offer_with_constraint(self): self.generator.add_constraint(AtomicConstraint("boolean", "True")) constr = self.generator.find_violated_constraint(self.violating_offer) self.assertTrue(constr in { AtomicConstraint("boolean", "True"), AtomicConstraint("integer", "5") })
def test_generates_valid_offers_when_constraints_are_present(self): self.generator.add_constraints({ AtomicConstraint("issue0", "2"), AtomicConstraint("issue1", "2"), AtomicConstraint("issue2", "2") }) generated_offer = self.generator.generate_offer() self.generator.satisfies_all_constraints(generated_offer)
def test_terminates_after_constrains_become_unsatisfiable(self): self.generator.add_constraints({ AtomicConstraint("boolean", "True"), AtomicConstraint("boolean", "False") }) with self.assertRaises(StopIteration): _ = self.generator.generate_offer()
def test_terminates_after_constrains_become_unsatisfiable(self): self.generator.add_constraints({ AtomicConstraint("issue0", "0"), AtomicConstraint("issue0", "1"), AtomicConstraint("issue0", "2") }) with self.assertRaises(StopIteration): _ = self.generator.generate_offer()
def discover_constraints(self) -> Set[AtomicConstraint]: """ Attempts to deduce new constraints from the current knowledge base. see :ref:`constraint-discovery` for more information. :return: A set containing all the newly discovered constraints. :rtype: Set[AtomicConstraint] """ new_constraints = set() for issue in self.neg_space.keys(): best_case = sum([ bc for i, bc in self.max_utility_by_issue.items() if i != issue ]) for value in self.neg_space[issue]: atom = atom_from_issue_value(issue, value) if atom in self.utilities.keys(): value_util = self.utilities[atom] else: value_util = 0 if best_case + value_util < self.acceptability_threshold: new_constraints.add(AtomicConstraint(issue, value)) return new_constraints
def find_violated_constraint(self, offer: Offer) -> Optional[AtomicConstraint]: for constr in self.constraints: for issue in offer.get_issues(): chosen_value = offer.get_chosen_value(issue) if not constr.is_satisfied_by_assignment(issue, chosen_value): return AtomicConstraint(issue, chosen_value) return None
def test_sorts_utils_correctly_with_initial_constraints(self): self.neg_space, self.utilities, _ = neg_scenario_from_util_matrices( arange(6).reshape((2, 3))**2, arange(6).reshape((2, 3))) self.arbitrary_reservation_value = 0 self.non_agreement_cost = -1000 self.max_util = 9**2 self.constr_value = -2 * self.max_util self.uniform_weights = { issue: 1 / len(self.neg_space.keys()) for issue in self.neg_space.keys() } self.evaluator = ConstrainedLinearEvaluator( self.utilities, self.uniform_weights, self.non_agreement_cost, self.constr_value, {AtomicConstraint("issue0", "2")}) self.generator = ConstrainedEnumGenerator( self.neg_space, self.utilities, self.evaluator, self.arbitrary_reservation_value, self.constr_value, {AtomicConstraint("issue0", "2")}) self.generator.generate_offer()
def test_all_offers_are_generated_in_dec_order_of_util(self): temp_neg_space = { "boolean": ["True", "False"], "integer": list(map(str, range(10))), "float": ["{0:.1f}".format(0.1 * i) for i in range(10)] } temp_utilities = { "boolean_True": 1000.0, "boolean_False": 10.0, "integer_9": 100.0, "integer_3": 10.0, "integer_1": 0.1, "integer_4": -10.0, "integer_5": -100.0, "'float_0.1'": 1.0 } temp_reservation_value = -(10**10.0) + 1 temp_non_agreement_cost = -(10**10.0) temp_contr = AtomicConstraint("integer", "8") evaluator = ConstrainedLinearEvaluator( temp_utilities, {issue: 1 for issue in temp_neg_space.keys()}, temp_non_agreement_cost, self.constr_value, set()) generator = ConstrainedEnumGenerator(temp_neg_space, temp_utilities, evaluator, temp_reservation_value, self.constr_value, set(), False) generator.add_constraint(temp_contr) temp_unconstrained_neg_space = deepcopy(temp_neg_space) for constr in generator.constraints: del temp_unconstrained_neg_space[constr.issue][ temp_unconstrained_neg_space[constr.issue].index(constr.value)] neg_space_size = reduce(lambda x, y: x * y, [ len(temp_unconstrained_neg_space[issue]) for issue in temp_unconstrained_neg_space.keys() ]) offer = generator.generate_offer() util = evaluator.calc_offer_utility(offer) transcript = [(offer, util)] for i in range(neg_space_size - 1): offer = generator.generate_offer() util = evaluator.calc_offer_utility(offer) transcript.append((offer, util)) self.assertTrue(transcript[-1][1] <= transcript[-2][1], transcript)
def setUp(self): self.neg_space, self.utilities, _ = neg_scenario_from_util_matrices( arange(9).reshape((3, 3))**2, arange(9).reshape((3, 3))) self.arbitrary_reservation_value = 0 self.non_agreement_cost = -1000 self.max_util = 4 + 25 + 64 self.constr_value = -2 * self.max_util self.uniform_weights = { issue: 1 / len(self.neg_space.keys()) for issue in self.neg_space.keys() } self.evaluator = ConstrainedLinearEvaluator(self.utilities, self.uniform_weights, self.non_agreement_cost, self.constr_value, set()) self.violating_offer = Offer({ "issue0": { "0": 0.0, "1": 0.0, "2": 1.0 }, "issue1": { "0": 0.0, "1": 0.0, "2": 1.0 }, "issue2": { "0": 0.0, "1": 0.0, "2": 1.0 } }) self.generator = ConstrainedEnumGenerator( self.neg_space, self.utilities, self.evaluator, self.arbitrary_reservation_value, self.constr_value, set()) self.difficult_constraint = AtomicConstraint("issue2", "2") self.generator.add_constraint(self.difficult_constraint)
def test_get_constraint(self): self.assertEqual(self.constraint_message.get_constraint(), AtomicConstraint("dummy1", "True"))
def setUp(self): self.test_atomic_constraint = AtomicConstraint("dummy1", "True")
def test_getting_utility_below_threshold_creates_constraint(self): low_util_dict = {"integer_4": -10000} self.generator.add_utilities(low_util_dict) self.assertTrue( AtomicConstraint("integer", "4") in self.generator.constraints, self.generator.constraints)
def test_own_offer_does_not_violate_constraint(self): self.generator.add_constraint(AtomicConstraint("boolean", "True")) generated_offer = self.generator.generate_offer() self.assertTrue( self.generator.satisfies_all_constraints(generated_offer))
def setUp(self): self.asdf_name = "A" self.opponent_name = "B" self.neg_space = { "boolean": [True, False], "integer": list(range(10)), "float": [float("{0:.2f}".format(0.1 * i)) for i in range(10)] } self.utilities = { "boolean_True": 100, "boolean_False": 10, "integer_9": 100, "integer_3": 10, "integer_1": 0.1, "integer_4": -10, "integer_5": -100, "'float_0.1'": 1 } self.reservation_value = 0 self.non_agreement_cost = -1000 # should have a utility of 100 self.nested_test_offer = { "boolean": {"True": 1, "False": 0}, "integer": {str(i): 0 for i in range(10)}, "float": {"{0:.1f}".format(i * 0.1): 0 for i in range(10)} } self.nested_test_offer["integer"]["2"] = 1 self.nested_test_offer['float']["0.6"] = 1 self.nested_test_offer = Offer(self.nested_test_offer) self.optimal_offer = { "boolean": {"True": 1.0, "False": 0.0}, "integer": {str(i): 0.0 for i in range(10)}, "float": {"{0:.1f}".format(i * 0.1): 0.0 for i in range(10)} } self.optimal_offer["integer"]["9"] = 1.0 self.optimal_offer['float']["0.1"] = 1.0 self.optimal_offer = Offer(self.optimal_offer) self.max_util = 100 + 100 + 1 self.constr_value = -2 * self.max_util self.violating_offer = { "boolean": {"True": 1.0, "False": 0.0}, "integer": {str(i): 0.0 for i in range(10)}, "float": {"{0:.1f}".format(i * 0.1): 0.0 for i in range(10)} } self.violating_offer["integer"]["2"] = 1.0 self.violating_offer['float']["0.1"] = 1.0 self.violating_offer = Offer(self.violating_offer) self.uniform_strat = Strategy({ "boolean": {"True": 0.5, "False": 0.5}, "integer": {str(i): 0.1 for i in range(10)}, "float": {"{0:.1f}".format(i * 0.1): 0.1 for i in range(10)} }) self.uniform_weights = { issue: 1 / len(self.neg_space.keys()) for issue in self.neg_space.keys()} self.evaluator = ConstrainedLinearEvaluator( self.utilities, self.uniform_weights, self.non_agreement_cost, self.constr_value, set([])) self.boolean_constraint = AtomicConstraint("boolean", "True") self.integer_constraint = AtomicConstraint("integer", "2")
def test_no_good_with_different_issue_are_unequal(self): other = AtomicConstraint("Dummy1", "True") self.assertFalse(self.test_atomic_constraint == other)
def setUp(self): self.agent_name = "A" self.opponent_name = "B" self.neg_space = { "boolean": [True, False], "integer": list(range(10)), "float": [float("{0:.2f}".format(0.1 * i)) for i in range(10)] } self.utilities = { "boolean_True": 100, "boolean_False": 10, "integer_9": 100, "integer_3": 10, "integer_1": 0.1, "integer_4": -10, "integer_5": -100, "'float_0.1'": 1 } self.kb = [ "boolean_True :- integer_2, 'float_0.1'." ] self.reservation_value = 0 self.non_agreement_cost = -1000 # should have a utility of 100 self.nested_test_offer = { "boolean": {"True": 1, "False": 0}, "integer": {str(i): 0 for i in range(10)}, "float": {"{0:.1f}".format(i * 0.1): 0 for i in range(10)} } self.nested_test_offer["integer"]["3"] = 1 self.nested_test_offer['float']["0.6"] = 1 self.nested_test_offer = Offer(self.nested_test_offer) self.optimal_offer = { "boolean": {"True": 1.0, "False": 0.0}, "integer": {str(i): 0.0 for i in range(10)}, "float": {"{0:.1f}".format(i * 0.1): 0.0 for i in range(10)} } self.optimal_offer["integer"]["9"] = 1.0 self.optimal_offer['float']["0.1"] = 1.0 self.optimal_offer = Offer(self.optimal_offer) self.max_util = 100 + 100 + 1 self.constr_value = -2 * self.max_util self.arbitrary_utilities = { "boolean_True": 100, "integer_2": -1000, "'float_0.1'": -3.2, "'float_0.5'": pi } self.violating_offer = { "boolean": {"True": 1, "False": 0}, "integer": {str(i): 0 for i in range(10)}, "float": {"{0:.1f}".format(i * 0.1): 0 for i in range(10)} } self.violating_offer["integer"]["2"] = 1 self.violating_offer['float']["0.6"] = 1 self.violating_offer = Offer(self.violating_offer) self.evaluator = ConstrainedProblogEvaluator( self.neg_space, self.utilities, self.non_agreement_cost, self.kb, self.constr_value, set([])) self.boolean_constraint = AtomicConstraint("boolean", "True") self.integer_constraint = AtomicConstraint("integer", "2")
def test_factory_correctly_determines_constraints(self): agent_a = make_constrained_linear_concession_agent("A", self.neg_space, self.utilities, 0.5, self.non_agreement_cost, set(), None) self.assertTrue(AtomicConstraint("integer","5") in agent_a.get_constraints())