示例#1
0
 def test_countable_outcomes_user_can_return_all_queries(self, neg):
     for s in (
         "exact",
         "bisection",
         "titration+0.05",
         "titration-0.5",
         "dtitration+0.5",
         "dtitration-0.05",
         "pingpong0.5",
         "dpingpong0.5",
     ):
         user = User(ufun=ufun, cost=cost)
         strategy = EStrategy(strategy=s)
         strategy.on_enter(neg.ami)
         q = possible_queries(ami=neg.ami, strategy=strategy, user=user)
         assert (
             len(q) > 0 and s != "exact" or len(q) == 0 and s == "exact"
         ), "returns some queries"
示例#2
0
 def test_elicitor_can_get_frontier(self, data_folder):
     domain, agents_info, issues = load_genius_domain_from_folder(
         os.path.join(data_folder, "Laptop"),
         force_single_issue=True,
         keep_issue_names=False,
         keep_value_names=False,
         normalize_utilities=True,
     )
     assert len(issues) == 1
     assert len(agents_info) == 2
     domain.add(LimitedOutcomesNegotiator(), ufun=agents_info[0]["ufun"])
     user = User(ufun=agents_info[0]["ufun"], cost=cost)
     strategy = EStrategy(strategy="titration-0.5")
     strategy.on_enter(ami=domain.ami)
     elicitor = FullKnowledgeElicitor(strategy=strategy, user=user)
     domain.add(elicitor)
     front, _ = domain.pareto_frontier()
     assert front == [(1.0, 1.0)]
示例#3
0
 def test_elicitor_can_run_from_genius_domain(self, data_folder):
     domain, agents_info, issues = load_genius_domain_from_folder(
         os.path.join(data_folder, "Laptop"),
         force_single_issue=True,
         keep_issue_names=False,
         keep_value_names=False,
         normalize_utilities=True,
     )
     domain.add(LimitedOutcomesNegotiator(), ufun=agents_info[0]["ufun"])
     # domain.n_steps = 10
     user = User(ufun=agents_info[0]["ufun"], cost=0.2)
     strategy = EStrategy(strategy="titration-0.5")
     strategy.on_enter(ami=domain.ami)
     elicitor = PandoraElicitor(strategy=strategy, user=user)
     domain.add(elicitor)
     front, _ = domain.pareto_frontier()
     domain.run()
     assert len(domain.history) > 0
示例#4
0
def master(true_utilities, strategy_name="titration-0.05"):
    user = User(
        ufun=MappingUtilityFunction(
            dict(zip([(_,) for _ in range(n_outcomes)], true_utilities)),
            reserved_value=0.0,
        ),
        cost=cost,
    )
    strategy = EStrategy(strategy=strategy_name)
    return user, strategy
示例#5
0
    def test_countable_outcmoes_user_can_elicit_bisection(self, neg, user):
        strategy = EStrategy(strategy="bisection", resolution=1e-4)
        strategy.on_enter(neg.ami)
        elicited = []
        estimated = []
        total_cost = 0.0
        while True:
            e = strategy.utility_estimate((0,))
            # assert user.total_cost <= total_cost + cost, 'incorrect total cost'
            u, reply = strategy.apply(user=user, outcome=(0,))
            if isinstance(u, float) or u.scale < cost:
                assert abs(u - utility) < 1e-2
                break
            total_cost += cost
            elicited.append(u)
            estimated.append(e)

        assert elicited[0].loc == 0.0, "first loc is incorrect in elicitation"
        assert elicited[0].scale == 0.5, "first scale is incorrect in elicitation"
        assert estimated[0].loc == 0.0, "first loc is incorrect in estimation"
        assert estimated[0].scale == 1.0, "first scale is incorrect in estimation"
        for u, e in zip(elicited, estimated):
            assert u.scale == 0.5 * e.scale, "uncertainty is not decreasing as expected"
        for i in range(len(elicited) - 1):
            assert (
                elicited[i + 1].scale == 0.5 * elicited[i].scale
            ), "uncertainty is not decreasing"
        for i in range(len(estimated) - 1):
            assert (
                estimated[i + 1].scale == 0.5 * estimated[i].scale
            ), "uncertainty is not decreasing"
示例#6
0
    def test_countable_outcmoes_user_can_elicit_dtitration_down(self, neg, user):
        step = -0.05
        strategy = EStrategy(strategy=f"dtitration{step}", resolution=1e-4)
        strategy.on_enter(neg.ami)
        elicited = []
        estimated = []
        total_cost = 0.0
        while True:
            e = strategy.utility_estimate((0,))
            # assert user.total_cost <= total_cost + cost, 'incorrect total cost'
            u, reply = strategy.apply(user=user, outcome=(0,))
            if isinstance(u, float) or u.scale < cost:
                assert abs(u - utility) < -step * 2
                break
            total_cost += cost
            elicited.append(u)
            estimated.append(e)

        step = -step
        assert (
            elicited[0].loc + elicited[0].scale == 1.0 - step
        ), "first loc is incorrect in elicitation"
        assert (
            elicited[0].scale == 1.0 - step
        ), "first scale is incorrect in elicitation"
        assert estimated[0].loc == 0.0, "first loc is incorrect in estimation"
        assert estimated[0].scale == 1.0, "first scale is incorrect in estimation"
示例#7
0
    def test_countable_outcmoes_user_can_elicit_titration_up(self, neg, user):
        step = 0.05
        strategy = EStrategy(strategy=f"titration+{step}", resolution=1e-4)
        strategy.on_enter(neg.ami)
        elicited = []
        estimated = []
        total_cost = 0.0
        while True:
            e = strategy.utility_estimate((0, ))
            assert user.total_cost == total_cost, "incorrect total cost"
            u, reply = strategy.apply(user=user, outcome=(0, ))
            if isinstance(u, float) or u.scale < cost:
                assert abs(u - utility) < step * 2
                break
            total_cost += cost
            elicited.append(u)
            estimated.append(e)

        assert elicited[0].loc == step, "first loc is incorrect in elicitation"
        assert (elicited[0].scale == 1.0 -
                step), "first scale is incorrect in elicitation"
        assert estimated[0].loc == 0.0, "first loc is incorrect in estimation"
        assert estimated[
            0].scale == 1.0, "first scale is incorrect in estimation"
        for u, e in zip(elicited[:-1], estimated[:-1]):
            assert (abs(u.scale - e.scale + step) <
                    1e-3), "uncertainty is not decreasing as expected"
        for i in range(len(elicited) - 2):
            assert (abs(elicited[i + 1].scale - elicited[i].scale + step) <
                    1e-3), "uncertainty is not decreasing"
        for i in range(len(estimated) - 2):
            assert (estimated[i + 1].scale - estimated[i].scale +
                    step) < 1e-3, "uncertainty is not decreasing"
示例#8
0
 def test_elicit_until(self, neg):
     for s in ("bisection", "titration+0.05", "titration-0.05", "pingpong"):
         user = User(ufun=ufun, cost=cost)
         stretegy = EStrategy(strategy=s, resolution=1e-3)
         stretegy.on_enter(neg.ami)
         outcome, query, qcost = next_query(
             strategy=stretegy, outcome=(0,), user=user
         )[0]
         stretegy.until(
             user=user, outcome=(0,), dist=query.answers[1].constraint.marginal((0,))
         )
示例#9
0
    def test_countable_outcmoes_user_can_elicit_titration_up_no_step(self, neg, user):
        step = 0.01
        strategy = EStrategy(strategy=f"titration", resolution=step)
        strategy.on_enter(neg.ami)
        elicited = []
        estimated = []
        total_cost = 0.0
        for _ in range(int(0.5 + 1.0 / step) + 2):
            e = strategy.utility_estimate((0,))
            # assert user.total_cost <= total_cost + cost, 'incorrect total cost'
            u, reply = strategy.apply(user=user, outcome=(0,))
            if isinstance(u, float) or u.scale < cost:
                u = float(u)
                assert abs(u - utility) < 2 * step
                break
            total_cost += cost
            elicited.append(u)
            estimated.append(e)
        else:
            # print(elicited)
            assert False, "did not end in expected time"

        assert elicited[0].loc == step, "first loc is incorrect in elicitation"
        assert (
            elicited[0].scale == 1.0 - step
        ), "first scale is incorrect in elicitation"
        assert estimated[0].loc == 0.0, "first loc is incorrect in estimation"
        assert estimated[0].scale == 1.0, "first scale is incorrect in estimation"
        for u, e in zip(elicited[:-1], estimated[:-1]):
            assert (
                abs(u.scale - e.scale + step) < 1e-3
            ), "uncertainty is not decreasing as expected"
        for i in range(len(elicited) - 2):
            assert (
                abs(elicited[i + 1].scale - elicited[i].scale + step) < 1e-3
            ), "uncertainty is not decreasing"
        for i in range(len(estimated) - 2):
            assert (
                estimated[i + 1].scale - estimated[i].scale + step
            ) < 1e-3, "uncertainty is not decreasing"
示例#10
0
 def test_pareto_frontier_2(self):
     n_outcomes = 10
     strategy = "titration-0.5"
     cost = 0.01
     reserved_value = 0.1
     outcomes = [(_,) for _ in range(n_outcomes)]
     accepted = [(2,), (3,), (4,), (5,)]
     elicitor_utilities = [
         0.5337723805661662,
         0.8532272031479199,
         0.4781281413197942,
         0.7242899747791032,
         0.3461879818432919,
         0.2608677043479706,
         0.9419131964655383,
         0.29368079952747694,
         0.6093201983562316,
         0.7066918086398718,
     ]
     # list(np.random.rand(n_outcomes).tolist())
     opponent_utilities = [
         1.0 if (_,) in accepted else 0.0 for _ in range(n_outcomes)
     ]
     frontier, frontier_locs = pareto_frontier(
         [
             MappingUtilityFunction(
                 lambda o: elicitor_utilities[o[0]],
                 reserved_value=reserved_value,
                 outcome_type=tuple,
             ),
             MappingUtilityFunction(
                 lambda o: opponent_utilities[o[0]],
                 reserved_value=reserved_value,
                 outcome_type=tuple,
             ),
         ],
         outcomes=outcomes,
         sort_by_welfare=True,
     )
     welfare = (
         np.asarray(elicitor_utilities) + np.asarray(opponent_utilities)
     ).tolist()
     # print(f'frontier: {frontier}\nmax. welfare: {max(welfare)} at outcome: ({welfare.index(max(welfare))},)')
     # print(f'frontier_locs: frontier_locs')
     neg = SAOMechanism(outcomes=n_outcomes, n_steps=10, outcome_type=tuple)
     opponent = LimitedOutcomesNegotiator(
         acceptable_outcomes=accepted,
         acceptance_probabilities=[1.0] * len(accepted),
     )
     eufun = MappingUtilityFunction(
         dict(zip(outcomes, elicitor_utilities)),
         reserved_value=reserved_value,
         outcome_type=tuple,
     )
     user = User(ufun=eufun, cost=cost)
     strategy = EStrategy(strategy=strategy)
     strategy.on_enter(ami=neg.ami)
     elicitor = FullKnowledgeElicitor(strategy=strategy, user=user)
     neg.add(opponent)
     neg.add(elicitor)
     neg.run()
     f2, f2_outcomes = neg.pareto_frontier(sort_by_welfare=True)
     assert len(frontier) == len(f2)
     assert all([_1 == _2] for _1, _2 in zip(frontier, f2))
     assert [_[0] for _ in f2_outcomes] == frontier_locs
示例#11
0
def strategy(neg: SAOMechanism) -> EStrategy:
    s = EStrategy(strategy="exact")
    s.on_enter(ami=neg.ami)
    return s