def test_propose(self): outcomes = [(_, ) for _ in range(10)] a1 = NaiveTitForTatNegotiator(name="a1", initial_concession="min") u1 = 22.0 - np.linspace(0.0, 22.0, len(outcomes)) neg = SAOMechanism(outcomes=outcomes, n_steps=10, avoid_ultimatum=False) neg.add(a1, ufun=u1) proposal = a1.propose_(neg.state) assert proposal == (0, ), "Proposes top first" proposal = a1.propose_(neg.state) assert proposal == ( 1, ), "Proposes second second if min concession is set" a1 = NaiveTitForTatNegotiator(name="a1") u1 = [50.0] * 3 + (22 - np.linspace(10.0, 22.0, len(outcomes) - 3)).tolist() neg = SAOMechanism(outcomes=outcomes, n_steps=10, avoid_ultimatum=False) neg.add(a1, ufun=u1) proposal = a1.propose_(neg.state) assert proposal == (0, ), "Proposes top first" proposal = a1.propose_(neg.state) assert proposal == ( 3, ), "Proposes first item with utility less than the top if concession is min"
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_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_alternating_offers_mechanism_fails_on_no_offerer(): p = SAOMechanism( outcomes=10, n_steps=10, dynamic_entry=False, publish_n_acceptances=True, publish_proposer=True, ) to_be_offered = [(0, ), (1, ), (2, )] to_be_accepted = [(2, )] a1 = LimitedOutcomesAcceptor(acceptable_outcomes=to_be_offered) a2 = LimitedOutcomesAcceptor(acceptable_outcomes=to_be_accepted) p.add(a1, ufun=MappingUtilityFunction(lambda x: x[0] + 1.0)) p.add(a2, ufun=MappingUtilityFunction(lambda x: x[0] + 1.0)) try: p.run() except RuntimeError: pass a1offers = [ s.current_offer for s in p.history if s.current_proposer == a1.id ] a2offers = [ s.current_offer for s in p.history if s.current_proposer == a2.id ] assert len(p.history) > 0 assert len(a2offers) == 0, "acceptor did not offer" assert len(a1offers) == 0, "acceptor did not offer" assert p.agreement is None, "no agreement"
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
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_a_session(): start = time.monotonic() p = SAOMechanism(outcomes=50, n_steps=50) for _ in range(4): p.add(LimitedOutcomesNegotiator(outcomes=50, p_ending=0.01, name=f'agent {_}') , ufun=HyperRectangleUtilityFunction([None], [lambda x: x[0]])) p.run() # print(f'{len(p.negotiators)} negotiators') assert len(p.history) > 0
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_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, )
def test_alternating_offers_mechanism_with_one_agent_run(): n_outcomes, n_steps = 10, 10 accepted = [(2, ), (3, ), (4, ), (5, )] neg = SAOMechanism(outcomes=n_outcomes, n_steps=n_steps) opponent = LimitedOutcomesNegotiator( acceptable_outcomes=accepted, acceptance_probabilities=[1.0] * len(accepted), ) neg.add(opponent) neg.add(opponent) assert neg.pareto_frontier(sort_by_welfare=True)[0] == [(1.0, )] neg.run()
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_tough_asp_negotiator(): a1 = ToughNegotiator() a2 = AspirationNegotiator(aspiration_type="conceder") outcomes = [(_, ) for _ in range(10)] u1 = np.linspace(0.0, 1.0, len(outcomes)) u2 = 1.0 - u1 neg = SAOMechanism(outcomes=outcomes, n_steps=100, outcome_type=tuple) neg.add(a1, ufun=u1) neg.add(a2, ufun=u2) neg.run() a1offers = neg.negotiator_offers(a1.id) a2offers = neg.negotiator_offers(a2.id) assert a1._offerable_outcomes is None if len(a1offers) > 0: assert len(set(a1offers)) == 1 and a1offers[-1] == (9, ) assert len(set(a2offers)) >= 0
def test_tough_asp_negotiator(): a1 = ToughNegotiator(dynamic_ufun=False) a2 = AspirationNegotiator(dynamic_ufun=False, aspiration_type='conceder') outcomes = [(_,) for _ in range(10)] u1 = np.linspace(0.0, 1.0, len(outcomes)) u2 = 1.0 - u1 neg = SAOMechanism(outcomes=outcomes, n_steps=20) neg.add(a1, ufun=u1) neg.add(a2, ufun=u2) neg.run() a1offers = [s.current_offer for s in neg.history if s.current_offerer == a1.id] a2offers = [s.current_offer for s in neg.history if s.current_offerer == a2.id] assert a1.offerable_outcomes is None if len(a1offers) > 0: assert len(set(a1offers)) == 1 and a1offers[-1] == (9,) assert len(set(a2offers)) >= 0
def test_best_only_asp_negotiator(): a1 = OnlyBestNegotiator(dynamic_ufun=False, min_utility=0.9, top_fraction=0.1) a2 = AspirationNegotiator(dynamic_ufun=False, aspiration_type='conceder') outcomes = [(_,) for _ in range(20)] u1 = np.linspace(0.0, 1.0, len(outcomes)) u2 = 1.0 - u1 neg = SAOMechanism(outcomes=outcomes, n_steps=200) neg.add(a1, ufun=u1) neg.add(a2, ufun=u2) neg.run() a1offers = [s.current_offer for s in neg.history if s.current_offerer == a1.id] a2offers = [s.current_offer for s in neg.history if s.current_offerer == a2.id] assert a1.offerable_outcomes is None if len(a1offers) > 0: assert len(set(a1offers)) <= 2 and min([u1[_[0]] for _ in a1offers if _ is not None]) >= 0.9 assert len(set(a2offers)) >= 1
def test_opponent_negotiator(): from drl_negotiation.negotiator import MyOpponentNegotiator from negmas import Issue, SAOMechanism from drl_negotiation.utility_functions import MyUtilityFunction name = "test_opponent_negotiator" # seller weights = (0, 0.25, 1) issues = [ Issue(values=10, name="quantity"), Issue(values=100, name="delivery_time"), Issue(values=100, name="unit_price") ] mechanism = SAOMechanism(issues=issues, n_steps=100) ufun = MyUtilityFunction(weights=weights, ami=mechanism.ami) opponent_negotiator = MyOpponentNegotiator(name=name, ufun=ufun) mechanism.add(opponent_negotiator)
def test_best_only_asp_negotiator(): a1 = OnlyBestNegotiator(min_utility=0.9, top_fraction=0.1) a2 = AspirationNegotiator(aspiration_type="conceder") outcomes = [(_, ) for _ in range(20)] u1 = np.linspace(0.0, 1.0, len(outcomes)) u2 = 1.0 - u1 neg = SAOMechanism(outcomes=outcomes, n_steps=200) neg.add(a1, ufun=u1) neg.add(a2, ufun=u2) neg.run() a1offers = neg.negotiator_offers(a1.id) a2offers = neg.negotiator_offers(a2.id) assert a1._offerable_outcomes is None if len(a1offers) > 0: assert (len(set(a1offers)) <= 2 and min([u1[_[0]] for _ in a1offers if _ is not None]) >= 0.9) assert len(set(a2offers)) >= 1
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
def test_mechanism_runall(n_negotiators, oia): n_outcomes = 5 mechanisms = [] for _ in range(10): mechanism = SAOMechanism( outcomes=n_outcomes, n_steps=random.randint(3, 20), 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]) mechanisms.append(mechanism) states = SAOMechanism.runall(mechanisms) assert len(states) == 10 assert not any(_.running for _ in states)
def test_tough_tit_for_tat_negotiator(): a1 = ToughNegotiator() a2 = NaiveTitForTatNegotiator() outcomes = [(_, ) for _ in range(10)] u1 = np.linspace(0.0, 1.0, len(outcomes)) u2 = 1.0 - u1 neg = SAOMechanism(outcomes=outcomes, n_steps=100, outcome_type=tuple) neg.add(a1, ufun=u1) neg.add(a2, ufun=u2) neg.run() a1offers = neg.negotiator_offers(a1.id) a2offers = neg.negotiator_offers(a2.id) # print(a1offers) # print(a2offers) assert a1._offerable_outcomes is None if len(a1offers) > 0: assert len(set(a1offers)) == 1 and a1offers[-1] == (9, ) assert len(set(a2offers)) >= 0
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_same_utility_leads_to_agreement(): n_outcomes, n_steps = 10, 10 accepted = [(2, ), (3, ), (4, ), (5, )] neg = SAOMechanism(outcomes=n_outcomes, n_steps=n_steps) opponent = LimitedOutcomesNegotiator( acceptable_outcomes=accepted, acceptance_probabilities=[1.0] * len(accepted), ) acceptor = LimitedOutcomesAcceptor( acceptable_outcomes=accepted, acceptance_probabilities=[1.0] * len(accepted), ) neg.add(opponent) neg.add(acceptor) assert neg.pareto_frontier(sort_by_welfare=True)[0] == [(1.0, 1.0)] state = neg.run() assert state.agreement is not None assert state.step < 4
def test_asp_negotaitor(): a1 = AspirationNegotiator(assume_normalized=True, name="a1") a2 = AspirationNegotiator(assume_normalized=False, name="a2") outcomes = [(_, ) for _ in range(10)] u1 = np.linspace(0.0, 1.0, len(outcomes)) u2 = 1.0 - u1 neg = SAOMechanism(outcomes=outcomes, n_steps=100) neg.add(a1, ufun=u1) neg.add(a2, ufun=u2) neg.run() a1offers = neg.negotiator_offers(a1.id) a2offers = neg.negotiator_offers(a2.id) assert a1offers[0] == (9, ) assert a2offers[0] == (0, ) for i, offer in enumerate(_[0] for _ in a1offers): assert i == 0 or offer <= a1offers[i - 1][0] for i, offer in enumerate(_[0] for _ in a2offers): assert i == 0 or offer >= a2offers[i - 1][0] assert neg.state.agreement is not None assert neg.state.agreement in ((4, ), (5, ))
def test_tit_for_tat_negotiators(): a1 = NaiveTitForTatNegotiator(name="a1") a2 = NaiveTitForTatNegotiator(name="a2") outcomes = [(_, ) for _ in range(10)] u1 = np.linspace(0.0, 1.0, len(outcomes)) u2 = 1.0 - u1 neg = SAOMechanism(outcomes=outcomes, n_steps=100, avoid_ultimatum=False) neg.add(a1, ufun=u1) neg.add(a2, ufun=u2) neg.run() a1offers = neg.negotiator_offers(a1.id) a2offers = neg.negotiator_offers(a2.id) # print(a1offers) # print(a2offers) assert a1offers[0] == (9, ) assert a2offers[0] == (0, ) for i, offer in enumerate(_[0] for _ in a1offers): assert i == 0 or offer <= a1offers[i - 1][0] for i, offer in enumerate(_[0] for _ in a2offers): assert i == 0 or offer >= a2offers[i - 1][0] assert neg.state.agreement is not None assert neg.state.agreement in ((4, ), (5, ))
def test_loops_are_broken(keep_order): """Tests that loops formed by concurrent negotiations are broken for syn controllers""" from negmas.mechanisms import Mechanism from negmas.sao import SAOSingleAgreementAspirationController a, b, c = ( SAOSingleAgreementAspirationController( ufun=MappingUtilityFunction(lambda x: x["price"]), strict=False), SAOSingleAgreementAspirationController( ufun=MappingUtilityFunction(lambda x: x["price"]), strict=False), SAOSingleAgreementAspirationController( ufun=MappingUtilityFunction(lambda x: x["price"]), strict=False), ) n1 = SAOMechanism( name="ab", issues=[Issue((0.0, 1.0), "price")], n_steps=50, outcome_type=dict, ) n2 = SAOMechanism( name="ac", issues=[Issue((0.0, 1.0), "price")], n_steps=50, outcome_type=dict, ) n3 = SAOMechanism( name="bc", issues=[Issue((0.0, 1.0), "price")], n_steps=50, outcome_type=dict, ) n1.add(a.create_negotiator(name="a>b")) n1.add(b.create_negotiator(name="b>a")) n2.add(a.create_negotiator(name="a>c")) n2.add(c.create_negotiator(name="c>a")) n3.add(b.create_negotiator(name="b>c")) n3.add(c.create_negotiator(name="c>b")) negs = [n1, n2, n3] Mechanism.runall(negs, keep_order) agreements = [neg.state.agreement for neg in negs] assert sum(_ is not None for _ in agreements) > 0
def test_drl_negotiator(): from drl_negotiation.negotiator import MyDRLNegotiator, DRLNegotiator from drl_negotiation.utility_functions import MyUtilityFunction from negmas import SAOMechanism, Issue, ResponseType, Outcome from drl_negotiation.env import DRLNegotiationEnv, NEnv name = "drl_negotiator" issues = [ Issue(values=10, name="quantity"), Issue(values=100, name="delivery_time"), Issue(values=100, name="unit_price") ] # buyer weights = (0, -0.5, -0.8) # set the utility function with MyUtilityFunction mechanism = SAOMechanism(issues=issues, n_steps=100) ufun = MyUtilityFunction(weights=weights, ) drl_negotiator = MyDRLNegotiator(name=name, ufun=ufun) mechanism.add(drl_negotiator) drl_negotiator_two = MyDRLNegotiator(name=name + "_two") mechanism.add(drl_negotiator_two, ufun=MyUtilityFunction(weights=(0, -0.2, -0.6))) assert drl_negotiator.name == name assert drl_negotiator.ufun == ufun # Test the basic attributes and functions # None assert drl_negotiator.env is None assert drl_negotiator.action is None #TODO: initial value and reserved value # Test the respond and propose of negotiator offer = Issue.sample(issues, 1) # Test acceptance strategy # Action: None, Env: None, Train: True # env is None, so the respond is always ResponseType.REJECT_OFFER drl_negotiator.train = True respond = drl_negotiator.respond(mechanism.state, offer[0]) assert type(respond) == ResponseType if respond == ResponseType.REJECT_OFFER: proposal_offer = drl_negotiator.propose(mechanism.state) if proposal_offer is not None: assert proposal_offer in drl_negotiator.ami.outcomes else: assert False, "Reponse must be ResponseType.Reject_OFFER!" # Action: None, Env: not None, Train: True # Env will automatically set the issues, games and so on attributes. drl_negotiator.train = True name = "drl_negotiation_env" n_env = DRLNegotiationEnv(name=name) drl_negotiator.reset(env=n_env) assert isinstance(drl_negotiator.env, NEnv) respond = drl_negotiator.respond(mechanism.state, offer[0]) assert type( respond) == ResponseType, "Type of response must be ResponseType!" # Action: not None, Env: not None drl_negotiator.reset(env=n_env) action = drl_negotiator.env.action_space.sample() drl_negotiator.set_current_action(action) assert type(drl_negotiator.action) == ResponseType assert type( respond) == ResponseType, "Type of response must be ResponseType!" respond = drl_negotiator.respond(mechanism.state, offer[0]) assert respond == drl_negotiator.action
def load_genius_domain(domain_file_name: str , utility_file_names: Optional[List[str]] = None , agent_factories: Optional[Union[Callable[[], Negotiator], List[Callable[[], Negotiator]]]] = None , force_single_issue=False , cache_and_discretize_outcomes=False , max_n_outcomes: int = 1e6 , n_discretization: Optional[int] = None , keep_issue_names=True , keep_value_names=True , normalize_utilities=True , n_steps=None , time_limit=3 * 60 # GENIUS uses 3min time limit by default , max_n_agents=None , dynamic_entry=True , safe_parsing=False , ignore_reserved=False , ignore_discount=False ) \ -> Tuple[Optional[SAOMechanism], List[dict], Union[Dict[str, Issue], List[Issue]]]: """ Loads a genius domain, creates appropriate negotiators if necessary Args: domain_file_name: utility_file_names: agent_factories: force_single_issue: cache_and_discretize_outcomes: max_n_outcomes: n_discretization: keep_issue_names: keep_value_names: normalize_utilities: n_steps: time_limit: max_n_agents: dynamic_entry: safe_parsing: ignore_reserved: ignore_discount: Returns: - mechanism (SAOMechanism): A mechanism for the given issues - agent_info (List[Dict]): All Negotiator functions from the given file - issues Union[Issue, Dict[str, Issue], List[Issue]]] : The issues """ issues, issues_details, mechanism = None, None, None if domain_file_name is not None: domain_file_name = str(domain_file_name) issues_details, _ = Issue.from_genius( domain_file_name, force_single_issue=False, keep_issue_names=True, keep_value_names=True, safe_parsing=safe_parsing, n_discretization=n_discretization) if force_single_issue: issues, _ = Issue.from_genius( domain_file_name, force_single_issue=force_single_issue, keep_issue_names=keep_issue_names, keep_value_names=keep_value_names, max_n_outcomes=max_n_outcomes, n_discretization=n_discretization) if issues is None: return None, [], [] else: issues, _ = Issue.from_genius( domain_file_name, force_single_issue=force_single_issue, keep_issue_names=keep_issue_names, keep_value_names=keep_value_names, safe_parsing=safe_parsing, n_discretization=n_discretization) agent_info = [] if utility_file_names is None: utility_file_names = [] utility_file_names = [str(_) for _ in utility_file_names] for ufname in utility_file_names: utility, discount_factor = UtilityFunction.from_genius( file_name=ufname, force_single_issue=force_single_issue, keep_issue_names=keep_issue_names, keep_value_names=keep_value_names, normalize_utility=normalize_utilities, domain_issues=issues_details, safe_parsing=safe_parsing, max_n_outcomes=max_n_outcomes, ignore_discount=ignore_discount, ignore_reserved=ignore_reserved) agent_info.append({ 'ufun': utility, 'reserved_value_func': utility.reserved_value if utility is not None else 0.0, 'discount_factor': discount_factor }) outcomes = None try: if force_single_issue or cache_and_discretize_outcomes or len( issues) == 1: n_outcomes: float = functools.reduce( operator.mul, (float(_.cardinality()) if not _.is_continuous() else float(n_discretization) if n_discretization is not None else np.inf for _ in ivalues(issues)), 1.0) if n_outcomes < max_n_outcomes: outcomes = enumerate_outcomes( issues, keep_issue_names=keep_issue_names) except ValueError: pass if domain_file_name is not None: mechanism_name = domain_file_name.split('/')[-1][:-4].replace( '-domain', '').replace('_domain', '').replace('domain', '') mechanism = SAOMechanism(issues=issues, outcomes=outcomes, n_steps=n_steps, time_limit=time_limit, max_n_agents=max_n_agents, dynamic_entry=dynamic_entry, name=mechanism_name, keep_issue_names=keep_issue_names) if agent_info is not None and len(agent_info) > 0: for info in agent_info: info['ufun'] = info['ufun'] if info['discount_factor'] is None or info['discount_factor'] == 1.0 else \ make_discounted_ufun(ufun=info['ufun'], info=mechanism.info , discount_per_round=info['discount_factor'], power_per_round=1.0) if agent_factories is not None and agent_info is not None and len( agent_info) > 0: if not isinstance(agent_factories, Iterable): agent_factories = [agent_factories] * len(agent_info) agents = [factory() for factory in agent_factories[0:len(agent_info)]] for a, info in zip(agents, agent_info): mechanism.add(a, ufun=info['ufun']) return mechanism, agent_info, (issues if not force_single_issue else [issues])
def test_can_run_from_checkpoint(tmp_path, checkpoint_every, exist_ok, copy, fork_after_reset): import shutil new_folder: Path = tmp_path / unique_name("empty", sep="") second_folder: Path = tmp_path / unique_name("second", sep="") new_folder.mkdir(parents=True, exist_ok=True) shutil.rmtree(new_folder) new_folder.mkdir(parents=True, exist_ok=True) second_folder.mkdir(parents=True, exist_ok=True) shutil.rmtree(second_folder) second_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=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], aspiration_type="conceder", ) mechanism.run() files = list(new_folder.glob("*")) if 0 < checkpoint_every <= n_steps: 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 runner = CheckpointRunner(folder=new_folder) assert len(runner.steps) * 2 == len(files) assert runner.current_step == -1 assert runner.loaded_object is None runner.step() assert runner.current_step == 0 assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.reset() assert len(runner.steps) * 2 == len(files) assert runner.current_step == -1 assert runner.loaded_object is None runner.goto(runner.last_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.next_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.previous_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.first_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.reset() if fork_after_reset: m = runner.fork(copy_past_checkpoints=copy, folder=second_folder) assert m is None return runner.step() m = runner.fork(copy_past_checkpoints=copy, folder=second_folder) if copy: step = runner.current_step assert len(list(second_folder.glob("*"))) >= 2 assert len(list(second_folder.glob(f"*{step}.mechanism"))) > 0 else: assert len(list(second_folder.glob("*"))) == 0 assert isinstance(m, SAOMechanism) step = m.current_step m.step() assert m.current_step == step + 1 state = m.run() assert state.agreement is not None runner.reset() assert len(runner.steps) * 2 == len(files) assert runner.current_step == -1 assert runner.loaded_object is None runner.goto(runner.last_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.next_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.previous_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.first_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.reset() runner.run()
def test_can_run_from_checkpoint(tmp_path, single_checkpoint, checkpoint_every, exist_ok): import shutil new_folder: Path = tmp_path / unique_name("empty", sep="") second_folder: Path = tmp_path / unique_name("second", sep="") new_folder.mkdir(parents=True, exist_ok=True) shutil.rmtree(new_folder) new_folder.mkdir(parents=True, exist_ok=True) filename = "mechanism" second_folder.mkdir(parents=True, exist_ok=True) 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]) mechanism.run() files = list(new_folder.glob("*")) 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 runner = CheckpointRunner(folder=new_folder) assert len(runner.steps) * 2 == len(files) assert runner.current_step == -1 assert runner.loaded_object is None runner.step() assert runner.current_step == (0 if not single_checkpoint else runner.steps[-1]) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.reset() assert len(runner.steps) * 2 == len(files) assert runner.current_step == -1 assert runner.loaded_object is None runner.goto(runner.last_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.next_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.previous_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.first_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.reset() runner.run()
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))