Ejemplo n.º 1
0
 def test_elicitor_runs(
     self, elicitor: Union[str, "BaseElicitor"], master, true_utilities, **kwargs
 ):
     neg = SAOMechanism(outcomes=n_outcomes, n_steps=10)
     user, strategy = master
     opponent = LimitedOutcomesNegotiator(
         acceptable_outcomes=accepted,
         acceptance_probabilities=[1.0] * len(accepted),
     )
     strategy.on_enter(ami=neg.ami)
     if isinstance(elicitor, str):
         elicitor = f"negmas.elicitation.{elicitor}"
         if "VOI" in elicitor:
             kwargs["dynamic_query_set"] = True
         elicitor = instantiate(elicitor, strategy=strategy, user=user, **kwargs)
     neg.add(opponent)
     neg.add(elicitor)
     assert elicitor.elicitation_cost == 0.0
     neg.run()
     queries = list(elicitor.user.elicited_queries())
     assert len(neg.history) > 0
     assert neg.agreement is None or neg.agreement in accepted
     assert (
         elicitor.elicitation_cost > 0.0
         or cost == 0.0
         or elicitor.strategy is None
         or neg.state.step < 2
     )
     if neg.agreement is not None:
         assert (
             elicitor.user_ufun(neg.agreement)
             == true_utilities[neg.agreement[0]] - elicitor.elicitation_cost
         )
     if hasattr(elicitor, "each_outcome_once") and elicitor.each_outcome_once:
         assert len(set([_[0] for _ in elicitor.offers])) == len(elicitor.offers)
Ejemplo n.º 2
0
def test_mechanism_can_run(n_negotiators):
    n_outcomes = 5
    mechanism = SAOMechanism(outcomes=n_outcomes, n_steps=3)
    ufuns = MappingUtilityFunction.generate_random(n_negotiators, outcomes=n_outcomes)
    for i in range(n_negotiators):
        mechanism.add(AspirationNegotiator(name=f"agent{i}"), ufun=ufuns[i])
    assert mechanism.state.step == 0
    mechanism.step()
    mechanism.run()
Ejemplo n.º 3
0
def test_can_run_all_negotiators(asdict):
    from negmas.helpers import instantiate

    issues = [Issue((0.0, 1.0), name="price"), Issue(10, name="quantity")]
    weights = dict(price=1.0, quantity=1.0) if asdict else (1.0, 1.0)
    for outcome_type in [tuple, dict]:
        outcomes = Issue.enumerate(issues, max_n_outcomes=100, astype=outcome_type)
        neg_types = [
            (
                "RandomNegotiator",
                dict(ufun=LinearUtilityFunction(weights=weights)),
            ),
            (
                "AspirationNegotiator",
                dict(ufun=LinearUtilityFunction(weights=weights)),
            ),
            (
                "LimitedOutcomesNegotiator",
                dict(acceptance_probabilities=0.5),
            ),
            (
                "LimitedOutcomesAcceptor",
                dict(acceptance_probabilities=0.5),
            ),
            (
                "ToughNegotiator",
                dict(ufun=LinearUtilityFunction(weights=weights)),
            ),
            (
                "OnlyBestNegotiator",
                dict(ufun=LinearUtilityFunction(weights=weights)),
            ),
            (
                "NaiveTitForTatNegotiator",
                dict(ufun=LinearUtilityFunction(weights=weights)),
            ),
            (
                "SimpleTitForTatNegotiator",
                dict(ufun=LinearUtilityFunction(weights=weights)),
            ),
            (
                "NiceNegotiator",
                dict(ufun=LinearUtilityFunction(weights=weights)),
            ),
        ]
        for i, (neg_type, params) in enumerate(neg_types):
            for n2, p2 in neg_types:
                # print(f"{neg_type} <> {n2}")
                n1 = instantiate("negmas.sao." + neg_type, **params)
                n2 = instantiate("negmas.sao." + n2, **p2)
                m = SAOMechanism(
                    n_steps=30, issues=issues, outcome_type=dict if asdict else tuple
                )
                m.add(n1)
                m.add(n2)
                m.run()
                assert not m.running
Ejemplo n.º 4
0
def test_checkpointing_mechanism(tmp_path):
    file = tmp_path
    n_outcomes, n_negotiators = 5, 3
    mechanism = SAOMechanism(
        outcomes=n_outcomes,
        n_steps=3,
        offering_is_accepting=True,
        avoid_ultimatum=False,
    )
    ufuns = MappingUtilityFunction.generate_random(n_negotiators, outcomes=n_outcomes)
    for i in range(n_negotiators):
        mechanism.add(AspirationNegotiator(name=f"agent{i}"), ufun=ufuns[i])

    assert mechanism.state.step == 0
    file_name = mechanism.checkpoint(file)

    info = SAOMechanism.checkpoint_info(file_name)
    assert isinstance(info["time"], str)
    assert info["step"] == 0
    assert info["type"].endswith("SAOMechanism")
    assert info["id"] == mechanism.id
    assert info["name"] == mechanism.name

    mechanism, info = SAOMechanism.from_checkpoint(file_name, return_info=True)
    assert isinstance(info["time"], str)
    assert info["step"] == 0
    assert info["type"].endswith("SAOMechanism")
    assert info["id"] == mechanism.id
    assert info["name"] == mechanism.name

    assert mechanism.state.step == 0
    mechanism.step()

    file_name = mechanism.checkpoint(file)

    info = SAOMechanism.checkpoint_info(file_name)
    assert isinstance(info["time"], str)
    assert info["step"] == 1
    assert info["type"].endswith("SAOMechanism")
    assert info["id"] == mechanism.id
    assert info["name"] == mechanism.name

    mechanism, info = SAOMechanism.from_checkpoint(file_name, return_info=True)
    assert isinstance(info["time"], str)
    assert info["step"] == 1
    assert info["type"].endswith("SAOMechanism")
    assert info["id"] == mechanism.id
    assert info["name"] == mechanism.name

    mechanism.run()
Ejemplo n.º 5
0
def test_neg_run_no_waiting():
    n_outcomes, n_steps, waste = 10, 10, 0.5
    mechanism = SAOMechanism(
        outcomes=n_outcomes, n_steps=n_steps, ignore_negotiator_exceptions=True
    )
    ufuns = MappingUtilityFunction.generate_random(2, outcomes=mechanism.outcomes)
    mechanism.add(TimeWaster(name=f"agent{0}", sleep_seconds=waste, ufun=ufuns[0]))
    mechanism.add(TimeWaster(name=f"agent{1}", sleep_seconds=waste, ufun=ufuns[1]))
    mechanism.run()
    assert mechanism.state.agreement is None
    assert mechanism.state.started
    assert mechanism.state.timedout
    assert mechanism.state.step == n_steps
    assert not mechanism.state.waiting
    assert len(mechanism.history) == n_steps
    for _, v in mechanism.stats["times"].items():
        assert v >= waste * n_steps
Ejemplo n.º 6
0
def test_auto_checkpoint(tmp_path, single_checkpoint, checkpoint_every, exist_ok):
    import shutil

    new_folder: Path = tmp_path / unique_name("empty", sep="")
    new_folder.mkdir(parents=True, exist_ok=True)
    shutil.rmtree(new_folder)
    new_folder.mkdir(parents=True, exist_ok=True)
    filename = "mechanism"

    n_outcomes, n_negotiators = 5, 3
    n_steps = 50
    mechanism = SAOMechanism(
        outcomes=n_outcomes,
        n_steps=n_steps,
        offering_is_accepting=True,
        avoid_ultimatum=False,
        checkpoint_every=checkpoint_every,
        checkpoint_folder=new_folder,
        checkpoint_filename=filename,
        extra_checkpoint_info=None,
        exist_ok=exist_ok,
        single_checkpoint=single_checkpoint,
    )
    ufuns = MappingUtilityFunction.generate_random(n_negotiators, outcomes=n_outcomes)
    for i in range(n_negotiators):
        mechanism.add(
            AspirationNegotiator(name=f"agent{i}"),
            ufun=ufuns[i],
            aspiration_type="conceder",
        )

    mechanism.run()

    if 0 < checkpoint_every <= n_steps:
        if single_checkpoint:
            assert len(list(new_folder.glob("*"))) == 2
        else:
            assert len(list(new_folder.glob("*"))) >= 2 * (
                max(1, mechanism.state.step // checkpoint_every)
            )
    elif checkpoint_every > n_steps:
        assert len(list(new_folder.glob("*"))) == 2
    else:
        assert len(list(new_folder.glob("*"))) == 0
Ejemplo n.º 7
0
    def test_full_knowledge(self, master):
        user, strategy = master
        neg = SAOMechanism(outcomes=[(_,) for _ in range(n_outcomes)], n_steps=10)
        opponent = LimitedOutcomesNegotiator(
            acceptable_outcomes=accepted,
            acceptance_probabilities=[1.0] * len(accepted),
        )
        elicitor = FullKnowledgeElicitor(user=user)
        neg.add(opponent)
        neg.add(elicitor, ufun=u0(neg))
        neg.run()
        # print(
        #     f'Got {elicitor.ufun(neg.agreement)} with elicitation cost {elicitor.elicitation_cost}'
        #     f' for {elicitor} using 0 elicited_queries')

        assert len(neg.history) > 0
        assert neg.agreement is None or neg.agreement in accepted
        # assert len(set([_[0] for _ in elicitor.offers])) > 1 or len(elicitor.offers) < 2
        assert elicitor.elicitation_cost == 0.0
Ejemplo n.º 8
0
def test_acceptable_outcomes():
    p = SAOMechanism(outcomes=6, n_steps=10)
    p.add(
        LimitedOutcomesNegotiator(name="seller", acceptable_outcomes=[(2,), (3,), (5,)])
    )
    p.add(
        LimitedOutcomesNegotiator(name="buyer", acceptable_outcomes=[(1,), (4,), (3,)])
    )
    state = p.run()
    assert state.agreement == (3,)
Ejemplo n.º 9
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
Ejemplo n.º 10
0
def test_single_mechanism_history_with_waiting(
    avoid_ultimatum, n_steps, n_waits, n_waits2
):
    n_outcomes, waste = 5, (0.0, 0.3)
    mechanism = SAOMechanism(
        outcomes=n_outcomes,
        n_steps=n_steps,
        ignore_negotiator_exceptions=False,
        avoid_ultimatum=avoid_ultimatum,
    )
    ufuns = MappingUtilityFunction.generate_random(2, outcomes=mechanism.outcomes)
    mechanism.add(
        TimeWaster(
            name=f"agent{0}", sleep_seconds=waste, ufun=ufuns[0], n_waits=n_waits
        )
    )
    mechanism.add(
        TimeWaster(
            name=f"agent{1}", sleep_seconds=waste, ufun=ufuns[1], n_waits=n_waits2
        )
    )
    mechanism.run()
    first = mechanism._selected_first
    n_negotiators = len(mechanism.negotiators)
    assert (not avoid_ultimatum and first == 0) or (
        avoid_ultimatum and 0 <= first < n_negotiators
    )
    assert mechanism.state.agreement is None
    assert mechanism.state.started
    assert mechanism.state.timedout or (
        n_waits + n_waits2 > 0 and mechanism.state.broken
    )
    assert mechanism.state.step == n_steps or (
        n_waits + n_waits2 > 0
        and mechanism.state.broken
        and mechanism.state.step <= n_steps
    )
    assert not mechanism.state.waiting
    assert len(mechanism.history) == n_steps or (
        n_waits + n_waits2 > 0
        and mechanism.state.broken
        and len(mechanism.history) <= n_steps
    )

    # check history details is correct
    s = [defaultdict(int), defaultdict(int)]
    r = [defaultdict(int), defaultdict(int)]
    h = [defaultdict(int), defaultdict(int)]
    first_offers = []
    ignored_offers = []
    for i, n in enumerate(mechanism.negotiators):
        # print(f"Received, offered, respones for {i} ({n})")
        # print(
        #     list(
        #         zip(
        #             zip(n.received_offers.keys(), n.received_offers.values()),
        #             zip(n.my_offers.keys(), n.my_offers.values()),
        #         )
        #     )
        # )
        # all agents asked to offer first if avoid_ultimatum
        if avoid_ultimatum:
            assert n.received_offers[0] is None
        else:
            first_offers.append(n.received_offers[0] is None)

        # sent and received match
        for j, w in n.my_offers.items():
            # cannot send mutlipe offers in the same step
            assert j not in s[i].keys()
            # cannot send None
            assert w is not None  # or (j == 0 and not avoid_ultimatum)
            if j == 0 and i != first and avoid_ultimatum:
                # cannot have more than n_negotiators - 1 ignored offers
                assert len(ignored_offers) < n_negotiators - 1
                ignored_offers.append(w[0])
                continue
            s[i][j] = w[0]
        for j, w in n.received_offers.items():
            # cannot receive multiple ofers in the same step
            assert j not in r[i].keys()
            # canont be asked to start offering except in the first step
            assert w is not None or j == 0
            # this is the first agent to offer, ignore its first step
            if (first == i and j == 0) or (avoid_ultimatum and j == 0):
                # if this is the first agent, its first thing recieved must be None
                assert w is None
                continue
            assert (
                w is not None
            ), f"None outcome agent {i} @ {j} (avoid={avoid_ultimatum}) first is {first}"
            r[i][j] = w[0]

    # a single agent is asked to offer first if not avoid_ultimatum
    if not avoid_ultimatum:
        assert any(first_offers) and not all(first_offers)
    # every agent is asked to offer and all except one are ignored if avoid_ultimatum
    if avoid_ultimatum:
        assert len(ignored_offers) == n_negotiators - 1

    # reconstruct history
    neg_map = dict(zip((_.id for _ in mechanism.negotiators), [0, 1]))
    for state in mechanism.history:
        for _, w in state.new_offers:
            a = neg_map[_]
            # cannot see the same step twice in the history of an agent
            assert state.step not in h[a].keys()
            h[a][state.step] = w

    # no gaps in steps and all step sets start with 0 or 1
    for i in range(len(mechanism.negotiators)):
        for x in (r, s, h):
            steps = list(x[i].keys())
            if not steps:
                continue
            assert steps[0] in (0, 1)
            for _ in range(len(steps) - 1):
                assert steps[_] + 1 == steps[_ + 1]

    # pprint([s, r, h])
    # history matches what is stored inside agents
    for i, n in enumerate(mechanism.negotiators):
        for j, w in s[i].items():
            assert j in r[1 - i] or (j == 0)
        for j, w in r[i].items():
            assert j in s[1 - i] or (j == 0 and not avoid_ultimatum)

    # s and r will not have matched indices but should have matched values
    s = [list(_.values()) for _ in s]
    r = [list(_.values()) for _ in r]
    h = [list(_[0] for _ in _.values()) for _ in h]
    # history matches what is stored inside agents
    for i, n in enumerate(mechanism.negotiators):
        for j, w in enumerate(s[i]):
            if j < len(r[1 - i]):
                assert r[1 - i][j] == w
            assert h[i][j] == w

        for j, w in enumerate(r[i]):
            assert s[1 - i][j] == w