def test_pickling_mechanism(tmp_path): import pickle file = tmp_path / "mechanism.pck" 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 with open(file, "wb") as f: pickle.dump(mechanism, f) with open(file, "rb") as f: pickle.load(f) assert mechanism.state.step == 0 mechanism.step() with open(file, "wb") as f: pickle.dump(mechanism, f) with open(file, "rb") as f: pickle.load(f) assert mechanism.state.step == 1
def test_times_are_calculated(n_outcomes, n_negotiators, n_steps): mechanism = SAOMechanism(outcomes=n_outcomes, n_steps=8) 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 _strt = time.perf_counter() for _ in range(n_steps): print(f"Stepping: {_}") mechanism.step() time.sleep(0.01) duration = time.perf_counter() - _strt # assert mechanism.current_step == n_steps assert mechanism._current_offer is not None assert len(mechanism.stats) == 3 stats = mechanism.stats assert "round_times" in stats.keys() assert 0 < sum(stats["round_times"]) < duration assert "times" in stats.keys() assert "exceptions" in stats.keys() assert stats["times"] is not None assert stats["exceptions"] is not None assert len(stats["times"]) == n_negotiators assert len(stats["exceptions"]) == 0 for i in range(n_negotiators): assert 0 < stats["times"][mechanism.negotiators[i].id] < duration assert len(stats["exceptions"][mechanism.negotiators[i].id]) == 0 assert 0 < sum(stats["times"].values()) < duration
def test_exceptions_are_saved(): n_outcomes, n_negotiators = 10, 2 mechanism = SAOMechanism(outcomes=n_outcomes, n_steps=n_outcomes, ignore_negotiator_exceptions=True) ufuns = MappingUtilityFunction.generate_random(n_negotiators, outcomes=mechanism.outcomes) mechanism.add(AspirationNegotiator(name=f"agent{0}"), ufun=ufuns[0]) mechanism.add(MyRaisingNegotiator(name=f"agent{1}"), ufun=ufuns[1]) assert mechanism.state.step == 0 mechanism.step() mechanism.step() mechanism.step() assert mechanism.state.step == 1 assert mechanism._current_offer is not None assert len(mechanism.stats) == 3 stats = mechanism.stats assert "times" in stats.keys() assert "exceptions" in stats.keys() assert stats["exceptions"] is not None assert len(stats["exceptions"]) == 1 print(stats["exceptions"][mechanism.negotiators[1].id]) assert len(stats["exceptions"][mechanism.negotiators[1].id]) == 1 assert exception_str in stats["exceptions"][mechanism.negotiators[1].id][0] assert len(stats["exceptions"][mechanism.negotiators[0].id]) == 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()
def test_round_n_agents(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() assert mechanism.state.step == 1 assert mechanism._current_offer is not None
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()
def test_mechanism_runs_with_offering_not_accepting(n_negotiators, oia): n_outcomes = 5 mechanism = SAOMechanism( outcomes=n_outcomes, n_steps=3, offering_is_accepting=oia, avoid_ultimatum=False ) ufuns = MappingUtilityFunction.generate_random(1, outcomes=n_outcomes) for i in range(n_negotiators): mechanism.add(AspirationNegotiator(name=f"agent{i}"), ufun=ufuns[0]) assert mechanism.state.step == 0 mechanism.step() assert mechanism._current_proposer.name == "agent0" assert mechanism._n_accepting == n_negotiators + int(oia) - 1 assert (mechanism.agreement is not None) is oia if mechanism.agreement is not None: return mechanism.step() assert mechanism._current_proposer.name == "agent0" assert mechanism._n_accepting == n_negotiators assert mechanism.agreement is not None
def test_aspiration_continuous_issues(n_negotiators, n_issues, presort, randomize_offers): for k in range(5): mechanism = SAOMechanism( issues=[ Issue(values=(0.0, 1.0), name=f"i{i}") for i in range(n_issues) ], n_steps=10, ) ufuns = [ LinearUtilityFunction( weights=[3.0 * random.random(), 2.0 * random.random()], reserved_value=0.0, ) for _ in range(n_negotiators) ] best_outcome = tuple([1.0] * n_issues) worst_outcome = tuple([0.0] * n_issues) i = 0 assert mechanism.add( AspirationNegotiator( name=f"agent{i}", presort=presort, randomize_offer=randomize_offers, ufun=ufuns[i], ufun_max=ufuns[i](best_outcome), ufun_min=ufuns[i](worst_outcome), )), "Cannot add negotiator" for i in range(1, n_negotiators): assert mechanism.add( AspirationNegotiator( name=f"agent{i}", presort=presort, randomize_offer=randomize_offers, ufun_max=ufuns[i](best_outcome), ufun_min=ufuns[i](worst_outcome), ), ufun=ufuns[i], ), "Cannot add negotiator" assert mechanism.state.step == 0 agents = dict( zip([_.id for _ in mechanism.negotiators], mechanism.negotiators)) offers = defaultdict(list) while not mechanism.state.ended: mechanism.step() for neg_id, offer in mechanism.state.new_offers: assert neg_id in agents.keys() neg = agents[neg_id] prev = offers[neg_id] last_offer = prev[-1] if len(prev) > 0 else float("inf") if randomize_offers: assert neg.utility_function(offer) <= neg.utility_function( best_outcome) else: assert neg.utility_function(offer) <= last_offer if not presort: assert ( -neg.tolerance <= (neg.utility_function(offer) - neg.aspiration( (mechanism.state.step) / mechanism.n_steps) * neg.utility_function(best_outcome)) < pow(neg.tolerance, 0.5 / neg.n_trials) + neg.tolerance) # else: # assert -neg.tolerance <= ( # neg.utility_function(offer) # - neg.aspiration( # (mechanism.state.step - 1) / mechanism.n_steps # ) # * neg.utility_function(best_outcome) # ) offers[neg_id].append(neg.utility_function(offer))