scml.oneshot.agents =================== .. py:module:: scml.oneshot.agents Submodules ---------- .. toctree:: :maxdepth: 1 /autoapi/scml/oneshot/agents/aspiration/index /autoapi/scml/oneshot/agents/greedy/index /autoapi/scml/oneshot/agents/nothing/index /autoapi/scml/oneshot/agents/rand/index Attributes ---------- .. autoapisummary:: scml.oneshot.agents.__all__ Classes ------- .. autoapisummary:: scml.oneshot.agents.SingleAgreementAspirationAgent scml.oneshot.agents.GreedyOneShotAgent scml.oneshot.agents.GreedySyncAgent scml.oneshot.agents.GreedySingleAgreementAgent scml.oneshot.agents.OneshotDoNothingAgent scml.oneshot.agents.Placeholder scml.oneshot.agents.RandomOneShotAgent scml.oneshot.agents.RandDistOneShotAgent scml.oneshot.agents.EqualDistOneShotAgent scml.oneshot.agents.SyncRandomOneShotAgent scml.oneshot.agents.SingleAgreementRandomAgent Package Contents ---------------- .. py:class:: SingleAgreementAspirationAgent(*args, **kwargs) Bases: :py:obj:`scml.oneshot.agent.OneShotSyncAgent` Uses a time-based strategy to accept a single agreement from the set it is considering. .. py:method:: before_step() Called at the beginning of every step. Remarks: - Use this for any proactive code that needs to be done every simulation step. .. py:method:: counter_all(offers, states) Calculate a response to all offers from all negotiators (negotiator ID is the key). :param offers: Maps negotiator IDs to offers :param states: Maps negotiator IDs to offers AT the time the offers were made. :returns: A dictionary mapping negotiator ID to an `SAOResponse`. The response per agent consist of a tuple. In case of acceptance or ending the negotiation the second item of the tuple should be None. In case of rejection, the second item should be the counter offer. Remarks: - The response type CANNOT be WAIT. - If the system determines that a loop is formed, the agent may receive this call for a subset of negotiations not all of them. .. py:method:: choose_agents(offers, outcome) Selects an appropriate way to distribute this outcome to agents with given IDs. .. py:method:: first_proposals() -> Dict[str, negmas.Outcome | None] Gets a set of proposals to use for initializing the negotiation. :returns: A dictionary mapping each negotiator (in self.negotiators dict) to an outcome to be used as the first proposal if the agent is to start a negotiation. .. py:class:: GreedyOneShotAgent(*args, concession_exponent=None, acc_price_slack=float('inf'), step_price_slack=None, opp_price_slack=None, opp_acc_price_slack=None, range_slack=None, **kwargs) Bases: :py:obj:`scml.oneshot.agent.OneShotAgent` A greedy agent based on OneShotAgent :param concession_exponent: A real number controlling how fast does the agent concede on price. :param acc_price_slack: The allowed slack in price limits compared with best prices I got so far :param step_price_slack: The allowed slack in price limits compared with best prices I got this step :param opp_price_slack: The allowed slack in price limits compared with best prices I got so far from a given opponent in this step :param opp_acc_price_slack: The allowed slack in price limits compared with best prices I got so far from a given opponent so far :param range_slack: Always consider prices above (1-`range_slack`) of the best possible prices *good enough*. Remarks: - A `concession_exponent` greater than one makes the agent concede super linearly and vice versa .. py:attribute:: _e :value: None .. py:attribute:: _acc_price_slack .. py:attribute:: _step_price_slack :value: None .. py:attribute:: _opp_price_slack :value: None .. py:attribute:: _opp_acc_price_slack :value: None .. py:attribute:: _range_slack :value: None .. py:method:: init() Initialize the quantities and best prices received so far .. py:method:: before_step() Initialize the quantities and best prices received for next step .. py:method:: on_negotiation_success(contract, mechanism) Record sales/supplies secured .. py:method:: propose(negotiator_id: str, state, source=None) -> negmas.Outcome | None Proposes an offer to one of the partners. :param negotiator_id: ID of the negotiator (and partner) :param state: Mechanism state including current step :returns: an outcome to offer. .. py:method:: respond(negotiator_id, state, source=None) -> negmas.ResponseType Responds to an offer from one of the partners. :param negotiator_id: ID of the negotiator (and partner) :param state: Mechanism state including current step :returns: A response type which can either be reject, accept, or end negotiation. Remarks: default behavior is to accept only if the current offer is the same or has a higher utility compared with what the agent would have proposed in the given state and reject otherwise .. py:method:: best_offer(negotiator_id) .. py:method:: _needed(negotiator_id) .. py:method:: _is_selling(nmi) .. py:method:: _is_good_price(nmi, state, price) Checks if a given price is good enough at this stage .. py:method:: _find_good_price(nmi, state) Finds a good-enough price conceding linearly over time .. py:method:: _price_range(nmi) Limits the price by the best price received .. py:method:: _th(step, n_steps) calculates a descending threshold (0 <= th <= 1) .. py:class:: GreedySyncAgent(*args, threshold=None, **kwargs) Bases: :py:obj:`scml.oneshot.agent.OneShotSyncAgent`, :py:obj:`GreedyOneShotAgent` A greedy agent based on OneShotSyncAgent .. py:attribute:: _threshold :value: None .. py:attribute:: ufun :type: scml.oneshot.ufun.OneShotUFun Returns the preferences if it is a `BaseUtilityFunction` else None .. py:method:: before_step() Called at the beginning of every step. Remarks: - Use this for any proactive code that needs to be done every simulation step. .. py:method:: first_proposals() Decide a first proposal on every negotiation. Returning None for a negotiation means ending it. .. py:method:: counter_all(offers, states) -> dict Respond to a set of offers given the negotiation state of each. .. py:method:: _needs() Returns both input and output needs .. py:method:: propose(negotiator_id, state) Proposes an offer to one of the partners. :param negotiator_id: ID of the negotiator (and partner) :param state: Mechanism state including current step :returns: an outcome to offer. .. py:method:: respond(negotiator_id, state, source='') Responds to an offer from one of the partners. :param negotiator_id: ID of the negotiator (and partner) :param state: Mechanism state including current step :returns: A response type which can either be reject, accept, or end negotiation. Remarks: default behavior is to accept only if the current offer is the same or has a higher utility compared with what the agent would have proposed in the given state and reject otherwise .. py:class:: GreedySingleAgreementAgent(*args, **kwargs) Bases: :py:obj:`scml.oneshot.agent.OneShotSingleAgreementAgent` A greedy agent based on `OneShotSingleAgreementAgent` .. py:attribute:: ufun :type: scml.oneshot.ufun.OneShotUFun Returns the preferences if it is a `BaseUtilityFunction` else None .. py:method:: before_step() Called at the beginning of every step. Remarks: - Use this for any proactive code that needs to be done every simulation step. .. py:method:: is_acceptable(offer, source, state) -> bool Should decide if the given offer is acceptable :param offer: The offer being tested :param source: The ID of the negotiator that received this offer :param state: The state of the negotiation handled by that negotiator Remarks: - If True is returned, this offer will be accepted and all other negotiations will be ended. .. py:method:: best_offer(offers) Return the ID of the negotiator with the best offer :param offers: A mapping from negotiator ID to the offer it received :returns: The ID of the negotiator with best offer. Ties should be broken. Return None only if there is no way to calculate the best offer. .. py:method:: is_better(a, b, negotiator, state) Compares two outcomes of the same negotiation :param a: "Outcome" :param b: "Outcome" :param negotiator: The negotiator for which the comparison is to be made :param state: Current state of the negotiation :returns: True if utility(a) > utility(b) .. py:class:: OneshotDoNothingAgent(owner=None, ufun: scml.oneshot.OneShotUFun | None = None, name=None) Bases: :py:obj:`scml.oneshot.agent.OneShotAgent` An agent that does nothing. Remarks: Note that this agent will lose money whenever it is at the edges (i.e. it is an input or an output agent trading in raw material or final product). .. py:method:: propose(negotiator_id, state) Proposes an offer to one of the partners. :param negotiator_id: ID of the negotiator (and partner) :param state: Mechanism state including current step :returns: an outcome to offer. .. py:method:: respond(negotiator_id, state, source=None) Responds to an offer from one of the partners. :param negotiator_id: ID of the negotiator (and partner) :param state: Mechanism state including current step :returns: A response type which can either be reject, accept, or end negotiation. Remarks: default behavior is to accept only if the current offer is the same or has a higher utility compared with what the agent would have proposed in the given state and reject otherwise .. py:class:: Placeholder(*args, **kwargs) Bases: :py:obj:`scml.oneshot.policy.OneShotPolicy` An agent that always raises an exception if called to negotiate. It is useful as a placeholder (for example for RL and MARL exposition) .. py:method:: act(state) The main policy. Generates an action given a state .. py:class:: RandomOneShotAgent(*args, p_accept=PROB_ACCEPTANCE, p_end=PROB_END, **kwargs) Bases: :py:obj:`scml.oneshot.agent.OneShotAgent` An agent that randomly leaves the negotiation, accepts or counters with random outcomes .. py:method:: _random_offer(negotiator_id: str) .. py:method:: propose(negotiator_id, state) -> negmas.outcomes.Outcome | None Proposes an offer to one of the partners. :param negotiator_id: ID of the negotiator (and partner) :param state: Mechanism state including current step :returns: an outcome to offer. .. py:method:: respond(negotiator_id, state, source=None) -> negmas.ResponseType Responds to an offer from one of the partners. :param negotiator_id: ID of the negotiator (and partner) :param state: Mechanism state including current step :returns: A response type which can either be reject, accept, or end negotiation. Remarks: default behavior is to accept only if the current offer is the same or has a higher utility compared with what the agent would have proposed in the given state and reject otherwise .. py:class:: RandDistOneShotAgent(*args, **kwargs) Bases: :py:obj:`SyncRandomOneShotAgent` An agent that distributes its needs over its partners randomly. :param equal: If given, it tries to equally distribute its needs over as many of its suppliers/consumers as possible :param overordering_max: Maximum fraction of needs to over-order. For example, it the agent needs 5 items and this is 0.2, it will order 6 in the first negotiation step. :param overordering_min: Minimum fraction of needs to over-order. Used in the last negotiation step. :param overordering_exp: Controls how fast does the over-ordering quantity go from max to min. :param concession_exp: Controls how fast does the agent concedes on matching its needs exactly. :param mismatch_max: Maximum mismtach in quantity allowed between needs and accepted offers. If a fraction, it is will be this fraction of the production capacity (n_lines). .. py:class:: EqualDistOneShotAgent(*args, **kwargs) Bases: :py:obj:`SyncRandomOneShotAgent` Same as RandDistOneShotAgent but defaulting to equal distribution of needs :param equal: If given, it tries to equally distribute its needs over as many of its suppliers/consumers as possible :param overordering_max: Maximum fraction of needs to over-order. For example, it the agent needs 5 items and this is 0.2, it will order 6 in the first negotiation step. :param overordering_min: Minimum fraction of needs to over-order. Used in the last negotiation step. :param overordering_exp: Controls how fast does the over-ordering quantity go from max to min. :param concession_exp: Controls how fast does the agent concedes on matching its needs exactly. :param mismatch_max: Maximum mismtach in quantity allowed between needs and accepted offers. If a fraction, it is will be this fraction of the production capacity (n_lines). .. py:class:: SyncRandomOneShotAgent(*args, equal: bool = False, overordering_max: float = 0.2, overordering_min: float = 0.0, overordering_exp: float = 0.4, mismatch_exp: float = 4.0, mismatch_max: float = 0.3, **kwargs) Bases: :py:obj:`scml.oneshot.agent.OneShotSyncAgent` An agent that distributes its needs over its partners randomly. :param equal: If given, it tries to equally distribute its needs over as many of its suppliers/consumers as possible :param overordering_max: Maximum fraction of needs to over-order. For example, it the agent needs 5 items and this is 0.2, it will order 6 in the first negotiation step. :param overordering_min: Minimum fraction of needs to over-order. Used in the last negotiation step. :param overordering_exp: Controls how fast does the over-ordering quantity go from max to min. :param concession_exp: Controls how fast does the agent concedes on matching its needs exactly. :param mismatch_max: Maximum mismtach in quantity allowed between needs and accepted offers. If a fraction, it is will be this fraction of the production capacity (n_lines). .. py:attribute:: equal_distribution :value: False .. py:attribute:: overordering_max :value: 0.2 .. py:attribute:: overordering_min :value: 0.0 .. py:attribute:: overordering_exp :value: 0.4 .. py:attribute:: mismatch_exp :value: 4.0 .. py:attribute:: mismatch_max :value: 0.3 .. py:method:: init() Called once after the AWI is set. Remarks: - Use this for any proactive initialization code. .. py:method:: distribute_needs(t: float) -> dict[str, int] Distributes my needs randomly over all my partners .. py:method:: first_proposals() Gets a set of proposals to use for initializing the negotiation. :returns: A dictionary mapping each negotiator (in self.negotiators dict) to an outcome to be used as the first proposal if the agent is to start a negotiation. .. py:method:: counter_all(offers, states) Calculate a response to all offers from all negotiators (negotiator ID is the key). :param offers: Maps negotiator IDs to offers :param states: Maps negotiator IDs to offers AT the time the offers were made. :returns: A dictionary mapping negotiator ID to an `SAOResponse`. The response per agent consist of a tuple. In case of acceptance or ending the negotiation the second item of the tuple should be None. In case of rejection, the second item should be the counter offer. Remarks: - The response type CANNOT be WAIT. - If the system determines that a loop is formed, the agent may receive this call for a subset of negotiations not all of them. .. py:method:: _allowed_mismatch(r: float) .. py:method:: _overordering_fraction(t: float) .. py:method:: _step_and_price(best_price=False) Returns current step and a random (or max) price .. py:class:: SingleAgreementRandomAgent(*args, p_accept: float = PROB_ACCEPTANCE, **kwargs) Bases: :py:obj:`scml.oneshot.agent.OneShotSingleAgreementAgent` A controller that agrees randomly to one offer .. py:attribute:: _p_accept :value: 0.1 .. py:method:: is_acceptable(offer: negmas.outcomes.Outcome, source: str, state: negmas.sao.SAOState) -> bool Should decide if the given offer is acceptable :param offer: The offer being tested :param source: The ID of the negotiator that received this offer :param state: The state of the negotiation handled by that negotiator Remarks: - If True is returned, this offer will be accepted and all other negotiations will be ended. .. py:method:: best_offer(offers: dict[str, negmas.outcomes.Outcome]) -> str | None Return the ID of the negotiator with the best offer :param offers: A mapping from negotiator ID to the offer it received :returns: The ID of the negotiator with best offer. Ties should be broken. Return None only if there is no way to calculate the best offer. .. py:method:: is_better(a: negmas.outcomes.Outcome | None, b: negmas.outcomes.Outcome | None, negotiator: str, state: negmas.sao.SAOState) -> bool Compares two outcomes of the same negotiation :param a: "Outcome" :param b: "Outcome" :param negotiator: The negotiator for which the comparison is to be made :param state: Current state of the negotiation :returns: True if utility(a) > utility(b) .. py:data:: __all__