negmas.sao

Implements Stacked Alternating Offers (SAO) mechanism and basic negotiators.

class negmas.sao.ACConst(th: float = 0.9, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Accepts outcomes with utilities above the given threshold

th: float[source]
class negmas.sao.ACLast(alpha: float = 1.0, beta: float = 0.0, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Implements the AClast acceptance strategy based on our last offer.

Accepts $omega$ if $lpha u(my-next-offer) + eta > u(omega)$

after_proposing(state: GBState, offer: Outcome | ExtendedOutcome | None, dest: str | None = None)[source]

Update the stored utility of our last proposed offer.

alpha: float[source]
beta: float[source]
last_offer_util: float[source]
class negmas.sao.ACLastFractionReceived(fraction: float = 1.0, alpha: float = 1.0, beta: float = 0.0, op: Callable[[list[float]], float] = <built-in function max>, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Accepts $omega$ if $lpha u(my-next-offer) + eta > f(u( ext{utils of offers received in the given fraction of time}))$

alpha: float[source]
before_responding(state: GBState, offer: Outcome | None, source: str | None = None)[source]

Record the utility and timestamp of the received offer for time-windowed analysis.

beta: float[source]
fraction: float[source]
op: Callable[[list[float]], float][source]
class negmas.sao.ACLastKReceived(k: int = 0, alpha: float = 1.0, beta: float = 0.0, op: Callable[[list[float]], float] = <built-in function max>, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Accepts $omega$ if $lpha u(my-next-offer) + eta > f(u( ext{utils of offers received in the last k steps))$

after_join(nmi) None[source]

Initialize the sliding window buffer for tracking recent offer utilities.

alpha: float[source]
before_responding(state: GBState, offer: Outcome | None, source: str | None = None)[source]

Record the utility of the received offer in the sliding window.

beta: float[source]
k: int[source]
op: Callable[[list[float]], float][source]
class negmas.sao.ACNext(offering_strategy: OfferingPolicy, alpha: float = 1.0, beta: float = 0.0, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Implements the ACnext acceptance strategy based on our next offer.

Accepts $omega$ if $lpha u(my-next-offer) + eta > u(omega)$

alpha: float[source]
beta: float[source]
offering_strategy: OfferingPolicy[source]
class negmas.sao.ACTime(tau: float, rational: bool = True, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Implements the ACtime acceptance strategy based on our next offer.

Accepts if the relative time is greater than or equal to tau

rational: bool[source]
tau: float[source]
class negmas.sao.AcceptAbove(limit: float, above_reserve: bool = True, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Accepts outcomes with utilities in the given top limit fraction above reserve/minimum (based on above_resrve ).

above_reserve: bool[source]
limit: float[source]
on_preferences_changed(changes: list[PreferencesChange])[source]

Handle preference updates (no action needed for threshold-based acceptance).

negmas.sao.AcceptAfter[source]

alias of ACTime

class negmas.sao.AcceptAnyRational(*, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Accepts any rational outcome.

class negmas.sao.AcceptAround(relative_time: float = 1.0, eps: float = 0.001, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Accepts around the given relative time (i.e. eps from it)

eps: float[source]
relative_time: float[source]
class negmas.sao.AcceptBest(best_util: float = inf, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Accepts Only the best outcome.

Remarks:
  • If the best possible utility cannot be found, nothing will be accepted

on_preferences_changed(changes: list[PreferencesChange])[source]

Handle preference updates (no action needed for best-only acceptance).

class negmas.sao.AcceptBetterRational(accepted: dict[str, Outcome] = NOTHING, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Accept first rational outcomes and then accept only outcomes better than the all accepted so far.

class negmas.sao.AcceptBetween(min: float, max: float = 1.0, rational: bool = True, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Accepts in the given range of relative times.

max: float[source]
min: float[source]
rational: bool[source]
class negmas.sao.AcceptImmediately(*, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Accepts immediately anything

class negmas.sao.AcceptNotWorseRational(accepted: dict[str, Outcome] = NOTHING, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Accept any outcome not worse than the best so far.

class negmas.sao.AcceptTop(fraction: float = 0.0, k: int = 1, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Accepts outcomes that are in the given top fraction or top k. If neither is given it reverts to accepting the best outcome only.

Remarks:
  • The outcome-space is always discretized and the constraints fraction and k are applied to the discretized space

fraction: float[source]
k: int[source]
on_preferences_changed(changes: list[PreferencesChange])[source]

Reinitialize the utility inverter when preferences change significantly.

class negmas.sao.AcceptancePolicy(*, negotiator: GBNegotiator | None = None)[source]

Bases: GBComponent

Acceptance policy implementation.

respond(state: GBState, offer: Outcome | None, source: str | None) ResponseType | ExtendedResponseType[source]

Called to respond to an offer. This is the method that should be overriden to provide an acceptance strategy.

Parameters:
  • state – a GBState giving current state of the negotiation.

  • offer – offer being tested

Returns:

The response to the offer

Return type:

ResponseType | ExtendedResponseType

Remarks:
  • The default implementation never ends the negotiation

  • The default implementation asks the negotiator to propose`() and accepts the `offer if its utility was at least as good as the offer that it would have proposed (and above the reserved value).

class negmas.sao.AdditiveFirstFollowingTBNegotiator(*args, dist_power: float = 2, issue_weights: list[float] | None = None, **kwargs)[source]

Bases: TimeBasedNegotiator

A time-based negotiator that selectes outcomes from the list allowed by the current utility level based on a weighted sum of their normalized utilities and distances to previous offers

class negmas.sao.AdditiveLastOfferFollowingTBNegotiator(*args, dist_power: float = 2, issue_weights: list[float] | None = None, **kwargs)[source]

Bases: TimeBasedNegotiator

A time-based negotiator that selectes outcomes from the list allowed by the current utility level based on a weighted sum of their normalized utilities and distances to previous offers

class negmas.sao.AdditiveParetoFollowingTBNegotiator(*args, dist_power: float = 2, issue_weights: list[float] | None = None, offer_filter: OfferFilterProtocol = <function NoFiltering>, **kwargs)[source]

Bases: TimeBasedNegotiator

A time-based negotiator that selectes outcomes from the list allowed by the current utility level based on a weighted sum of their normalized utilities and distances to previous offers

class negmas.sao.AdditivePartnerOffersOrientedSelector(*args, u_weight: float = 0.6, **kwargs)[source]

Bases: PartnerOffersOrientedSelector

Orients offes toward the set of past opponent offers.

The score of an offer is the product of its utility to self and its distance to opponent’s past offers after normalization

calculate_scores(outcomes: Sequence[Outcome], pivots: list[Outcome], state: GBState) Sequence[tuple[float, Outcome]][source]

Compute scores as a weighted sum of utility and normalized distance to pivots.

class negmas.sao.AllAcceptanceStrategies(strategies: list[AcceptancePolicy], *, negotiator: GBNegotiator | None = None)[source]

Bases: ConcensusAcceptancePolicy

Accept only if all children accept, end only if all of them end, otherwise reject

decide(indices: list[int], responses: list[ResponseType]) ResponseType | ExtendedResponseType[source]

Return first non-accept response, or accept if all strategies accepted.

Parameters:
  • indices – Indices of strategies whose responses were saved.

  • responses – The saved responses from those strategies.

Returns:

ACCEPT_OFFER if all accepted, otherwise the first reject/end response.

filter(indx: int, response: ResponseType) FilterResult[source]

Stop early on reject/end; continue collecting accepts for unanimous decision.

Parameters:
  • indx – Index of the strategy in the strategies list.

  • response – The response returned by the strategy at this index.

Returns:

FilterResult indicating whether to continue and whether to save this response.

class negmas.sao.AnyAcceptancePolicy(strategies: list[AcceptancePolicy], *, negotiator: GBNegotiator | None = None)[source]

Bases: ConcensusAcceptancePolicy

Accept any children accept, end or reject only if all of them end or reject

decide(indices: list[int], responses: list[ResponseType]) ResponseType | ExtendedResponseType[source]

Accept if any strategy accepted, reject only if all rejected.

Parameters:
  • indices – Indices of strategies whose responses were saved.

  • responses – The saved responses from those strategies.

Returns:

ACCEPT_OFFER if any accepted, REJECT_OFFER if all rejected.

filter(indx: int, response: ResponseType) FilterResult[source]

Stop early on accept/end; continue collecting rejects to find any acceptor.

Parameters:
  • indx – Index of the strategy in the strategies list.

  • response – The response returned by the strategy at this index.

Returns:

FilterResult indicating whether to continue and whether to save this response.

class negmas.sao.AspirationNegotiator(*args, max_aspiration=1.0, aspiration_type: Literal['boulware'] | Literal['conceder'] | Literal['linear'] | float = 'boulware', stochastic=False, presort: bool = True, tolerance: float = 0.001, **kwargs)[source]

Bases: TimeBasedConcedingNegotiator

Represents a time-based negotiation strategy that is independent of the offers received during the negotiation.

Parameters:
  • name – The agent name

  • preferences – The utility function to attache with the agent

  • max_aspiration – The aspiration level to use for the first offer (or first acceptance decision).

  • aspiration_type – The polynomial aspiration curve type. Here you can pass the exponent as a real value or pass a string giving one of the predefined types: linear, conceder, boulware.

  • stochastic – If True, the agent will propose outcomes with utility >= the current aspiration level not outcomes just above it.

  • can_propose – If True, the agent is allowed to propose

  • ranking – If True, the aspiration level will not be based on the utility value but the ranking of the outcome within the presorted list. It is only effective when presort is set to True

  • presort – If True, the negotiator will catch a list of outcomes, presort them and only use them for offers and responses. This is much faster then other option for general continuous utility functions but with the obvious problem of only exploring a discrete subset of the issue space (Decided by the discrete_outcomes property of the NegotiatorMechanismInterface . If the number of outcomes is very large (i.e. > 10000) and discrete, presort will be forced to be True. You can check if presorting is active in realtime by checking the “presorted” attribute.

  • tolerance – A tolerance used for sampling of outcomes when presort is set to False

  • owner – The Agent that owns the negotiator.

  • parent – The parent which should be an GBController

Remarks:

property tolerance[source]

Returns the tolerance used when sampling outcomes near the aspiration level.

property ufun_max[source]

Returns the maximum utility value from the inverter.

property ufun_min[source]

Returns the minimum utility value from the inverter.

utility_at(t)[source]

Returns the aspiration utility level at relative time t (0.0 to 1.0).

class negmas.sao.BestOfferOrientedSelector(distance_fun: DistanceFun = <function generalized_minkowski_distance>, **kwargs)[source]

Bases: OfferOrientedSelector

Selects the offer nearest the partner’s best offer for me so far

before_responding(state: GBState, offer: Outcome | None, source: str | None = None)[source]

Updates the pivot if the current offer has the highest utility so far.

class negmas.sao.BestOfferOrientedTBNegotiator(*args, distance_fun: ~typing.Callable[[tuple, tuple, ~negmas.outcomes.protocols.OutcomeSpace | None], float] = <function generalized_minkowski_distance>, **kwargs)[source]

Bases: FirstOfferOrientedTBNegotiator

A time-based negotiator that selectes outcomes from the list allowed by the current utility level based on their utility value and how near they are to the partner’s past offer with the highest utility for me

class negmas.sao.BestOfferSelector(*args, **kwargs)[source]

Bases: OfferSelector

Selects the outcome with the highest utility value.

class negmas.sao.BoulwareTBNegotiator(*args, **kwargs)[source]

Bases: TimeBasedConcedingNegotiator

A Boulware time-based negotiator that conceeds sub-linearly

class negmas.sao.CABNegotiator(*args, **kwargs)[source]

Bases: MAPNegotiator

Conceding Accepting Better Strategy (optimal, complete, but not an equilibirum)

Parameters:
  • name – Negotiator name

  • parent – Parent controller if any

  • preferences – The preferences of the negotiator

  • ufun – The ufun of the negotiator (overrides prefrences)

  • owner – The Agent that owns the negotiator.

class negmas.sao.CABOfferingPolicy(next_indx: int = 0, sorter: PresortingInverseUtilityFunction | None = None, *, negotiator: GBNegotiator | None = None)[source]

Bases: OfferingPolicy

CABOffering policy implementation.

next_indx: int[source]
on_preferences_changed(changes: list[PreferencesChange])[source]

Initializes the outcome sorter on significant preference changes.

sorter: PresortingInverseUtilityFunction | None[source]
class negmas.sao.CANNegotiator(*args, **kwargs)[source]

Bases: MAPNegotiator

Conceding Accepting Not Worse Strategy (optimal, complete, but not an equilibirum)

Parameters:
  • name – Negotiator name

  • parent – Parent controller if any

  • preferences – The preferences of the negotiator

  • ufun – The ufun of the negotiator (overrides prefrences)

  • owner – The Agent that owns the negotiator.

class negmas.sao.CARNegotiator(*args, **kwargs)[source]

Bases: MAPNegotiator

Conceding Accepting Rational Strategy (neither complete nor an equilibrium)

Parameters:
  • name – Negotiator name

  • parent – Parent controller if any

  • preferences – The preferences of the negotiator

  • ufun – The ufun of the negotiator (overrides prefrences)

  • owner – The Agent that owns the negotiator.

class negmas.sao.ConcederTBNegotiator(*args, **kwargs)[source]

Bases: TimeBasedConcedingNegotiator

A Boulware time-based negotiator that conceeds super-linearly

class negmas.sao.ConcensusAcceptancePolicy(strategies: list[AcceptancePolicy], *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy, ABC

Accepts based on concensus of multiple strategies

abstractmethod decide(indices: list[int], responses: list[ResponseType | ExtendedResponseType]) ResponseType | ExtendedResponseType[source]

Called to make a final decision given the decisions of the strategies with indices indices (see filter for filtering rules)

filter(indx: int, response: ResponseType | ExtendedResponseType) FilterResult[source]

Called with the decision of each strategy in order.

Remarks:
  • Two decisions need to be made:

    1. Should we continue trying other strategies

    2. Should we save this result.

on_negotiation_start(state) None[source]

Initialize child strategies with the negotiator reference at negotiation start.

strategies: list[AcceptancePolicy][source]
class negmas.sao.ConcensusOfferingPolicy(strategies: list[OfferingPolicy], *, negotiator: GBNegotiator | None = None)[source]

Bases: OfferingPolicy, ABC

Offers based on concensus of multiple strategies

abstractmethod decide(indices: list[int], responses: list[Outcome | ExtendedOutcome | None]) Outcome | ExtendedOutcome | None[source]

Called to make a final decsision given the decisions of the stratgeis with indices indices (see filter for filtering rules)

filter(indx: int, offer: Outcome | ExtendedOutcome | None) FilterResult[source]

Called with the decision of each strategy in order.

Remarks:
  • Two decisions need to be made:

    1. Should we continue trying other strategies

    2. Should we save this result.

strategies: list[OfferingPolicy][source]
class negmas.sao.ConcessionRecommender(*, negotiator: GBNegotiator | None = None)[source]

Bases: GBComponent

Decides the level of concession to use

class negmas.sao.ControlledSAONegotiator(preferences: Preferences | None = None, ufun: BaseUtilityFunction | None = None, name: str | None = None, parent: Controller | None = None, owner: Agent | None = None, id: str | None = None, type_name: str | None = None, can_propose: bool = True, **kwargs)[source]

Bases: SAOPRNegotiator, ControlledNegotiator

A negotiator that acts as an end point to a parent Controller.

This negotiator simply calls its controler for everything.

join(nmi, state, *, preferences=None, ufun=None, role: str = 'negotiator') bool[source]

Joins a negotiation.

Remarks:

This method first gets permission from the parent controller by calling before_join on it and confirming the result is True, it then joins the negotiation and calls after_join of the controller to inform it that joining is completed if joining was successful.

on_negotiation_end(state) None[source]

Calls parent controller

on_negotiation_start(state) None[source]

Calls parent controller

propose(state: SAOState, dest: str | None = None) tuple | ExtendedOutcome | None[source]

Calls parent controller

respond(state, source: str | None = None) ResponseType | ExtendedResponseType[source]

Calls parent controller

class negmas.sao.EndImmediately(*, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Ends negotiation immediately regardless of the offer.

class negmas.sao.FastMiCRONegotiator(*args, accept_same: bool = True, **kwargs)[source]

Bases: MAPNegotiator

Rational Concession Negotiator

Parameters:
  • name – Negotiator name

  • parent – Parent controller if any

  • preferences – The preferences of the negotiator

  • ufun – The ufun of the negotiator (overrides prefrences)

  • owner – The Agent that owns the negotiator.

class negmas.sao.FirstOfferOrientedSelector(distance_fun: DistanceFun = <function generalized_minkowski_distance>, **kwargs)[source]

Bases: OfferOrientedSelector

Selects the offer nearest the partner’s first offer

before_responding(state: GBState, offer: Outcome | None, source: str | None = None)[source]

Sets the pivot to the first offer received from the partner.

class negmas.sao.FirstOfferOrientedTBNegotiator(*args, distance_fun: ~typing.Callable[[tuple, tuple, ~negmas.outcomes.protocols.OutcomeSpace | None], float] = <function generalized_minkowski_distance>, **kwargs)[source]

Bases: OfferOrientedNegotiator

A time-based negotiator that selectes outcomes from the list allowed by the current utility level based on their utility value and how near they are to the partner’s first offer

class negmas.sao.FrequencyLinearUFunModel(*, negotiator: GBNegotiator | None = None)[source]

Bases: UFunModel

A PartnerUfunModel that uses a simple frequency-based model of the opponent offers assuming the ufun is LinearAdditiveUtilityFunction .

eval(offer: Outcome) Value[source]

Eval.

Parameters:

offer – Offer being considered.

Returns:

The result.

Return type:

Value

class negmas.sao.FrequencyUFunModel(*, negotiator: GBNegotiator | None = None)[source]

Bases: UFunModel

A PartnerUfunModel that uses a simple frequency-based model of the opponent offers.

eval(offer: Outcome) Value[source]

Eval.

Parameters:

offer – Offer being considered.

Returns:

The result.

Return type:

Value

class negmas.sao.GACCombi(offering_policy: OfferingPolicy, a: float = 1.0, b: float = 0.0, t: float = 0.99, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_Combi acceptance strategy from Genius.

Combines AC_Next and AC_Time: accepts if either condition is met.

Accepts if:

(a * u(opponent_offer) + b >= u(my_next_offer)) OR (time >= t)

Parameters:
  • offering_policy – The offering strategy used to determine my next offer.

  • a – Scaling factor for opponent’s offer utility (default 1.0).

  • b – Offset added to scaled opponent utility (default 0.0).

  • t – Time threshold for acceptance (default 0.99).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_Combi

a: float[source]
b: float[source]
offering_policy: OfferingPolicy[source]
t: float[source]
class negmas.sao.GACCombiAvg(offering_policy: OfferingPolicy, t: float = 0.98, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_CombiAvg acceptance strategy from Genius.

Combines AC_Next with average-based acceptance in the end game.

Before time t: acts like AC_Next. After time t: accepts if opponent’s offer >= average of opponent’s offers in window.

Parameters:
  • offering_policy – The offering strategy used to determine my next offer.

  • t – Time threshold after which average-based acceptance kicks in (default 0.98).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_CombiAvg

offering_policy: OfferingPolicy[source]
t: float[source]
class negmas.sao.GACCombiBestAvg(offering_policy: OfferingPolicy, t: float = 0.98, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_CombiBestAvg acceptance strategy from Genius.

Combines AC_Next with best-average-based acceptance.

Before time t: acts like AC_Next. After time t: accepts if opponent’s offer >= average of offers better than current offer.

Parameters:
  • offering_policy – The offering strategy used to determine my next offer.

  • t – Time threshold after which best-average acceptance kicks in (default 0.98).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_CombiBestAvg

offering_policy: OfferingPolicy[source]
t: float[source]
class negmas.sao.GACCombiBestAvgDiscounted(offering_policy: OfferingPolicy, t: float = 0.98, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_CombiBestAvgDiscounted acceptance strategy from Genius.

Like AC_CombiBestAvg but applies time discount to utilities.

Before time t: acts like AC_Next. After time t: accepts if discounted opponent offer >= discounted avg of better offers.

Parameters:
  • offering_policy – The offering strategy used to determine my next offer.

  • t – Time threshold after which best-average acceptance kicks in (default 0.98).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_CombiBestAvgDiscounted

offering_policy: OfferingPolicy[source]
t: float[source]
class negmas.sao.GACCombiMax(offering_policy: OfferingPolicy, t: float = 0.98, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_CombiMax acceptance strategy from Genius.

Combines AC_Next with maximum-based acceptance.

Before time t: acts like AC_Next. After time t: accepts if opponent’s offer >= max of all previous opponent offers.

Parameters:
  • offering_policy – The offering strategy used to determine my next offer.

  • t – Time threshold after which max-based acceptance kicks in (default 0.98).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_CombiMax

offering_policy: OfferingPolicy[source]
t: float[source]
class negmas.sao.GACCombiMaxInWindow(offering_policy: OfferingPolicy, t: float = 0.98, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_CombiMaxInWindow acceptance strategy from Genius.

Combines AC_Next with a time-window-based acceptance criterion.

Before time t: acts like AC_Next only. After time t: accepts if opponent’s offer is >= best offer seen in remaining time window.

Parameters:
  • offering_policy – The offering strategy used to determine my next offer.

  • t – Time threshold after which window-based acceptance kicks in (default 0.98).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_CombiMaxInWindow

offering_policy: OfferingPolicy[source]
t: float[source]
class negmas.sao.GACCombiMaxInWindowDiscounted(offering_policy: OfferingPolicy, t: float = 0.98, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_CombiMaxInWindowDiscounted acceptance strategy from Genius.

Like AC_CombiMaxInWindow but applies time discount to utilities.

Before time t: acts like AC_Next. After time t: accepts if discounted offer >= discounted best in window.

Parameters:
  • offering_policy – The offering strategy used to determine my next offer.

  • t – Time threshold after which window-based acceptance kicks in (default 0.98).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_CombiMaxInWindowDiscounted

offering_policy: OfferingPolicy[source]
t: float[source]
class negmas.sao.GACCombiProb(offering_policy: OfferingPolicy, t: float = 0.98, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_CombiProb acceptance strategy from Genius.

Probability-based acceptance that combines AC_Next with probabilistic acceptance based on the expected utility of waiting.

Before time t: acts like AC_Next. After time t: accepts with probability based on how good the offer is relative to expected future offers.

Parameters:
  • offering_policy – The offering strategy used to determine my next offer.

  • t – Time threshold after which probabilistic acceptance kicks in (default 0.98).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_CombiProb

offering_policy: OfferingPolicy[source]
t: float[source]
class negmas.sao.GACCombiProbDiscounted(offering_policy: OfferingPolicy, t: float = 0.98, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_CombiProbDiscounted acceptance strategy from Genius.

Like AC_CombiProb but applies time discount to utilities.

Before time t: acts like AC_Next. After time t: probabilistic acceptance with discounted utilities.

Parameters:
  • offering_policy – The offering strategy used to determine my next offer.

  • t – Time threshold after which probabilistic acceptance kicks in (default 0.98).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_CombiProbDiscounted

offering_policy: OfferingPolicy[source]
t: float[source]
class negmas.sao.GACCombiV2(offering_policy: OfferingPolicy, a: float = 1.0, b: float = 0.0, t: float = 0.99, decay: float = 0.9, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_CombiV2 acceptance strategy from Genius.

A variant of AC_Combi that uses a different combination logic. Accepts if the opponent’s offer utility exceeds a time-dependent threshold based on both the next offer utility and a decay factor.

Before time t: acts like AC_Next. After time t: accepts if opponent’s offer >= next offer utility * decay.

Parameters:
  • offering_policy – The offering strategy used to determine my next offer.

  • a – Scaling factor for opponent’s offer utility (default 1.0).

  • b – Offset added to scaled opponent utility (default 0.0).

  • t – Time threshold (default 0.99).

  • decay – Decay factor applied after time threshold (default 0.9).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_CombiV2

a: float[source]
b: float[source]
decay: float[source]
offering_policy: OfferingPolicy[source]
t: float[source]
class negmas.sao.GACCombiV3(offering_policy: OfferingPolicy, a: float = 1.0, b: float = 0.0, t: float = 0.95, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_CombiV3 acceptance strategy from Genius.

A variant of AC_Combi that uses linear interpolation between AC_Next threshold and reserved value based on time.

The acceptance threshold decreases linearly from next offer utility to reserved value as time progresses past threshold t.

Parameters:
  • offering_policy – The offering strategy used to determine my next offer.

  • a – Scaling factor for opponent’s offer utility (default 1.0).

  • b – Offset added to scaled opponent utility (default 0.0).

  • t – Time threshold when interpolation begins (default 0.95).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_CombiV3

a: float[source]
b: float[source]
offering_policy: OfferingPolicy[source]
t: float[source]
class negmas.sao.GACCombiV4(offering_policy: OfferingPolicy, t: float = 0.98, w: float = 0.5, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_CombiV4 acceptance strategy from Genius.

A variant of AC_Combi that combines AC_Next with a weighted combination of max and average opponent offers in the end game.

Before time t: acts like AC_Next. After time t: accepts if opponent’s offer >= weighted combo of max and avg.

Parameters:
  • offering_policy – The offering strategy used to determine my next offer.

  • t – Time threshold after which combined strategy kicks in (default 0.98).

  • w – Weight for max utility (1-w used for avg utility) (default 0.5).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_CombiV4

offering_policy: OfferingPolicy[source]
t: float[source]
w: float[source]
class negmas.sao.GACConst(c: float = 0.9, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_Const acceptance strategy from Genius.

Accepts an offer if its utility exceeds a constant threshold.

Parameters:

c – Constant threshold. Accept if utility > c (default 0.9).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_Const

c: float[source]
class negmas.sao.GACConstDiscounted(c: float = 0.9, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_ConstDiscounted acceptance strategy from Genius.

Accepts an offer if its discounted utility exceeds a constant threshold. Takes time discount into account.

Parameters:

c – Constant threshold. Accept if discounted utility > c (default 0.9).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_ConstDiscounted

c: float[source]
class negmas.sao.GACFalse(*, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_False acceptance strategy from Genius.

Never accepts any offer. Useful for debugging and testing.

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_False

class negmas.sao.GACGap(c: float = 0.01, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_Gap acceptance strategy from Genius.

Accepts an offer if:

u(opponent_offer) + c >= u(my_previous_offer)

A restricted version of AC_Previous with a=1 and configurable gap.

Parameters:

c – Gap constant added to opponent utility (default 0.01).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_Gap

c: float[source]
class negmas.sao.GACNext(offering_policy: OfferingPolicy, a: float = 1.0, b: float = 0.0, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_Next acceptance strategy from Genius.

Accepts an offer if:

a * u(opponent_offer) + b >= u(my_next_offer)

where:
  • u(opponent_offer): Utility of the opponent’s current offer

  • u(my_next_offer): Utility of the offer we would make next

  • a: Scaling factor (default 1.0)

  • b: Offset factor (default 0.0)

With default parameters (a=1, b=0), this accepts if the opponent’s offer is at least as good as what we would offer next.

Parameters:
  • offering_policy – The offering strategy used to determine my next offer.

  • a – Scaling factor for opponent’s offer utility (default 1.0).

  • b – Offset added to scaled opponent utility (default 0.0).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_Next

a: float[source]
b: float[source]
offering_policy: OfferingPolicy[source]
class negmas.sao.GACPrevious(a: float = 1.0, b: float = 0.0, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_Previous acceptance strategy from Genius.

Accepts an offer if:

a * u(opponent_offer) + b >= u(my_previous_offer)

Similar to AC_Next but compares against our previous offer instead of next.

Parameters:
  • a – Scaling factor for opponent’s offer utility (default 1.0).

  • b – Offset added to scaled opponent utility (default 0.0).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_Previous

a: float[source]
b: float[source]
class negmas.sao.GACTime(t: float = 0.99, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_Time acceptance strategy from Genius.

Accepts any offer after a certain time threshold has passed.

Parameters:

t – Time threshold (0 to 1). Accept any offer when time > t (default 0.99).

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_Time

t: float[source]
class negmas.sao.GACTrue(*, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusAcceptancePolicy

AC_True acceptance strategy from Genius.

Always accepts any offer. Useful for debugging and testing.

Transcompiled from: negotiator.boaframework.acceptanceconditions.other.AC_True

class negmas.sao.GAgentXFrequencyModel(learning_rate: float = 0.25, default_value: int = 1, issue_weights: dict[int, float] = NOTHING, value_counts: dict[int, dict] = NOTHING, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusOpponentModel

AgentX frequency-based opponent model from Genius.

From AgentX (ANAC 2015). An advanced frequency model that uses both value frequencies and issue weight learning based on bid patterns.

Tracks issue weights by observing which issues change less frequently, and uses exponential smoothing for weight updates.

Parameters:
  • learning_rate – Learning rate for weight updates (default 0.25).

  • default_value – Default value for unseen issue values (default 1).

Transcompiled from: negotiator.boaframework.opponentmodel.AgentXFrequencyModel

default_value: int[source]
eval(offer: Outcome | None) Value[source]

Evaluate opponent utility.

Parameters:

offer – The outcome to evaluate.

Returns:

Estimated opponent utility (0 to 1).

eval_normalized(offer: Outcome | None, above_reserve: bool = True, expected_limits: bool = True) Value[source]

Return normalized utility.

learning_rate: float[source]
on_partner_proposal(state: GBState, partner_id: str, offer: Outcome) None[source]

Update model based on opponent’s offer.

on_preferences_changed(changes: list[PreferencesChange]) None[source]

Reset the model when preferences change.

class negmas.sao.GBayesianModel(n_hypotheses: int = 10, rationality: float = 5.0, issue_weight_hypotheses: list[dict[int, float]] = NOTHING, hypothesis_probs: list[float] = NOTHING, value_utils: dict[int, dict] = NOTHING, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusOpponentModel

Bayesian opponent model from Genius.

Uses Bayesian inference to update beliefs about opponent’s utility function based on their bids. Maintains probability distributions over possible opponent preferences and updates them using Bayes’ rule.

This is a simplified version that assumes the opponent is rational and only offers bids above some threshold.

Parameters:
  • n_hypotheses – Number of hypotheses to consider (default 10).

  • rationality – Assumed opponent rationality - higher values assume opponent is more likely to make utility-maximizing bids (default 5.0).

Transcompiled from: negotiator.boaframework.opponentmodel.BayesianModel

eval(offer: Outcome | None) Value[source]

Evaluate opponent utility as weighted average over hypotheses.

Parameters:

offer – The outcome to evaluate.

Returns:

Estimated opponent utility (0 to 1).

eval_normalized(offer: Outcome | None, above_reserve: bool = True, expected_limits: bool = True) Value[source]

Return normalized utility.

n_hypotheses: int[source]
on_partner_proposal(state: GBState, partner_id: str, offer: Outcome) None[source]

Update hypothesis probabilities using Bayes’ rule.

on_preferences_changed(changes: list[PreferencesChange]) None[source]

Reset the model when preferences change.

rationality: float[source]
class negmas.sao.GBoulwareOffering(e: float = 0.2, k: float = 0.0, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusOfferingPolicy

Boulware offering strategy - a time-dependent strategy with e < 1.

Concedes slowly at first, then faster as deadline approaches. This is a convenience wrapper around GTimeDependentOffering.

Parameters:
  • e – Concession exponent (default 0.2, typical Boulware value).

  • k – Offset constant (default 0).

Transcompiled from: negotiator.boaframework.offeringstrategy.other.TimeDependent_Offering with e < 1

e: float[source]
k: float[source]
on_preferences_changed(changes: list[PreferencesChange]) None[source]

Initialize the delegate time-dependent offering strategy.

class negmas.sao.GChoosingAllBids(all_outcomes: list[Outcome] = NOTHING, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusOfferingPolicy

ChoosingAllBids offering strategy from Genius.

Iterates through all possible bids in the domain, offering each one in sequence. Useful for exhaustive exploration or testing.

When all bids have been offered, it restarts from the beginning.

Transcompiled from: negotiator.boaframework.offeringstrategy.other.ChoosingAllBids

on_preferences_changed(changes: list[PreferencesChange]) None[source]

Initialize the list of all outcomes.

class negmas.sao.GConcederOffering(e: float = 2.0, k: float = 0.0, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusOfferingPolicy

Conceder offering strategy - a time-dependent strategy with e > 1.

Concedes quickly at first, then slows down as deadline approaches. This is a convenience wrapper around GTimeDependentOffering.

Parameters:
  • e – Concession exponent (default 2.0, typical Conceder value).

  • k – Offset constant (default 0).

Transcompiled from: negotiator.boaframework.offeringstrategy.other.TimeDependent_Offering with e > 1

e: float[source]
k: float[source]
on_preferences_changed(changes: list[PreferencesChange]) None[source]

Initialize the delegate time-dependent offering strategy.

class negmas.sao.GDefaultModel(*, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusOpponentModel

Default opponent model from Genius.

A no-op model that doesn’t learn from opponent behavior and assumes uniform preferences. Always returns 0.5 utility for any outcome.

Useful as a baseline or placeholder when no opponent modeling is needed.

Transcompiled from: negotiator.boaframework.opponentmodel.DefaultModel

eval(offer: Outcome | None) Value[source]

Return constant utility (0.5) for any outcome.

Parameters:

offer – The outcome to evaluate.

Returns:

Always returns 0.5.

eval_normalized(offer: Outcome | None, above_reserve: bool = True, expected_limits: bool = True) Value[source]

Return normalized utility.

on_partner_proposal(state: GBState, partner_id: str, offer: Outcome) None[source]

No-op - this model doesn’t learn from offers.

on_preferences_changed(changes: list[PreferencesChange]) None[source]

No-op - this model doesn’t adapt.

class negmas.sao.GHardHeadedFrequencyModel(learning_coef: float = 0.2, learning_value_addition: int = 1, default_value: int = 1, issue_weights: dict[int, float] = NOTHING, value_weights: dict[int, dict] = NOTHING, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusOpponentModel

Hard-Headed Frequency-based opponent model from Genius.

This model estimates the opponent’s utility function by tracking which issues remain unchanged between consecutive opponent bids. Issues that don’t change are assumed to be more important to the opponent.

The model works by: 1. Tracking bid frequencies for each issue value 2. When an issue value stays the same between consecutive bids,

increasing its weight (the opponent likely cares about that issue)

  1. Computing opponent utility as a weighted sum of issue value frequencies

Parameters:
  • learning_coef – Learning coefficient controlling how fast weights adapt. Higher values mean faster adaptation (default 0.2).

  • learning_value_addition – Value added to unchanged issue weights (default 1).

  • default_value – Default value for unseen issue values (default 1).

Transcompiled from: negotiator.boaframework.opponentmodel.HardHeadedFrequencyModel

default_value: int[source]
eval(offer: Outcome | None) Value[source]

Evaluate the estimated opponent utility for an outcome.

Parameters:

offer – The outcome to evaluate.

Returns:

Estimated opponent utility (0 to 1).

eval_normalized(offer: Outcome | None, above_reserve: bool = True, expected_limits: bool = True) Value[source]

Evaluate normalized opponent utility.

Parameters:
  • offer – The outcome to evaluate.

  • above_reserve – Whether to normalize above reserve value.

  • expected_limits – Whether to use expected limits.

Returns:

Normalized opponent utility (0 to 1).

learning_coef: float[source]
learning_value_addition: int[source]
on_partner_proposal(state: GBState, partner_id: str, offer: Outcome) None[source]

Update the model based on the opponent’s offer.

Parameters:
  • state – Current negotiation state.

  • partner_id – ID of the partner who made the offer.

  • offer – The opponent’s offer.

on_preferences_changed(changes: list[PreferencesChange]) None[source]

Reset the model when preferences change.

Parameters:

changes – List of preference changes.

class negmas.sao.GHardlinerOffering(*, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusOfferingPolicy

Hardliner offering strategy - always offers the best outcome.

Never concedes - always offers the maximum utility outcome. This is equivalent to time-dependent with e = 0.

Transcompiled from: negotiator.boaframework.offeringstrategy.other.TimeDependent_Offering with e = 0

on_preferences_changed(changes: list[PreferencesChange]) None[source]

Initialize the inverse utility function.

class negmas.sao.GLinearOffering(k: float = 0.0, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusOfferingPolicy

Linear offering strategy - a time-dependent strategy with e = 1.

Concedes at a constant rate throughout negotiation. This is a convenience wrapper around GTimeDependentOffering.

Parameters:

k – Offset constant (default 0).

Transcompiled from: negotiator.boaframework.offeringstrategy.other.TimeDependent_Offering with e = 1

k: float[source]
on_preferences_changed(changes: list[PreferencesChange]) None[source]

Initialize the delegate time-dependent offering strategy.

class negmas.sao.GNashFrequencyModel(default_value: int = 1, issue_weights: dict[int, float] = NOTHING, value_counts: dict[int, dict] = NOTHING, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusOpponentModel

Nash frequency-based opponent model from Genius.

A frequency model that aims to estimate outcomes close to the Nash bargaining solution by combining opponent utility estimates with our own utility.

Uses frequency-based opponent modeling but biases toward Pareto-efficient outcomes by considering the product of utilities.

Parameters:

default_value – Default value for unseen issue values (default 1).

Transcompiled from: negotiator.boaframework.opponentmodel.NashFrequencyModel

default_value: int[source]
eval(offer: Outcome | None) Value[source]

Evaluate opponent utility with Nash-optimal bias.

Parameters:

offer – The outcome to evaluate.

Returns:

Estimated opponent utility (0 to 1).

eval_normalized(offer: Outcome | None, above_reserve: bool = True, expected_limits: bool = True) Value[source]

Return normalized utility.

on_partner_proposal(state: GBState, partner_id: str, offer: Outcome) None[source]

Update model based on opponent’s offer.

on_preferences_changed(changes: list[PreferencesChange]) None[source]

Reset the model when preferences change.

class negmas.sao.GOppositeModel(*, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusOpponentModel

Opposite opponent model from Genius.

Assumes the opponent has exactly opposite preferences - what’s good for us is bad for them and vice versa. Returns 1 - our_utility.

This is a pessimistic assumption useful for competitive scenarios.

Transcompiled from: negotiator.boaframework.opponentmodel.OppositeModel

eval(offer: Outcome | None) Value[source]

Return opposite utility (1 - our utility).

Parameters:

offer – The outcome to evaluate.

Returns:

1 - our_utility for the outcome.

eval_normalized(offer: Outcome | None, above_reserve: bool = True, expected_limits: bool = True) Value[source]

Return normalized opposite utility.

on_partner_proposal(state: GBState, partner_id: str, offer: Outcome) None[source]

No-op - this model uses our utility function inversely.

on_preferences_changed(changes: list[PreferencesChange]) None[source]

No special initialization needed.

class negmas.sao.GRandomOffering(*, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusOfferingPolicy

Random offering strategy from Genius.

This strategy offers random bids from the outcome space, completely ignoring utility. Also known as “Zero Intelligence” or “Random Walker”.

This is useful for: - Debugging and testing - Creating baseline comparisons - Simulating unpredictable opponents

Transcompiled from: negotiator.boaframework.offeringstrategy.other.Random_Offering

class negmas.sao.GScalableBayesianModel(learning_rate: float = 0.1, issue_weights: dict[int, float] = NOTHING, value_utils: dict[int, dict] = NOTHING, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusOpponentModel

Scalable Bayesian opponent model from Genius.

A Bayesian model optimized for large outcome spaces. Uses a more efficient representation that scales better with domain size.

Instead of maintaining full hypothesis distributions, it tracks sufficient statistics and uses approximate inference.

Parameters:

learning_rate – Rate of belief updates (default 0.1).

Transcompiled from: negotiator.boaframework.opponentmodel.ScalableBayesianModel

eval(offer: Outcome | None) Value[source]

Evaluate opponent utility.

Parameters:

offer – The outcome to evaluate.

Returns:

Estimated opponent utility (0 to 1).

eval_normalized(offer: Outcome | None, above_reserve: bool = True, expected_limits: bool = True) Value[source]

Return normalized utility.

learning_rate: float[source]
on_partner_proposal(state: GBState, partner_id: str, offer: Outcome) None[source]

Update beliefs using online learning.

on_preferences_changed(changes: list[PreferencesChange]) None[source]

Reset the model when preferences change.

class negmas.sao.GSmithFrequencyModel(default_value: int = 1, value_counts: dict[int, dict] = NOTHING, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusOpponentModel

Smith frequency-based opponent model from Genius.

From AgentSmith (ANAC 2010). Similar to HardHeadedFrequencyModel but with a simpler weight update mechanism based purely on value frequencies.

The model tracks how often each value appears in opponent bids and assumes higher frequency = higher importance.

Parameters:

default_value – Default value for unseen issue values (default 1).

Transcompiled from: negotiator.boaframework.opponentmodel.SmithFrequencyModel

default_value: int[source]
eval(offer: Outcome | None) Value[source]

Evaluate opponent utility based on value frequencies.

Parameters:

offer – The outcome to evaluate.

Returns:

Estimated opponent utility (0 to 1).

eval_normalized(offer: Outcome | None, above_reserve: bool = True, expected_limits: bool = True) Value[source]

Return normalized utility.

on_partner_proposal(state: GBState, partner_id: str, offer: Outcome) None[source]

Update value frequencies based on opponent’s offer.

on_preferences_changed(changes: list[PreferencesChange]) None[source]

Reset the model when preferences change.

class negmas.sao.GTimeDependentOffering(e: float = 0.2, k: float = 0.0, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusOfferingPolicy

Time-dependent offering strategy from Genius.

This strategy offers bids based on a time-dependent target utility curve. The curve is controlled by the concession exponent e: - e = 0: Hardliner (never concedes) - e < 1: Boulware (concedes slowly, faster near deadline) - e = 1: Linear - e > 1: Conceder (concedes quickly at start)

The target utility at time t is computed as:

f(t) = k + (1 - k) * t^(1/e) target(t) = Pmin + (Pmax - Pmin) * (1 - f(t))

where:
  • k: Offset constant (default 0)

  • e: Concession exponent (default 0.2 for Boulware)

  • Pmin: Minimum utility (reserved value)

  • Pmax: Maximum utility (best outcome utility)

Parameters:
  • e – Concession exponent. Controls the shape of the concession curve.

  • k – Offset constant for the time function (default 0).

Transcompiled from: negotiator.boaframework.offeringstrategy.other.TimeDependent_Offering

e: float[source]
k: float[source]
on_preferences_changed(changes: list[PreferencesChange]) None[source]

Initialize the inverse utility function for finding outcomes by utility.

Parameters:

changes – List of preference changes.

class negmas.sao.GUniformModel(outcome_utils: dict[tuple, float] = NOTHING, *, negotiator: GBNegotiator | None = None)[source]

Bases: GeniusOpponentModel

Uniform opponent model from Genius.

Assumes the opponent values all outcomes equally - returns uniform random utility values. Each outcome gets a consistent random value.

Transcompiled from: negotiator.boaframework.opponentmodel.UniformModel

eval(offer: Outcome | None) Value[source]

Return a random but consistent utility for the outcome.

Parameters:

offer – The outcome to evaluate.

Returns:

Random utility value in [0, 1], consistent for same outcome.

eval_normalized(offer: Outcome | None, above_reserve: bool = True, expected_limits: bool = True) Value[source]

Return normalized utility.

on_partner_proposal(state: GBState, partner_id: str, offer: Outcome) None[source]

No-op - this model uses random values.

on_preferences_changed(changes: list[PreferencesChange]) None[source]

Reset cached utilities when preferences change.

class negmas.sao.GeniusAcceptancePolicy(*, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Base class for Genius acceptance policies.

class negmas.sao.GeniusOfferingPolicy(*, negotiator: GBNegotiator | None = None)[source]

Bases: OfferingPolicy

Base class for Genius offering policies.

class negmas.sao.GeniusOpponentModel(*, negotiator: GBNegotiator | None = None)[source]

Bases: GBComponent, BaseUtilityFunction

Base class for Genius opponent models.

This base class provides helper methods for updating the negotiator’s private_info with learned opponent utility function estimates.

class negmas.sao.HybridNegotiator(*args, alpha: float = 1.0, beta: float = 0.0, **kwargs)[source]

Bases: MAPNegotiator

Rational Concession Negotiator

Parameters:
  • name – Negotiator name

  • parent – Parent controller if any

  • preferences – The preferences of the negotiator

  • ufun – The ufun of the negotiator (overrides prefrences)

  • owner – The Agent that owns the negotiator.

class negmas.sao.HybridOfferingPolicy(initial_utility: float = nan, concession_ratio: float = nan, final_utility: float = nan, empathy_score: float = nan, frac_time_based: dict[int, tuple[float, ...]] = NOTHING, above_only: bool = False, *, negotiator: GBNegotiator | None = None)[source]

Bases: OfferingPolicy

HybridOffering policy implementation.

above_only: bool[source]
behaviour_based(t: float) float[source]

Computes target utility based on opponent’s concession patterns.

Parameters:

t – Normalized negotiation time in [0, 1].

Returns:

The target utility value adjusted by opponent behavior.

concession_ratio: float[source]
empathy_score: float[source]
final_utility: float[source]
frac_time_based: dict[int, tuple[float, ...]][source]
initial_utility: float[source]
on_partner_proposal(state: GBState, partner_id: str, offer: Outcome) None[source]

Records partner’s offer and its utility for behavior-based strategy.

on_preferences_changed(changes: list[PreferencesChange])[source]

Recalculates parameters and outcome utilities when preferences change.

time_based(t: float) float[source]

Computes target utility using a quadratic Bezier curve over time.

Parameters:

t – Normalized negotiation time in [0, 1].

Returns:

The target utility value at time t.

class negmas.sao.KindConcessionRecommender(kindness: float = 0.0, punish: float = True, initial_concession: float = 0.0, must_concede: bool = True, inverter: UtilityInverter | None = None, *, negotiator: GBNegotiator | None = None)[source]

Bases: ConcessionRecommender

A simple recommender that does one small concession first then a tit-for-tat response

Parameters:
  • kindness – A fraction of the utility range to concede everytime no matter what.

  • punish – If True, the partner will be punished by pushing our lower utility limit up if the concession (or its expectation) was negative

  • initial_concession – The amount of concession to do in the first step

  • must_concede – If True the agent is guaranteed to concede in the first step

  • inverter – Used only if must_concede is True to determine the lowest level of concession possible

initial_concession: float[source]
inverter: UtilityInverter | None[source]
kindness: float[source]
must_concede: bool[source]
punish: float[source]
set_inverter(inverter: UtilityInverter | None) None[source]

Set inverter.

Parameters:

inverter – Inverter.

set_negotiator(negotiator: GBNegotiator) None[source]

Set negotiator.

Parameters:

negotiator – Negotiator.

class negmas.sao.LastOfferOrientedSelector(distance_fun: DistanceFun = <function generalized_minkowski_distance>, **kwargs)[source]

Bases: OfferOrientedSelector

Selects the offer nearest the partner’s last offer

before_responding(state: GBState, offer: Outcome | None, source: str | None = None)[source]

Updates the pivot to the most recent offer from the partner.

class negmas.sao.LastOfferOrientedTBNegotiator(*args, distance_fun: ~typing.Callable[[tuple, tuple, ~negmas.outcomes.protocols.OutcomeSpace | None], float] = <function generalized_minkowski_distance>, **kwargs)[source]

Bases: FirstOfferOrientedTBNegotiator

A time-based negotiator that selectes outcomes from the list allowed by the current utility level based on their utility value and how near they are to the partner’s last offer

class negmas.sao.LimitedOutcomesAcceptancePolicy(prob: dict[Outcome, float] | float | None, p_ending: float = 0.0, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Accepts from a list of predefined outcomes

Remarks:
  • if prob is a number, it is taken as the probability of aceptance for any outcome.

  • if prob is None, the probability of acceptance of any outcome will be set to the relative time

classmethod from_outcome_list(outcomes: list[Outcome], prob: list[float] | float = 1.0, p_ending: float = 0.0)[source]

Create policy from a list of outcomes with their acceptance probabilities.

Parameters:
  • outcomes – The list of acceptable outcomes.

  • prob – Acceptance probability for each outcome (single value or per-outcome list).

  • p_ending – Probability of ending negotiation on each call.

p_ending: float[source]
prob: dict[Outcome, float] | float | None[source]
class negmas.sao.LimitedOutcomesAcceptor(acceptable_outcomes: list[tuple] | None = None, acceptance_probabilities: list[float] | None = None, p_ending=0.0, preferences=None, ufun=None, **kwargs)[source]

Bases: MAPNegotiator, GBNegotiator

A negotiation agent that uses a fixed set of outcomes in a single negotiation.

Remarks:
  • The ufun inputs to the constructor and join are ignored. A ufun will be generated that gives a utility equal to the probability of choosing a given outcome.

class negmas.sao.LimitedOutcomesNegotiator(acceptable_outcomes: list[tuple] | None = None, acceptance_probabilities: float | list[float] | None = None, proposable_outcomes: list[tuple] | None = None, p_ending=0.0, p_no_response=0.0, preferences=None, ufun=None, **kwargs)[source]

Bases: MAPNegotiator

A negotiation agent that uses a fixed set of outcomes in a single negotiation.

Parameters:
  • acceptable_outcomes – the set of acceptable outcomes. If None then it is assumed to be all the outcomes of the negotiation.

  • acceptance_probabilities – probability of accepting each acceptable outcome. If None then it is assumed to be unity.

  • proposable_outcomes – the set of outcomes from which the agent is allowed to propose. If None, then it is the same as acceptable outcomes with nonzero probability

  • p_no_response – probability of refusing to respond to offers

  • p_ending – probability of ending negotiation

Remarks:
  • The ufun inputs to the constructor and join are ignored. A ufun will be generated that gives a utility equal to the probability of choosing a given outcome.

  • If proposable_outcomes is passed as None, it is considered the same as acceptable_outcomes

class negmas.sao.LimitedOutcomesOfferingPolicy(outcomes: list[Outcome] | None, prob: list[float] | None = None, p_ending: float = 0.0, *, negotiator: GBNegotiator | None = None)[source]

Bases: OfferingPolicy

Offers from a given list of outcomes

outcomes: list[Outcome] | None[source]
p_ending: float[source]
prob: list[float] | None[source]
class negmas.sao.LinearTBNegotiator(*args, **kwargs)[source]

Bases: TimeBasedConcedingNegotiator

A Boulware time-based negotiator that conceeds linearly

class negmas.sao.MeanMetaNegotiator(*args, negotiators: Iterable[SAOPRNegotiator] | None = None, negotiator_types: Iterable[type[SAOPRNegotiator]] | None = None, negotiator_params: Iterable[dict[str, Any]] | None = None, negotiator_names: Iterable[str] | None = None, initial_epsilon: float = 0.05, epsilon_step: float = 0.1, max_cardinality: int = 10000, **kwargs)[source]

Bases: SAOAggMetaNegotiator

An SAO meta-negotiator that samples outcomes around the mean utility of sub-negotiator proposals.

This negotiator collects proposals from all sub-negotiators, computes the mean utility of those proposals, and tries to sample an outcome with utility close to the mean. If no outcome is found within a small epsilon around the mean, it progressively expands the search range until it covers the full min/max range of sub-negotiator proposals.

For response aggregation, it uses majority voting among sub-negotiators.

Parameters:
  • negotiators – An iterable of SAONegotiator instances to manage. Mutually exclusive with negotiator_types.

  • negotiator_types – An iterable of SAONegotiator types to instantiate. Mutually exclusive with negmas.negotiators.

  • negotiator_params – Optional iterable of parameter dicts for each negotiator type. Only used with negotiator_types.

  • negotiator_names – Optional names for the negotiators.

  • initial_epsilon – Initial utility range around the mean to search. Defaults to 0.05.

  • epsilon_step – How much to expand the range on each iteration. Defaults to 0.1.

  • max_cardinality – Maximum number of outcomes to sample when searching. Defaults to 10000.

  • *args – Additional positional arguments passed to the base class.

  • **kwargs – Additional keyword arguments passed to the base class.

Example

>>> from negmas.sao.negotiators import (
...     MeanMetaNegotiator,
...     BoulwareTBNegotiator,
...     ConcederTBNegotiator,
... )
>>> from negmas.sao import SAOMechanism
>>> from negmas.preferences import LinearAdditiveUtilityFunction as U
>>> from negmas.outcomes import make_issue, make_os
>>>
>>> issues = [make_issue(10, "price")]
>>> os = make_os(issues)
>>> ufun1 = U.random(os, reserved_value=0.0)
>>> ufun2 = U.random(os, reserved_value=0.0)
>>>
>>> # Create a mean meta-negotiator with diverse strategies
>>> meta = MeanMetaNegotiator(
...     negotiator_types=[BoulwareTBNegotiator, ConcederTBNegotiator],
...     ufun=ufun1,
... )
>>> opponent = ConcederTBNegotiator(ufun=ufun2)
>>>
>>> mechanism = SAOMechanism(issues=issues, n_steps=50)
>>> _ = mechanism.add(meta)
>>> _ = mechanism.add(opponent)
>>> result = mechanism.run()
>>> result.running
False
aggregate_proposals(state: SAOState, proposals: list[tuple[SAOPRNegotiator, tuple | ExtendedOutcome | None]], dest: str | None = None) tuple | ExtendedOutcome | None[source]

Aggregate proposals by sampling an outcome near the mean utility.

Computes the mean utility of sub-negotiator proposals and tries to find an outcome within a small epsilon around the mean. If not found, progressively expands the search range up to the full min/max range.

Parameters:
  • state – The current SAO state.

  • proposals – List of (negotiator, proposal) tuples from sub-negotiators.

  • dest – The destination partner ID (if applicable).

Returns:

An outcome near the mean utility of sub-negotiator proposals, or None if no valid outcome can be found.

aggregate_responses(state: SAOState, responses: list[tuple[SAOPRNegotiator, ResponseType]], offer: tuple | None, source: str | None = None) ResponseType[source]

Aggregate responses using majority voting.

Parameters:
  • state – The current SAO state.

  • responses – List of (negotiator, response) tuples from sub-negotiators.

  • offer – The offer being responded to.

  • source – The source partner ID (if applicable).

Returns:

The most common response among sub-negotiators.

class negmas.sao.MedianOfferSelector(*args, **kwargs)[source]

Bases: OfferSelector

Selects the outcome with the median utility value.

class negmas.sao.MiCRONegotiator(*args, accept_same: bool = True, **kwargs)[source]

Bases: MAPNegotiator

Rational Concession Negotiator

Parameters:
  • name – Negotiator name

  • parent – Parent controller if any

  • preferences – The preferences of the negotiator

  • ufun – The ufun of the negotiator (overrides prefrences)

  • owner – The Agent that owns the negotiator.

class negmas.sao.MiCROOfferingPolicy(next_indx: int = 0, sorter: PresortingInverseUtilityFunction | None = None, received: set[Outcome] = NOTHING, sent: set[Outcome] = NOTHING, *, negotiator: GBNegotiator | None = None)[source]

Bases: OfferingPolicy

MiCROOffering policy implementation.

best_offer_so_far() Outcome | ExtendedOutcome | None[source]

Returns the highest-utility outcome offered so far, or None if none sent.

ensure_sorter()[source]

Initializes the outcome sorter if not already initialized and returns it.

next_indx: int[source]
next_offer() Outcome | ExtendedOutcome | None[source]

Returns the next outcome to offer based on current concession level.

on_partner_proposal(state: GBState, partner_id: str, offer: Outcome) None[source]

Records the partner’s offer to track concession balance.

on_preferences_changed(changes: list[PreferencesChange])[source]

Reinitializes the sorter and resets offer tracking on significant preference changes.

ready_to_concede() bool[source]

Checks if we should concede based on offer exchange balance.

sample_sent() Outcome | ExtendedOutcome | None[source]

Returns a random outcome from previously sent offers, or None if empty.

sorter: PresortingInverseUtilityFunction | None[source]
negmas.sao.Model[source]

alias of GBComponent

class negmas.sao.MultiplicativeFirstFollowingTBNegotiator(*args, dist_power: float = 2, issue_weights: list[float] | None = None, **kwargs)[source]

Bases: TimeBasedNegotiator

A time-based negotiator that selectes outcomes from the list allowed by the current utility level based on a weighted sum of their normalized utilities and distances to previous offers

class negmas.sao.MultiplicativeLastOfferFollowingTBNegotiator(*args, dist_power: float = 2, issue_weights: list[float] | None = None, **kwargs)[source]

Bases: TimeBasedNegotiator

A time-based negotiator that selectes outcomes from the list allowed by the current utility level based on a weighted sum of their normalized utilities and distances to previous offers

class negmas.sao.MultiplicativeParetoFollowingTBNegotiator(*args, dist_power: float = 2, issue_weights: list[float] | None = None, offer_filter: OfferFilterProtocol = <function NoFiltering>, **kwargs)[source]

Bases: TimeBasedNegotiator

A time-based negotiator that selectes outcomes from the list allowed by the current utility level based on a weighted sum of their normalized utilities and distances to previous offers

class negmas.sao.MultiplicativePartnerOffersOrientedSelector(distance_fun: DistanceFun = <function generalized_minkowski_distance>, offer_filter: OfferFilterProtocol = <function NoFiltering>, **kwargs)[source]

Bases: PartnerOffersOrientedSelector

Orients offes toward the set of past opponent offers.

The score of an offer is the product of its utility to self and its distance to opponent’s past offers after normalization

calculate_scores(outcomes: Sequence[Outcome], pivots: list[Outcome], state: GBState) Sequence[tuple[float, Outcome]][source]

Compute scores as the product of utility and normalized distance to pivots.

class negmas.sao.MyBestConcensusOfferingPolicy(strategies: list[OfferingPolicy], *, negotiator: GBNegotiator | None = None)[source]

Bases: UtilBasedConcensusOfferingPolicy

Offers my best outcome from the list of stratgies (different strategy every time).

decide_util(utils: list[Distribution | float]) int[source]

Returns the index of the outcome with the highest utility.

Parameters:

utils – List of utility values for each candidate outcome.

Returns:

Index of the maximum utility outcome.

class negmas.sao.MyWorstConcensusOfferingPolicy(strategies: list[OfferingPolicy], *, negotiator: GBNegotiator | None = None)[source]

Bases: UtilBasedConcensusOfferingPolicy

Offers my worst outcome from the list of stratgies (different strategy every time) based on outcome utilities

decide_util(utils: list[Distribution | float]) int[source]

Returns the index of the outcome with the lowest utility.

Parameters:

utils – List of utility values for each candidate outcome.

Returns:

Index of the minimum utility outcome.

class negmas.sao.NaiveTitForTatNegotiator(*args, kindness=0.0, punish=False, initial_concession: float | Literal['min'] = 'min', rank_only: bool = False, stochastic: bool = False, **kwargs)[source]

Bases: MAPNegotiator

Implements a naive tit-for-tat strategy that does not depend on the availability of an opponent model.

Parameters:
  • name – Negotiator name

  • preferences – negotiator preferences

  • ufun – negotiator ufun (overrides preferences)

  • parent – A controller

  • kindness – How ‘kind’ is the agent. A value of zero is standard tit-for-tat. Positive values makes the negotiator concede faster and negative values slower.

  • stochastic – If True, the offers will be randomized above the level determined by the current concession which in turn reflects the opponent’s concession.

  • punish – If True the agent punish a partner who does not seem to conede by requiring higher utilities

  • initial_concession – How much should the agent concede in the beginning in terms of utility. Should be a number or the special string value ‘min’ for minimum concession

Remarks:

  • This negotiator does not keep an opponent model. It thinks only in terms of changes in its own utility. If the opponent’s last offer was better for the negotiator compared with the one before it, it considers that the opponent has conceded by the difference. This means that it implicitly assumes a zero-sum situation.

class negmas.sao.NegotiatorAcceptancePolicy(acceptor: GBNegotiator, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Uses a negotiator as an offering strategy

acceptor: GBNegotiator[source]
class negmas.sao.NegotiatorOfferingPolicy(*, negotiator: GBNegotiator | None = None, proposer: GBNegotiator)[source]

Bases: OfferingPolicy

Uses a negotiator as an offering strategy

proposer: GBNegotiator[source]
class negmas.sao.NiceNegotiator(*args, **kwargs)[source]

Bases: MAPNegotiator

Offers and accepts anything.

Parameters:
  • name – Negotiator name

  • parent – Parent controller if any

  • preferences – The preferences of the negotiator

  • ufun – The ufun of the negotiator (overrides prefrences)

  • owner – The Agent that owns the negotiator.

class negmas.sao.NoneOfferingPolicy(*, negotiator: GBNegotiator | None = None)[source]

Bases: OfferingPolicy

Always offers None which means it never gets an agreement.

class negmas.sao.OSMeanMetaNegotiator(*args, negotiators: Iterable[SAOPRNegotiator] | None = None, negotiator_types: Iterable[type[SAOPRNegotiator]] | None = None, negotiator_params: Iterable[dict[str, Any]] | None = None, negotiator_names: Iterable[str] | None = None, share_ufun: bool = True, share_nmi: bool = True, **kwargs)[source]

Bases: SAOAggMetaNegotiator

An SAO meta-negotiator that aggregates proposals by averaging in outcome space.

Unlike MeanMetaNegotiator which works in utility space, this negotiator works directly in the outcome space by averaging issue values from sub-negotiator proposals.

For numeric issues (integers, floats), it computes the mean value across all sub-negotiator proposals and finds/generates an outcome with values near that mean. For non-numeric issues (categorical), it samples from the values proposed by sub-negotiators.

For response aggregation, it uses majority voting among sub-negotiators.

Parameters:
  • negotiators – An iterable of SAONegotiator instances to manage. Mutually exclusive with negotiator_types.

  • negotiator_types – An iterable of SAONegotiator types to instantiate. Mutually exclusive with negmas.negotiators.

  • negotiator_params – Optional iterable of parameter dicts for each negotiator type. Only used with negotiator_types.

  • negotiator_names – Optional names for the negotiators.

  • *args – Additional positional arguments passed to the base class.

  • **kwargs – Additional keyword arguments passed to the base class.

Remarks:
  • For continuous issues, the mean value is used directly.

  • For discrete numeric issues (integers), the mean is rounded to the nearest valid value within the issue’s range.

  • For categorical issues, a value is randomly sampled from those proposed by the sub-negotiators.

Example

>>> from negmas.sao.negotiators import (
...     OSMeanMetaNegotiator,
...     BoulwareTBNegotiator,
...     ConcederTBNegotiator,
... )
>>> from negmas.sao import SAOMechanism
>>> from negmas.preferences import LinearAdditiveUtilityFunction as U
>>> from negmas.outcomes import make_issue, make_os
>>>
>>> issues = [make_issue(10, "price"), make_issue(5, "quantity")]
>>> os = make_os(issues)
>>> ufun1 = U.random(os, reserved_value=0.0)
>>> ufun2 = U.random(os, reserved_value=0.0)
>>>
>>> # Create an outcome-space mean meta-negotiator
>>> meta = OSMeanMetaNegotiator(
...     negotiator_types=[BoulwareTBNegotiator, ConcederTBNegotiator],
...     ufun=ufun1,
... )
>>> opponent = ConcederTBNegotiator(ufun=ufun2)
>>>
>>> mechanism = SAOMechanism(issues=issues, n_steps=50)
>>> _ = mechanism.add(meta)
>>> _ = mechanism.add(opponent)
>>> result = mechanism.run()
>>> result.running
False
aggregate_proposals(state: SAOState, proposals: list[tuple[SAOPRNegotiator, tuple | ExtendedOutcome | None]], dest: str | None = None) tuple | ExtendedOutcome | None[source]

Aggregate proposals by averaging issue values in outcome space.

For numeric issues, computes the mean and finds/generates a valid value. For non-numeric issues, samples from the values proposed by sub-negotiators.

Parameters:
  • state – The current SAO state.

  • proposals – List of (negotiator, proposal) tuples from sub-negotiators.

  • dest – The destination partner ID (if applicable).

Returns:

An outcome with averaged issue values, or None if no valid proposals.

aggregate_responses(state: SAOState, responses: list[tuple[SAOPRNegotiator, ResponseType]], offer: tuple | None, source: str | None = None) ResponseType[source]

Aggregate responses using majority voting.

Parameters:
  • state – The current SAO state.

  • responses – List of (negotiator, response) tuples from sub-negotiators.

  • offer – The offer being responded to.

  • source – The source partner ID (if applicable).

Returns:

The most common response among sub-negotiators.

class negmas.sao.OfferBest(best: Outcome | None = None, *, negotiator: GBNegotiator | None = None)[source]

Bases: OfferingPolicy

Offers Only the best outcome.

Remarks:
  • You can pass the best outcome if you know it as best otherwise it will find it.

on_preferences_changed(changes: list[PreferencesChange])[source]

Finds and caches the best outcome when preferences change.

class negmas.sao.OfferOrientedSelector(distance_fun: DistanceFun = <function generalized_minkowski_distance>, **kwargs)[source]

Bases: OfferSelector

Selects the nearest outcome to the pivot outcome which is updated before responding

class negmas.sao.OfferSelector(*args, **kwargs)[source]

Bases: OfferSelectorProtocol, GBComponent

Can select the best offer in some sense from a list of offers based on an inverter

class negmas.sao.OfferSelectorProtocol(*args, **kwargs)[source]

Bases: Protocol

Can select the best offer in some sense from a list of offers based on an inverter

class negmas.sao.OfferTop(fraction: float = 0.0, k: int = 1, *, negotiator: GBNegotiator | None = None)[source]

Bases: OfferingPolicy

Offers outcomes that are in the given top fraction or top k. If neither is given it reverts to only offering the best outcome

Remarks:
  • The outcome-space is always discretized and the constraints fraction and k are applied to the discretized space

fraction: float[source]
k: int[source]
on_preferences_changed(changes: list[PreferencesChange])[source]

Computes the set of top outcomes based on fraction and k constraints.

class negmas.sao.OfferingPolicy(*, negotiator: GBNegotiator | None = None)[source]

Bases: GBComponent

Offering policy implementation.

propose(state: GBState, dest: str | None = None) Outcome | ExtendedOutcome | None[source]

Propose an offer or None to refuse.

Parameters:
  • stateGBState giving current state of the negotiation.

  • dest – the thread in which I am supposed to offer.

Returns:

The outcome being proposed or None to refuse to propose

Remarks:
  • Caches results for the same thread and step. If called multiple times for the same thread and step, it will do the computations only once.

  • Caching is useful when the acceptance strategy calls the offering strategy

class negmas.sao.OutcomeSetOrientedSelector(distance_fun: DistanceFun = <function generalized_minkowski_distance>, offer_filter: OfferFilterProtocol = <function NoFiltering>, **kwargs)[source]

Bases: OfferSelector

Selects the nearest outcome to a set of pivot outcomes which is updated before responding

abstractmethod calculate_scores(outcomes: Sequence[Outcome], pivots: list[Outcome], state: GBState) Sequence[tuple[float, Outcome]][source]

Compute a score for each outcome based on its relation to the pivot outcomes.

Parameters:
  • outcomes – The candidate outcomes to score.

  • pivots – Reference outcomes used for distance calculations.

  • state – The current negotiation state.

Returns:

Sequence of (score, outcome) tuples for ranking.

class negmas.sao.PartnerOffersOrientedSelector(distance_fun: DistanceFun = <function generalized_minkowski_distance>, offer_filter: OfferFilterProtocol = <function NoFiltering>, **kwargs)[source]

Bases: OutcomeSetOrientedSelector

Orients offes toward the set of past opponent offers

before_responding(state: GBState, offer: Outcome | None, source: str | None = None)[source]

Adds the partner’s offer to the pivot set for future distance calculations.

negmas.sao.ProposalPolicy[source]

alias of OfferingPolicy

class negmas.sao.RandomAcceptancePolicy(p_acceptance: float = 0.15, p_rejection: float = 0.25, p_ending: float = 0.1, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Responds randomly with configurable probabilities for accept, reject, end, or no response.

p_acceptance: float[source]
p_ending: float[source]
p_rejection: float[source]
class negmas.sao.RandomAlwaysAcceptingNegotiator(p_acceptance=0.15, p_rejection=0.75, p_ending=0.1, can_propose=True, accept_around=1.0, eps=0.001, **kwargs)[source]

Bases: MAPNegotiator

RandomAlwaysAccepting negotiator.

class negmas.sao.RandomConcensusOfferingPolicy(strategies: list[OfferingPolicy], prob: list[float] | None = None, *, negotiator: GBNegotiator | None = None)[source]

Bases: ConcensusOfferingPolicy

Offers a random response from the list of strategies (different strategy every time).

decide(indices: list[int], responses: list[Outcome | ExtendedOutcome | None]) Outcome | ExtendedOutcome | None[source]

Randomly selects an outcome from responses using probability weights.

Parameters:
  • indices – Indices of strategies that passed the filter.

  • responses – Outcomes proposed by the filtered strategies.

Returns:

A randomly selected outcome based on probability distribution.

prob: list[float] | None[source]
class negmas.sao.RandomNegotiator(p_acceptance=0.15, p_rejection=0.75, p_ending=0.1, can_propose=True, **kwargs)[source]

Bases: MAPNegotiator

A negotiation agent that responds randomly in a single negotiation.

Parameters:
  • p_acceptance – Probability of accepting an offer

  • p_rejection – Probability of rejecting an offer

  • p_ending – Probability of ending the negotiation at any round

  • can_propose – Whether the agent can propose or not

  • **kwargs – Passed to the GBNegotiator

Remarks:

  • If p_acceptance + p_rejection + p_ending < 1, the rest is the probability of no-response.

class negmas.sao.RandomOfferSelector(*args, **kwargs)[source]

Bases: OfferSelector

Selects a random outcome from the candidate set.

class negmas.sao.RandomOfferingPolicy(*, negotiator: GBNegotiator | None = None)[source]

Bases: OfferingPolicy

Offers random outcomes from the negotiation outcome space.

class negmas.sao.RangeMetaNegotiator(*args, negotiators: Iterable[SAOPRNegotiator] | None = None, negotiator_types: Iterable[type[SAOPRNegotiator]] | None = None, negotiator_params: Iterable[dict[str, Any]] | None = None, negotiator_names: Iterable[str] | None = None, max_cardinality: int = 10000, **kwargs)[source]

Bases: SAOAggMetaNegotiator

An SAO meta-negotiator that samples outcomes within the utility range of sub-negotiator proposals.

This negotiator collects proposals from all sub-negotiators, computes their utilities, and samples an outcome from the outcome space that falls within the min/max utility range defined by those proposals.

For response aggregation, it uses majority voting among sub-negotiators.

Parameters:
  • negotiators – An iterable of SAONegotiator instances to manage. Mutually exclusive with negotiator_types.

  • negotiator_types – An iterable of SAONegotiator types to instantiate. Mutually exclusive with negmas.negotiators.

  • negotiator_params – Optional iterable of parameter dicts for each negotiator type. Only used with negotiator_types.

  • negotiator_names – Optional names for the negotiators.

  • max_cardinality – Maximum number of outcomes to sample when searching for outcomes in the utility range. Defaults to 10000.

  • *args – Additional positional arguments passed to the base class.

  • **kwargs – Additional keyword arguments passed to the base class.

Example

>>> from negmas.sao.negotiators import (
...     RangeMetaNegotiator,
...     BoulwareTBNegotiator,
...     ConcederTBNegotiator,
... )
>>> from negmas.sao import SAOMechanism
>>> from negmas.preferences import LinearAdditiveUtilityFunction as U
>>> from negmas.outcomes import make_issue, make_os
>>>
>>> issues = [make_issue(10, "price")]
>>> os = make_os(issues)
>>> ufun1 = U.random(os, reserved_value=0.0)
>>> ufun2 = U.random(os, reserved_value=0.0)
>>>
>>> # Create a range meta-negotiator with diverse strategies
>>> meta = RangeMetaNegotiator(
...     negotiator_types=[BoulwareTBNegotiator, ConcederTBNegotiator],
...     ufun=ufun1,
... )
>>> opponent = ConcederTBNegotiator(ufun=ufun2)
>>>
>>> mechanism = SAOMechanism(issues=issues, n_steps=50)
>>> _ = mechanism.add(meta)
>>> _ = mechanism.add(opponent)
>>> result = mechanism.run()
>>> result.running
False
aggregate_proposals(state: SAOState, proposals: list[tuple[SAOPRNegotiator, tuple | ExtendedOutcome | None]], dest: str | None = None) tuple | ExtendedOutcome | None[source]

Aggregate proposals by sampling an outcome within the utility range.

Computes the utility of each sub-negotiator’s proposal, finds the min/max utility range, and samples an outcome from the outcome space that falls within this range.

Parameters:
  • state – The current SAO state.

  • proposals – List of (negotiator, proposal) tuples from sub-negotiators.

  • dest – The destination partner ID (if applicable).

Returns:

An outcome within the utility range of sub-negotiator proposals, or None if no valid outcome can be found.

aggregate_responses(state: SAOState, responses: list[tuple[SAOPRNegotiator, ResponseType]], offer: tuple | None, source: str | None = None) ResponseType[source]

Aggregate responses using majority voting.

Parameters:
  • state – The current SAO state.

  • responses – List of (negotiator, response) tuples from sub-negotiators.

  • offer – The offer being responded to.

  • source – The source partner ID (if applicable).

Returns:

The most common response among sub-negotiators.

class negmas.sao.RejectAlways(*, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

Rejects everything

class negmas.sao.ResponseType(*values)[source]

Bases: IntEnum

Possible responses to offers during negotiation.

ACCEPT_OFFER = 0[source]
END_NEGOTIATION = 2[source]
LEAVE = 5[source]

Leave the negotiation without necessarily ending it for other negotiators.

NO_RESPONSE = 3[source]
REJECT_OFFER = 1[source]
WAIT = 4[source]
class negmas.sao.SAOAggMetaNegotiator(*args, negotiators: Iterable[SAOPRNegotiator] | None = None, negotiator_types: Iterable[type[SAOPRNegotiator]] | None = None, negotiator_params: Iterable[dict[str, Any]] | None = None, negotiator_names: Iterable[str] | None = None, share_ufun: bool = True, share_nmi: bool = True, **kwargs)[source]

Bases: SAOMetaNegotiator

An SAO meta-negotiator that aggregates proposals and responses from sub-negotiators.

This class collects proposals and responses from all sub-negotiators and uses abstract aggregation methods to combine them into a single proposal or response.

Subclasses must implement aggregate_proposals and aggregate_responses to define how proposals and responses from sub-negotiators are combined.

Parameters:
  • negotiators – An iterable of SAONegotiator instances to manage. Mutually exclusive with negotiator_types.

  • negotiator_types – An iterable of SAONegotiator types to instantiate. Mutually exclusive with negmas.negotiators.

  • negotiator_params – Optional iterable of parameter dicts for each negotiator type. Only used with negotiator_types.

  • negotiator_names – Optional names for the negotiators.

  • share_ufun – If True (default), sub-negotiators will share the parent’s ufun.

  • share_nmi – If True (default), sub-negotiators will receive the parent’s NMI on join.

  • *args – Additional positional arguments passed to the base class.

  • **kwargs – Additional keyword arguments passed to the base class.

Remarks:
  • propose collects proposals from all sub-negotiators and aggregates them.

  • respond collects responses from all sub-negotiators and aggregates them.

Example

>>> from negmas.sao.negotiators import (
...     SAOAggMetaNegotiator,
...     BoulwareTBNegotiator,
... )
>>> from negmas.sao import SAOMechanism
>>> from negmas.preferences import LinearAdditiveUtilityFunction as U
>>> from negmas.outcomes import make_issue
>>>
>>> class MajorityVoteNegotiator(SAOAggMetaNegotiator):
...     def aggregate_proposals(self, state, proposals, dest=None):
...         for neg, proposal in proposals:
...             if proposal is not None:
...                 return proposal
...         return None
...
...     def aggregate_responses(self, state, responses, offer, source=None):
...         accept_count = sum(
...             1 for _, r in responses if r == ResponseType.ACCEPT_OFFER
...         )
...         if accept_count > len(responses) / 2:
...             return ResponseType.ACCEPT_OFFER
...         return ResponseType.REJECT_OFFER
abstractmethod aggregate_proposals(state: SAOState, proposals: list[tuple[SAOPRNegotiator, tuple | ExtendedOutcome | None]], dest: str | None = None) tuple | ExtendedOutcome | None[source]

Aggregate proposals from all sub-negotiators into a single proposal.

Parameters:
  • state – The current SAO state.

  • proposals – List of (negotiator, proposal) tuples from sub-negotiators.

  • dest – The destination partner ID (if applicable).

Returns:

The aggregated proposal, or None to refuse to propose.

abstractmethod aggregate_responses(state: SAOState, responses: list[tuple[SAOPRNegotiator, ResponseType]], offer: tuple | None, source: str | None = None) ResponseType[source]

Aggregate responses from all sub-negotiators into a single response.

Parameters:
  • state – The current SAO state.

  • responses – List of (negotiator, response) tuples from sub-negotiators.

  • offer – The offer being responded to.

  • source – The source partner ID (if applicable).

Returns:

The aggregated response.

propose(state: SAOState, dest: str | None = None) tuple | ExtendedOutcome | None[source]

Collect proposals from all sub-negotiators and aggregate them.

Parameters:
  • state – The current SAO state.

  • dest – The destination partner ID (if applicable).

Returns:

The aggregated proposal.

respond(state: SAOState, source: str | None = None) ResponseType[source]

Collect responses from all sub-negotiators and aggregate them.

Parameters:
  • state – The current SAO state.

  • source – The source partner ID.

Returns:

The aggregated response.

class negmas.sao.SAOCallNegotiator(*args, **kwargs)[source]

Bases: SAOPRNegotiator, ABC

An SAO negotiator implemented by overriding __call__ to return a counter offer.

Parameters:
  • name – Negotiator name

  • parent – Parent controller if any

  • preferences – The preferences of the negotiator

  • ufun – The utility function of the negotiator (overrides preferences if given)

  • owner – The Agent that owns the negotiator.

Remarks:

  • The only method that must be implemented by any SAONegotiator is propose.

  • The default respond method, accepts offers with a utility value no less than whatever propose returns with the same mechanism state.

See also

SAOPRNegotiator

propose(state: SAOState, dest: str | None = None) tuple | ExtendedOutcome | None[source]

Generate proposal by calling the negotiator and extracting the outcome.

Parameters:
  • state – Current SAO state with step counter and previous offers

  • dest – Destination negotiator ID (None broadcasts to all)

Returns:

Cached or freshly generated proposal

Return type:

Outcome | ExtendedOutcome | None

respond(state: SAOState, source: str | None = None) ResponseType[source]

Generate response by calling negotiator and extracting response type.

Parameters:
  • state – Current SAO state including the offer to respond to

  • source – Negotiator ID who made the offer (None if unknown)

Returns:

Response action (ACCEPT_OFFER, REJECT_OFFER, or END_NEGOTIATION)

Return type:

ResponseType

class negmas.sao.SAOController(default_negotiator_type=<class 'negmas.sao.negotiators.controlled.ControlledSAONegotiator'>, preferences=None, ufun=None, **kwargs)[source]

Bases: Controller[SAONMI, SAOState, ControlledSAONegotiator]

A controller that can manage multiple negotiators taking full or partial control from them.

Parameters:
  • default_negotiator_type – Default type to use when creating negotiators using this controller. The default type is ControlledSAONegotiator which passes full control to the controller.

  • default_negotiator_params – Default paramters to pass to the default controller.

  • auto_kill – Automatically kill the negotiator once its negotiation session is ended.

  • name – Controller name

  • preferences – The preferences of the controller.

  • ufun – The ufun of the controller (overrides negmas.preferences).

after_join(negotiator_id, *args, ufun=None, preferences=None, **kwargs) None[source]

Called by children negotiators after joining a negotiation to inform the controller

Parameters:
  • negotiator_id – The negotiator ID

  • nmi (SAONMI) – The negotiation.

  • state (SAOState) – The current state of the negotiation

  • ufun (UtilityFunction) – The ufun function to use before any discounting.

  • role (str) – role of the agent.

before_join(negotiator_id: str, nmi: SAONMI, state: SAOState, *, preferences: Preferences | None = None, role: str = 'negotiator') bool[source]

Called by children negotiators to get permission to join negotiations

Parameters:
  • negotiator_id – The negotiator ID

  • nmi (SAONMI) – The negotiation.

  • state (SAOState) – The current state of the negotiation

  • ufun (UtilityFunction) – The ufun function to use before any discounting.

  • role (str) – role of the agent.

Returns:

True if the negotiator is allowed to join the negotiation otherwise False

create_negotiator(negotiator_type=None, name: str | None = None, cntxt: Any = None, **kwargs)[source]

Creates a new negotiator managed by this controller.

propose(negotiator_id: str, state: SAOState, dest: str | None = None) tuple | ExtendedOutcome | None[source]

Generates a proposal for the given negotiator.

respond(negotiator_id: str, state: SAOState, source: str | None = None) ResponseType | ExtendedResponseType[source]

Generates a response for the given negotiator.

class negmas.sao.SAOMechanism(dynamic_entry=False, extra_callbacks=True, end_on_no_response=True, avoid_ultimatum=False, check_offers=False, enforce_issue_types=False, cast_offers=False, offering_is_accepting=True, allow_offering_just_rejected_outcome=True, allow_none_with_data=True, allow_negotiators_to_leave=True, name: str | None = None, max_wait: int = 9223372036854775807, sync_calls: bool = False, initial_state: SAOState | None = None, one_offer_per_step: bool = False, **kwargs)[source]

Bases: Mechanism[SAONMI, SAOState, SAOResponse, SAOPRNegotiator | GBNegotiator]

A generalized Stacked Alternating Offers Protocol mechanism.

This mechanism extends the classic SAO protocol with several advanced features:

  • Dynamic Entry/Exit: Negotiators can join after the negotiation starts (dynamic_entry=True) and can leave gracefully using ResponseType.LEAVE without forcing the negotiation to end (allow_negotiators_to_leave=True).

  • Per-Negotiator Limits: Each negotiator can have individual time and step limits, enabling asymmetric negotiation scenarios.

  • Text-Based Communication: Negotiators can send messages or explanations alongside offers using the data field and can even send messages that do not contain any offers as long as they include some text or data (allow_none_with_data=True).

  • Flexible Response Types: Beyond ACCEPT/REJECT/END, negotiators can WAIT (pause their turn) or LEAVE (exit gracefully).

  • Callbacks: Negotiators receive notifications when others join (on_negotiator_entered) or leave (on_negotiator_left) and on the most important events including partner offers, rounds start and end, etc.

Parameters:
  • outcome_space – The negotiation agenda

  • issues – A list of issues defining the outcome-space of the negotiation

  • outcomes – A list of outcomes defining the outcome-space of the negotiation

  • n_steps – The maximum number of negotiation rounds (see time_limit )

  • time_limit – The maximum wall-time allowed for the negotiation (see n_steps)

  • step_time_limit – The maximum wall-time allowed for a single negotiation round.

  • max_n_agents – The maximum number of negotiators allowed to join the negotiation.

  • dynamic_entry – Whether it is allowed for negotiators to join the negotiation after it starts

  • cache_outcomes – If true, the mechanism will catch negmas.outcomes and a discrete version (discrete_outcomes) that can be accessed by any negotiator through their NMIs.

  • max_cardinality – Maximum number or outcomes to use when discretizing the outcome-space

  • annotation – A key-value mapping to keep around. Accessible through the NMI but not used by the mechanism.

  • end_on_no_response – End the negotiation if any negotiator returns NO_RESPONSE from respond/counter or returns REJECT_OFFER then refuses to give an offer (by returning None from proposee/`counter).

  • enable_callbacks – Enable callbacks like on_round_start, etc. Note that on_negotiation_end is always received by the negotiators no matter what is the setting for this parameter.

  • check_offers – If true, offers are checked to see if they are valid for the negotiation outcome-space and if not the offer is considered None which is the same as refusing to offer (NO_RESPONSE).

  • enforce_issue_types – If True, the type of each issue is enforced depending on the value of cast_offers

  • cast_offers – If true, each issue value is cast using the issue’s type otherwise an incorrect type will be considered an invalid offer. See check_offers. Only used if enforce_issue_types

  • ignore_negotiator_exceptions – just silently ignore negotiator exceptions and consider them no-responses.

  • offering_is_accepting – Offering an outcome implies accepting it. If not, the agent who proposed an offer will be asked to respond to it after all other agents.

  • allow_none_with_data – If True (default), a negotiator can respond with REJECT_OFFER and outcome=None as long as there is associated data (e.g., text). This allows negotiators to send messages or explanations without making a concrete offer. The negotiation will continue rather than breaking.

  • allow_negotiators_to_leave – If True (default), a LEAVE response removes the negotiator but remaining negotiators continue if 2+ remain. If fewer than 2 remain after leaving, the negotiation ends unless dynamic_entry=True (allowing new negotiators to join). If False, LEAVE is treated exactly like END_NEGOTIATION (breaks the negotiation).

  • sync_calls – If given, calls to negotiators will be synchronized. This will not enforce timeouts on single calls which means that a negotiator in an infinite loop will hog the CPU. By default calls are done using a different thread that is killed when the timeout passes. This may, but is not guaranteed to, resolve this issue at the expense of slower negotiations and harder debugging

  • name – Name of the mechanisms

  • **kwargs – Extra parameters passed directly to the Mechanism constructor

Remarks:

Events:

  • negotiator_exception: Data=(negotiator, exception) raised whenever a negotiator raises an exception if ignore_negotiator_exceptions is set to True.

add(negotiator: SAONegotiator | GBNegotiator, *, preferences: Preferences | None = None, role: str | None = None, **kwargs) bool | None[source]

Add a negotiator to this mechanism.

Parameters:
  • negotiator – The negotiator instance to add.

  • preferences – Optional preferences to assign to the negotiator.

  • role – Optional role identifier for the negotiator.

  • **kwargs – Additional keyword arguments passed to the parent add method.

Returns:

True if successfully added, False if rejected, None if pending.

property agreement_partners: list[SAOPRNegotiator | GBNegotiator][source]

Returns negotiators who are part of the final agreement.

This is the same as participating_negotiators - it includes all negotiators who haven’t left the negotiation. If there’s an agreement, these are the parties to that agreement.

Returns:

List of negotiator objects who participated in the final outcome.

property atomic_steps: bool[source]

Is every step corresponding to a single action by a single negotiator

property extended_trace: list[tuple[int, str, tuple]][source]

Returns the negotiation history as a list of step/negotiator/offer tuples

following_negotiators() list[str][source]

Returns a list of ids for all negotiators in the order they are to be run in the next calls to step()

property full_trace: list[TraceElement][source]

Returns the negotiation history as a list of relative_time/step/negotiator/offer tuples

property full_trace_with_utils: list[tuple][source]

Returns the full trace and the utility of the negotiators at each step.

full_trace_with_utils_df(ufun_names: str | list[str] = 'id') pd.DataFrame[source]

Returns the full trace and the utility of the negotiators at each step.

Parameters:

ufun_names – How to name utility columns. “id” (default) uses negotiator IDs for consistency with the ‘negotiator’ field in trace entries. “name” uses negotiator names. Can also be a list of custom names.

make_config() dict[str, Any][source]
property n_participating: int[source]

Number of negotiators still participating (not left).

Returns:

Count of active negotiators.

negotiator_full_trace(negotiator_id: str) list[tuple[float, float, int, tuple, str, str | None, dict[str, Any] | None]][source]

Returns the (time/relative-time/step/outcome/response/text/data) given by a negotiator (in order)

negotiator_offers(negotiator_id: str) list[tuple][source]

Returns the offers given by a negotiator (in order)

next_negotitor_ids() list[str][source]

Returns a list of negotiator IDs in the order they are to be run in the next call to step()

property offers: list[tuple][source]

Returns the negotiation history as a list of offers

property participating_negotiators: list[SAOPRNegotiator | GBNegotiator][source]

Returns negotiators still participating (those who haven’t left).

Unlike negmas.negotiators, this excludes any negotiator that has returned a LEAVE response. The original negotiator list and indices remain unchanged to avoid breaking any saved references.

Returns:

List of negotiator objects still active in the negotiation.

plot(plotting_negotiators: tuple[int, int] | tuple[str, str] = (0, 1), save_fig: bool = False, path: str | None = None, fig_name: str | None = None, ignore_none_offers: bool = True, with_lines: bool = True, show_agreement: bool = False, show_pareto_distance: bool = True, show_nash_distance: bool = True, show_kalai_distance: bool = True, show_ks_distance: bool = True, show_max_welfare_distance: bool = True, show_max_relative_welfare_distance: bool = False, show_end_reason: bool = True, show_last_negotiator: bool = True, show_annotations: bool = False, show_reserved: bool = True, show_total_time=True, show_relative_time=True, show_n_steps=True, colors: list | None = None, markers: list[str] | None = None, colormap: str = 'jet', ylimits: tuple[float, float] | None = None, common_legend: bool = True, xdim: str = 'relative_time', only2d: bool = False, no2d: bool = False, fast: bool = False, simple_offers_view: bool = False, mark_offers_view: bool = True, mark_pareto_points: bool = True, mark_all_outcomes: bool = True, mark_nash_points: bool = True, mark_kalai_points: bool = True, mark_ks_points: bool = True, mark_max_welfare_points: bool = True, show: bool = True, **kwargs)[source]

Visualize the negotiation run showing offers and utilities in 2D space.

Parameters:
  • plotting_negotiators – Indices or IDs of two negotiators whose utilities form the axes.

  • save_fig – Whether to save the figure to disk.

  • path – Directory path for saving the figure.

  • fig_name – Filename for the saved figure.

  • ignore_none_offers – Whether to skip None offers in the plot.

  • with_lines – Whether to connect offers with lines showing progression.

  • show_agreement – Whether to highlight the final agreement point.

  • show_pareto_distance – Whether to display distance to Pareto frontier.

  • show_nash_distance – Whether to display distance to Nash solution.

  • show_kalai_distance – Whether to display distance to Kalai-Smorodinsky solution.

  • show_ks_distance – Whether to display distance to KS point.

  • show_max_welfare_distance – Whether to display distance to max welfare point.

  • show_max_relative_welfare_distance – Whether to display distance to max relative welfare.

  • show_end_reason – Whether to annotate why the negotiation ended.

  • show_last_negotiator – Whether to show the last negotiator who acted.

  • show_annotations – Whether to show offer annotations on the plot.

  • show_reserved – Whether to show reservation values.

  • show_total_time – Whether to display total negotiation time.

  • show_relative_time – Whether to display relative time progress.

  • show_n_steps – Whether to display the number of steps.

  • colors – Custom color list for negotiators.

  • markers – Custom marker list for negotiators.

  • colormap – Matplotlib colormap name for coloring offers.

  • ylimits – Y-axis limits as (min, max) tuple.

  • common_legend – Whether to use a shared legend for all subplots.

  • xdim – Dimension for x-axis (“relative_time”, “step”, etc.).

  • only2d – Whether to show only the 2D utility space plot.

  • no2d – Whether to skip the 2D utility space plot.

  • fast – Whether to use faster but less detailed rendering.

  • simple_offers_view – Whether to use simplified offer visualization.

  • mark_offers_view – Whether to mark offers in the utility space view.

  • mark_pareto_points – Whether to mark Pareto optimal points.

  • mark_all_outcomes – Whether to mark all possible outcomes.

  • mark_nash_points – Whether to mark Nash bargaining solution.

  • mark_kalai_points – Whether to mark Kalai-Smorodinsky solution.

  • mark_ks_points – Whether to mark KS points.

  • mark_max_welfare_points – Whether to mark maximum welfare points.

  • show – Whether to display the figure immediately.

  • **kwargs – Additional arguments passed to the plotting function.

set_sync_call(v: bool)[source]

Enable or disable synchronous negotiator calls.

property state: SAOState[source]

Returns the current state.

Override extra_state if you want to keep extra state

property trace: list[tuple[str, tuple]][source]

Returns the negotiation history as a list of negotiator/offer tuples

class negmas.sao.SAOMetaNegotiator(*args, negotiators: Iterable[SAOPRNegotiator] | None = None, negotiator_types: Iterable[type[SAOPRNegotiator]] | None = None, negotiator_params: Iterable[dict[str, Any]] | None = None, negotiator_names: Iterable[str] | None = None, share_ufun: bool = True, share_nmi: bool = True, **kwargs)[source]

Bases: MetaNegotiator, SAOPRNegotiator

Abstract base class for SAO meta-negotiators that manage multiple SAONegotiator instances.

This class provides the infrastructure for managing sub-negotiators in SAO protocols, including lifecycle callback forwarding, NMI/ufun sharing, and proper joining.

Subclasses must implement propose and respond to define how the meta-negotiator behaves. This is straightforward - just decide how to use your sub-negotiators.

Parameters:
  • negotiators – An iterable of SAONegotiator instances to manage. Mutually exclusive with negotiator_types.

  • negotiator_types – An iterable of SAONegotiator types to instantiate. Mutually exclusive with negmas.negotiators.

  • negotiator_params – Optional iterable of parameter dicts for each negotiator type. Only used with negotiator_types.

  • negotiator_names – Optional names for the negotiators.

  • share_ufun – If True (default), sub-negotiators will share the parent’s ufun.

  • share_nmi – If True (default), sub-negotiators will receive the parent’s NMI on join.

  • *args – Additional positional arguments passed to the base class.

  • **kwargs – Additional keyword arguments passed to the base class.

Remarks:
  • All lifecycle callbacks are delegated to all sub-negotiators.

  • Subclasses can implement any strategy: delegation to a single negotiator, aggregation of multiple negotiators, or custom logic that uses sub-negotiators for advice/context only.

  • You can either pass negmas.negotiators (instances) OR negotiator_types (classes to instantiate). If using negotiator_types, you can optionally provide negotiator_params (parameter dicts).

Example

A simple passthrough meta-negotiator that delegates to its first sub-negotiator:

class PassthroughMeta(SAOMetaNegotiator):
    def propose(self, state, dest=None):
        return self._negotiators[0].propose(state, dest=dest)

    def respond(self, state, source=None):
        return self._negotiators[0].respond(state, source=source)

Creating with negotiator types instead of instances:

meta = MeanMetaNegotiator(
    negotiator_types=[BoulwareTBNegotiator, ConcederTBNegotiator],
    negotiator_params=[{"name": "boulware"}, {"name": "conceder"}],
)

See also

SAOAggMetaNegotiator: Implementation that aggregates proposals/responses

from multiple sub-negotiators.

join(nmi: NegotiatorMechanismInterface, state: MechanismState, *, preferences: Preferences | None = None, ufun: BaseUtilityFunction | None = None, role: str = 'negotiator') bool[source]

Join a negotiation and have sub-negotiators join too.

Parameters:
  • nmi – The negotiator-mechanism interface.

  • state – The current mechanism state.

  • preferences – Optional preferences for this negotiator.

  • ufun – Optional utility function (overrides preferences).

  • role – The role in the negotiation.

Returns:

True if successfully joined, False otherwise.

on_leave(state: MechanismState) None[source]

Notify all sub-negotiators that we’re leaving the negotiation.

on_mechanism_error(state: MechanismState) None[source]

Notify all sub-negotiators of a mechanism error.

on_negotiation_end(state: MechanismState) None[source]

Notify all sub-negotiators that negotiation has ended.

on_negotiation_start(state: MechanismState) None[source]

Notify all sub-negotiators that negotiation has started.

on_negotiator_didnot_enter(negotiator_id: str, state: MechanismState) None[source]

Notify all sub-negotiators that a negotiator failed to enter the negotiation.

on_negotiator_entered(negotiator_id: str, state: MechanismState) None[source]

Notify all sub-negotiators that a new negotiator entered the negotiation.

on_negotiator_left(negotiator_id: str, state: MechanismState) None[source]

Notify all sub-negotiators that a negotiator left the negotiation.

on_round_end(state: MechanismState) None[source]

Notify all sub-negotiators that a round has ended.

on_round_start(state: MechanismState) None[source]

Notify all sub-negotiators that a round has started.

abstractmethod propose(state: SAOState, dest: str | None = None) tuple | ExtendedOutcome | None[source]

Generate a proposal for the negotiation.

Subclasses must implement this method to define how proposals are generated. This could involve delegating to a single sub-negotiator, aggregating proposals from multiple sub-negotiators, or using custom logic.

Parameters:
  • state – The current SAO state.

  • dest – The destination partner ID (if applicable).

Returns:

The proposal, or None to refuse to propose.

abstractmethod respond(state: SAOState, source: str | None = None) ResponseType[source]

Respond to an offer in the negotiation.

Subclasses must implement this method to define how responses are generated. This could involve delegating to a single sub-negotiator, aggregating responses from multiple sub-negotiators, or using custom logic.

Parameters:
  • state – The current SAO state.

  • source – The source partner ID.

Returns:

The response to the current offer.

property sao_negotiators: tuple[SAOPRNegotiator, ...][source]

Return the tuple of SAO sub-negotiators.

Returns:

A tuple of all SAO sub-negotiators.

class negmas.sao.SAOMetaNegotiatorController(*args, meta_negotiator: GBNegotiator | None = None, **kwargs)[source]

Bases: SAOController

Controls multiple negotiations using a single meta negotiator.

Parameters:

meta_negotiator (-) – The negotiator used for controlling all negotiations.

Remarks:

  • The controller will use the meta-negotiator to handle all negotiations by first setting its NMI to the current negotiation then calling the appropriate method in the meta negotiator.

  • If no meta-negotiator is given, an AspirationNegotiator will be created and used (with default parameters).

  • The meta-negotiator should not internally store information between calls to propose and respond about the negotiation because it will be called to propose and respond in multiple negotiations. The AspirationNegotiator can be used but SimpleTitForTatNegotiator cannot as it stores the past offer.

propose(negotiator_id: str, state: SAOState, dest: str | None = None) tuple | ExtendedOutcome | None[source]

Uses the meta negotiator to propose

respond(negotiator_id: str, state: SAOState, source: str | None = None) ResponseType | ExtendedResponseType[source]

Uses the meta negotiator to respond

class negmas.sao.SAONMI(id: str, n_outcomes: int | float, outcome_space: OutcomeSpace, shared_time_limit: float, shared_n_steps: int | None, private_time_limit: float, private_n_steps: int | None, pend: float, pend_per_second: float, step_time_limit: float, negotiator_time_limit: float, dynamic_entry: bool, max_n_negotiators: int | None, _mechanism: Mechanism, annotation: dict[str, Any] = NOTHING, end_on_no_response: bool = True, one_offer_per_step: bool = False, offering_is_accepting: bool = True, allow_none_with_data: bool = True, allow_negotiators_to_leave: bool = True)[source]

Bases: NegotiatorMechanismInterface

The NegotiatorMechanismInterface of SAO

allow_negotiators_to_leave: bool[source]

If true, negotiators can leave using LEAVE response without ending the negotiation for others

allow_none_with_data: bool[source]

If true, a negotiator can offer None with associated data (e.g., text) without breaking the negotiation

end_on_no_response: bool[source]

End the negotiation if any agent responded with None

property extended_trace: list[tuple[int, str, Outcome]][source]

Returns the negotiation history as a list of step, negotiator, offer tuples

property history: list[SAOState][source]

Complete history of all SAO negotiation states.

Returns:

Chronological list of states from negotiation start to current

Return type:

list[SAOState]

negotiator_offers(negotiator_id: str) list[Outcome][source]

Get all offers made by a specific negotiator.

Parameters:

negotiator_id – ID of the negotiator whose offers to retrieve

Returns:

List of all outcomes proposed by this negotiator

Return type:

list[Outcome]

offering_is_accepting: bool[source]

If true, offering is considered an acceptance of that offer which means that the offerer need not accept the offer again to make it an agreement

property offers: list[Outcome][source]

Returns offers exchanged in order

one_offer_per_step: bool[source]

If true, a step should be atomic with only one action from one negotiator

property state: SAOState[source]

Current state of the SAO negotiation mechanism.

Returns:

State containing step number, current offer, and negotiation status

Return type:

SAOState

property trace: list[tuple[str, Outcome]][source]

Returns the negotiation history as a list of negotiator, offer tuples

negmas.sao.SAONegotiator[source]

alias of SAOPRNegotiator

class negmas.sao.SAOPRNegotiator(preferences: Preferences | None = None, ufun: BaseUtilityFunction | None = None, name: str | None = None, parent: Controller | None = None, owner: Agent | None = None, id: str | None = None, type_name: str | None = None, can_propose: bool = True, **kwargs)[source]

Bases: GBNegotiator[SAONMI, SAOState]

Base class for all SAO negotiators. Implemented by implementing propose() and respond() methods.

Parameters:
  • name – Negotiator name

  • parent – Parent controller if any

  • preferences – The preferences of the negotiator

  • ufun – The utility function of the negotiator (overrides preferences if given)

  • owner – The Agent that owns the negotiator.

Remarks:

  • The only method that must be implemented by any SAONegotiator is propose.

  • The default respond method, accepts offers with a utility value no less than whatever propose returns with the same mechanism state.

  • A default implementation of respond() is provided which simply accepts any offer better than the last offer I gave or the next one I would have given in the current state.

on_notification(notification: Notification, notifier: str)[source]

Called whenever a notification is received

Parameters:
  • notification – The notification

  • notifier – The notifier entity

Remarks:

  • The default implementation only responds to end_negotiation by ending the negotiation

abstractmethod propose(state: SAOState, dest: str | None = None) tuple | ExtendedOutcome | None[source]

Generate a proposal (offer) for the current negotiation state.

Parameters:
  • state – Current SAO negotiation state including step, offers, and responses

  • dest – Target negotiator ID to send proposal to (None for all)

Returns:

Proposed outcome, or None to end negotiation

Return type:

Outcome | ExtendedOutcome | None

propose_(state: SAOState, dest: str | None = None) tuple | ExtendedOutcome | None[source]

The method directly called by the mechanism (through counter ) to ask for a proposal

Parameters:
  • state – The mechanism state

  • dest – the destination (can be ignored in AOP, SAOP, MAOP)

Returns:

An outcome to offer or None to refuse to offer

Remarks:

  • Depending on the SAOMechanism settings, refusing to offer may be interpreted as ending the negotiation

  • The negotiator will only receive this call if it has the ‘propose’ capability.

respond(state: SAOState, source: str | None = None) ResponseType | ExtendedResponseType[source]

Called to respond to an offer. This is the method that should be overriden to provide an acceptance strategy.

Parameters:
  • state – a SAOState giving current state of the negotiation.

  • source – The ID of the negotiator that gave this offer

Returns:

The response to the offer

Return type:

ResponseType | ExtendedResponseType

Remarks:

  • The default implementation never ends the negotiation

  • The default implementation asks the negotiator to propose`() and accepts the `offer if its utility was at least as good as the offer that it would have proposed (and above the reserved value).

  • The current offer to respond to can be accessed through state.current_offer

respond_(state: SAOState, source: str | None = None) ResponseType | ExtendedResponseType[source]

The method to be called directly by the mechanism (through counter ) to respond to an offer.

Parameters:
  • state – a SAOState giving current state of the negotiation.

  • source – The ID of the negotiator that gave the offer.

Returns:

The response to the offer. Possible values are:

  • NO_RESPONSE: refuse to offer. Depending on the mechanism settings this may be interpreted as ending

    the negotiation.

  • ACCEPT_OFFER: Accepting the offer.

  • REJECT_OFFER: Rejecting the offer. The negotiator will be given the chance to counter this

    offer through a call of propose_ later if this was not the last offer to be evaluated by the mechanism.

  • END_NEGOTIATION: End the negotiation

  • WAIT: Instructs the mechanism to wait for this negotiator more. It may lead to cycles so use with care.

Return type:

ResponseType | ExtendedResponseType

Remarks:

  • The default implementation never ends the negotiation except if an earler end_negotiation notification is sent to the negotiator

  • The default implementation asks the negotiator to propose`() and accepts the `offer if its utility was at least as good as the offer that it would have proposed (and above the reserved value).

negmas.sao.SAOProtocol[source]

alias of SAOMechanism

class negmas.sao.SAORandomController(*args, p_acceptance: float = 0.1, **kwargs)[source]

Bases: SAOController

A controller that returns random offers.

Parameters:

p_acceptance – The probability of accepting an offer.

propose(negotiator_id: str, state: SAOState, dest: str | None = None) tuple | ExtendedOutcome | None[source]

Generates a random proposal for the given negotiator.

respond(negotiator_id: str, state: SAOState, source: str | None = None) ResponseType | ExtendedResponseType[source]

Generates a random response for the given negotiator.

class negmas.sao.SAORandomSyncController(*args, p_acceptance=0.15, p_rejection=0.85, p_ending=0.0, **kwargs)[source]

Bases: SAOSyncController

A sync controller that returns random offers. (See SAOSyncController ).

Parameters:
  • p_acceptance – The probability that an offer will be accepted

  • p_rejection – The probability that an offer will be rejected

  • p_ending – The probability of ending the negotiation at any negotiation round.

Remarks:

  • If probability of acceptance, rejection and ending sum to less than 1.0, the agent will return NO_RESPONSE with the remaining probability. Depending on the settings of the SAOMechanism this may be treated as ending the negotiation.

counter_all(offers, states)[source]

Generates random counter-offers for all negotiators.

first_proposals()[source]

Generates initial random proposals for all controlled negotiators.

make_response() ResponseType | ExtendedResponseType[source]

Generates a random response based on configured probabilities.

class negmas.sao.SAOResponse(response: ResponseType = ResponseType.NO_RESPONSE, outcome: Outcome | None = None, data: dict[str, Any] | None = None)[source]

Bases: MechanismAction

A response to an offer given by a negotiator in the alternating offers protocol.

This class encapsulates both the response decision and an optional offer, along with any additional data (such as text explanations).

response[source]

The response type (ACCEPT_OFFER, REJECT_OFFER, END_NEGOTIATION, etc.).

Type:

ResponseType

outcome[source]

The proposed outcome/offer, or None if not proposing.

Type:

Outcome | None

data[source]

Optional dictionary of additional data, such as text explanations.

Type:

dict[str, Any] | None

Example

Creating a simple response:

>>> from negmas.sao.common import SAOResponse
>>> from negmas.gb.common import ResponseType
>>> response = SAOResponse(ResponseType.REJECT_OFFER, (5, 10))
>>> response.response
<ResponseType.REJECT_OFFER: 1>

Creating a response from extended types with text:

>>> from negmas.outcomes.common import ExtendedOutcome
>>> from negmas.gb.common import ExtendedResponseType
>>> ext_response = ExtendedResponseType(
...     ResponseType.REJECT_OFFER,
...     data={"text": "Price too high"}
... )
>>> ext_offer = ExtendedOutcome(
...     outcome=(5, 10),
...     data={"text": "Counter offer"}
... )
>>> combined = SAOResponse.from_extended(ext_response, ext_offer)
>>> "Price too high" in combined.data["text"]
True

To customize how text is combined when both response and offer have text, subclass SAOResponse and override the text_combiner class method.

data: dict[str, Any] | None[source]
classmethod from_extended(response: ResponseType | ExtendedResponseType, offer: Outcome | ExtendedOutcome | None) SAOResponse[source]

Create SAOResponse from extended response and offer types.

Parameters:
  • response – The response, either ResponseType or ExtendedResponseType.

  • offer – The offer, either Outcome, ExtendedOutcome, or None.

Returns:

SAOResponse with merged data from both response and offer.

Remarks:
  • If both response and offer have data with the same key, the keys are renamed with “_response” and “_offer” postfixes respectively.

  • If “text” exists in only one of them, it is copied normally.

  • If “text” exists in both, the text_combiner class method is used to combine them.

  • To customize text combination, subclass SAOResponse and override text_combiner.

outcome: Outcome | None[source]
response: ResponseType[source]
classmethod text_combiner(response_text: str, offer_text: str) str[source]

Combine text from response and offer.

Override this method in subclasses to customize text combination behavior.

Parameters:
  • response_text – Text from the response.

  • offer_text – Text from the offer.

Returns:

Combined text string.

class negmas.sao.SAOSingleAgreementAspirationController(*args, max_aspiration: float = 1.0, aspiration_type: Literal['boulware', 'conceder', 'linear'] | int | float = 'boulware', **kwargs)[source]

Bases: SAOSingleAgreementController

A SAOSingleAgreementController that uses aspiration level to decide what to accept and what to propose.

Parameters:
  • preferences – The utility function to use for ALL negotiations

  • max_aspiration – The maximum aspiration level to start with

  • aspiration_type – The aspiration type/ exponent

Remarks:

  • This controller will get at most one agreement. It uses a concession strategy controlled by max_aspiration and aspiration_type as in the AspirationNegotiator for all negotiations.

  • The partner who gives the best proposal will receive an offer that is guaranteed to have a utility value (for the controller) above the current aspiration level.

  • The controller uses a single ufun for all negotiations. This implies that all negotiations should have the same outcome space (i.e. the same issues).

best_offer(offers)[source]

Returns the negotiator ID with the highest utility offer.

best_outcome(negotiator, state=None)[source]

Samples an outcome meeting current aspiration level.

is_acceptable(offer: tuple, source: str, state: SAOState)[source]

Checks if offer utility meets current aspiration level.

is_better(a: tuple | None, b: tuple | None, negotiator: str, state: SAOState) bool[source]

Compares outcomes using the controller’s utility function.

utility_at(x)[source]

Returns the aspiration utility at the given relative time.

class negmas.sao.SAOSingleAgreementController(*args, strict=False, **kwargs)[source]

Bases: SAOSyncController, ABC

A synchronized controller that tries to get no more than one agreeement.

This controller manages a set of negotiations from which only a single one – at most – is likely to result in an agreement. An example of a case in which it is useful is an agent negotiating to buy a car from multiple suppliers. It needs a single car at most but it wants the best one from all of those suppliers. To guarentee a single agreement, pass strict=True

The general algorithm for this controller is something like this:

  • Receive offers from all partners.

  • Find the best offer among them by calling the abstract best_offer method.

  • Check if this best offer is acceptable using the abstract is_acceptable method.

    • If the best offer is acceptable, accept it and end all other negotiations.

    • If the best offer is still not acceptable, then all offers are rejected and with the partner who sent it receiving the result of best_outcome while the rest of the partners receive the result of make_outcome.

  • The default behavior of best_outcome is to return the outcome with maximum utility.

  • The default behavior of make_outcome is to return the best offer received in this round if it is valid for the respective negotiation and the result of best_outcome otherwise.

Parameters:

strict – If True the controller is guaranteed to get a single agreement but it will have to send no-response repeatedly so there is a higher chance of never getting an agreement when two of those controllers negotiate with each other

after_join(negotiator_id, *args, ufun=None, preferences=None, **kwargs) None[source]

Stores best outcome for the negotiator after joining.

abstractmethod best_offer(offers: dict[str, tuple]) str | None[source]

Return the ID of the negotiator with the best offer

Parameters:

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.

best_outcome(negotiator: str, state: SAOState | None = None) tuple | None[source]

The best outcome for the negotiation negotiator engages in given the state .

Parameters:
  • negotiator – The negotiator for which the best outcome is to be found

  • state – If given, the state of the negotiation. If None, should return the absolute best outcome

Returns:

The outcome with maximum utility.

Remarks:

  • The default implementation, just returns the best outcome for this negotiation without considering the state or returns None if it is not possible to find this best outcome.

  • If the negotiator defines a ufun, it is used otherwise the ufun defined for the controller if used (if any)

counter_all(offers: dict[str, tuple | None], states: dict[str, SAOState]) dict[str, SAOResponse][source]

Counters all responses

Parameters:
  • offers – A dictionary mapping partner ID to offer

  • states – A dictionary mapping partner ID to mechanism state

Returns:

A dictionary mapping partner ID to a response

Remarks:

The agent will counter all offers by either ending all negotiations except one which is accepted or by rejecting all offers and countering them using the make_offer method.

first_proposals() dict[str, tuple | None][source]

Generates first proposals, selecting one random partner in strict mode.

abstractmethod is_acceptable(offer: tuple, source: str, state: SAOState) bool[source]

Should decide if the given offer is acceptable

Parameters:
  • offer – The offer being tested

  • source – The ID of the negotiator that received this offer

  • 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.

abstractmethod is_better(a: tuple | None, b: tuple | None, negotiator: str, state: SAOState) bool[source]

Compares two outcomes of the same negotiation

Parameters:
  • a – Outcome

  • b – Outcome

  • negotiator – The negotiator for which the comparison is to be made

  • state – Current state of the negotiation

Returns:

True if utility(a) > utility(b)

make_offer(negotiator: str, state: SAOState, best_offer: tuple | None, best_from: str | None) tuple | None[source]

Generate an offer for the given partner

Parameters:
  • negotiator – The ID of the negotiator for who an offer is to be made.

  • state – The mechanism state of this partner

  • best_offer – The best offer received in this round. None means that no known best offers.

  • best_from – The ID of the negotiator that received the best offer

Returns:

The outcome to be offered to negotiator (None means no-offer)

Remarks:

Default behavior is to offer everyone best_offer if available otherwise, it returns no offers (None). The best_from negotiator will be sending the result of best_outcome.

on_negotiation_end(negotiator_id: str, state: SAOState) None[source]

Handles negotiation end, ending all negotiations if agreement was reached.

response_to_best_offer(negotiator: str, state: SAOState, offer: tuple) tuple | None[source]

Return a response to the partner from which the best current offer was received

Parameters:
  • negotiator – The negotiator from which the best offer was received

  • state – The state of the corresponding negotiation

  • offer – The best offer received at this round.

Returns:

The offer to be sent back to negotiator

class negmas.sao.SAOSingleAgreementRandomController(*args, p_acceptance=0.1, **kwargs)[source]

Bases: SAOSingleAgreementController

A single agreement controller that uses a random negotiation strategy.

Parameters:

p_acceptance – The probability that an offer is accepted

best_offer(offers: dict[str, tuple]) str | None[source]

Returns a random negotiator as having the best offer.

is_acceptable(offer: tuple, source: str, state: SAOState) bool[source]

Checks if offer is acceptable using random probability.

is_better(a: tuple | None, b: tuple | None, negotiator: str, state: SAOState) bool[source]

Randomly determines if outcome a is better than b.

class negmas.sao.SAOState(running: bool = False, waiting: bool = False, started: bool = False, step: int = 0, time: float = 0.0, relative_time: float = 0.0, broken: bool = False, timedout: bool = False, agreement: Outcome | None = None, results: Outcome | OutcomeSpace | tuple[Outcome] | None = None, n_negotiators: int = 0, has_error: bool = False, error_details: str = '', erred_negotiator: str = '', erred_agent: str = '', threads: dict[str, ThreadState] = NOTHING, last_thread: str = '', left_negotiators: set[str] = NOTHING, current_offer: Outcome | None = None, current_proposer: str | None = None, current_proposer_agent: str | None = None, n_acceptances: int = 0, new_offers: list[tuple[str, Outcome | None]] = NOTHING, new_offerer_agents: list[str | None] = NOTHING, last_negotiator: str | None = None, current_data: dict[str, Any] | None = None, new_data: list[tuple[str, dict[str, Any] | None]] = NOTHING)[source]

Bases: GBState

The MechanismState of SAO

current_data: dict[str, Any] | None[source]
current_offer: Outcome | None[source]
current_proposer: str | None[source]
current_proposer_agent: str | None[source]
last_negotiator: str | None[source]
n_acceptances: int[source]
new_data: list[tuple[str, dict[str, Any] | None]][source]
new_offerer_agents: list[str | None][source]
new_offers: list[tuple[str, Outcome | None]][source]
class negmas.sao.SAOSyncController(*args, global_ufun=None, **kwargs)[source]

Bases: SAOController

A controller that can manage multiple negotiators synchronously.

Parameters:

global_ufun – If true, the controller assumes that the ufun is only defined globally for the complete set of negotiations

Remarks:

  • The controller waits for an offer from each one of its negotiators before deciding what to do.

  • Loops may happen if multiple controllers of this type negotiate with each other. For example controller A is negotiating with B, C, while B is also negotiating with C. These loops are broken by the SAOMechanism by forcing some controllers to respond before they have all of the offers. In this case, counter_all will receive offers from one or more negotiators but not all of them.

abstractmethod counter_all(offers: dict[str, tuple | None], states: dict[str, SAOState]) dict[str, SAOResponse][source]

Calculate a response to all offers from all negotiators (negotiator ID is the key).

Parameters:
  • offers – Maps negotiator IDs to offers

  • states – Maps negotiator IDs to offers AT the time the offers were made.

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.

first_offer(negotiator_id: str) tuple | None[source]

Finds the first offer for this given negotiator. By default it will be the best offer

Parameters:

negotiator_id – The ID of the negotiator

Returns:

The first offer to use.

Remarks:

Default behavior is to use the ufun defined for the controller if any then try the ufun defined for the negotiator. If neither exists, the first offer will be None.

first_proposals() dict[str, tuple | None][source]

Gets a set of proposals to use for initializing the negotiation.

is_clean() bool[source]

Checks that the agent has no negotiators and that all its intermediate data-structures are reset

on_negotiation_end(negotiator_id: str, state: SAOState) None[source]

Handles negotiation end by resetting internal state for the negotiator.

propose(negotiator_id: str, state: SAOState, dest: str | None = None) tuple | ExtendedOutcome | None[source]

Generates a synchronized proposal for the given negotiator.

reset()[source]

Clears all cached offers, responses, and proposals to prepare for new negotiations.

respond(negotiator_id: str, state: SAOState, source: str | None = None) ResponseType | ExtendedResponseType[source]

Generates a synchronized response for the given negotiator.

negmas.sao.SimpleTitForTatNegotiator[source]

alias of NaiveTitForTatNegotiator

class negmas.sao.TFTAcceptancePolicy(partner_ufun: UFunModel, recommender: ConcessionRecommender, *, negotiator: GBNegotiator | None = None)[source]

Bases: AcceptancePolicy

An acceptance strategy that concedes as much as the partner (or more)

partner_ufun: UFunModel[source]
recommender: ConcessionRecommender[source]
class negmas.sao.TFTOfferingPolicy(partner_ufun: UFunModel, recommender: ConcessionRecommender, stochastic: bool = False, *, negotiator: GBNegotiator | None = None)[source]

Bases: OfferingPolicy

An acceptance strategy that concedes as much as the partner (or more)

before_responding(state: GBState, offer: Outcome | None, source: str | None = None)[source]

Stores the partner’s latest offer for concession calculation.

on_preferences_changed(changes: list[PreferencesChange])[source]

Propagates preference changes to the partner utility model.

partner_ufun: UFunModel[source]
recommender: ConcessionRecommender[source]
stochastic: bool[source]
class negmas.sao.TimeBasedConcedingNegotiator(*args, offering_curve: Aspiration | Literal['boulware'] | Literal['conceder'] | Literal['linear'] | float = 'boulware', accepting_curve: Aspiration | Literal['boulware'] | Literal['conceder'] | Literal['linear'] | float | None = None, starting_utility: float = 1.0, **kwargs)[source]

Bases: TimeBasedNegotiator

Represents a time-based negotiation strategy that is independent of the offers received during the negotiation.

Parameters:
  • offering_curve (TimeCurve) – A TimeCurve that is to be used to sample outcomes when offering

  • accepting_curve (TimeCurve) – A TimeCurve that is to be used to decide utility range to accept

  • starting_utility (float) – The relative utility (range 1.0 to 0.0) at which to give the first offer. Only used if offering_curve was not given

class negmas.sao.TimeBasedNegotiator(*args, offering_curve: TimeCurve | Literal['boulware'] | Literal['conceder'] | Literal['linear'] | float = 'boulware', accepting_curve: TimeCurve | Literal['boulware'] | Literal['conceder'] | Literal['linear'] | float | None = None, offer_selector: OfferSelector | None = None, **kwargs)[source]

Bases: UtilBasedNegotiator

Represents a time-based negotiation strategy that is independent of the offers received during the negotiation.

Parameters:
  • offering_curve (TimeCurve) – A TimeCurve that is to be used to sample outcomes when offering

  • accepting_curve (TimeCurve) – A TimeCurve that is to be used to decide utility range to accept

  • inverter (UtilityInverter) – A component used to keep track of the ufun inverse

  • offer_selector (OfferSelector) – The way to select an offer from the set of valid offers at every time-step

utility_range_to_accept(state) tuple[float, float][source]

Returns the acceptable utility range for accepting offers at the current negotiation state.

utility_range_to_propose(state) tuple[float, float][source]

Returns the acceptable utility range for making proposals at the current negotiation state.

class negmas.sao.TimeBasedOfferingPolicy(curve: PolyAspiration = NOTHING, stochastic: bool = False, sorter: PresortingInverseUtilityFunction | None = None, *, negotiator: GBNegotiator | None = None)[source]

Bases: OfferingPolicy

TimeBasedOffering policy implementation.

curve: PolyAspiration[source]
on_preferences_changed(changes: list[PreferencesChange])[source]

Initializes the outcome sorter when preferences are set or changed.

Handles different change types appropriately: - Initialization/General: Initialize the sorter (warn if already initialized) - Scale/ReservedValue/ReservedOutcome: Ignored (don’t affect outcome ordering)

sorter: PresortingInverseUtilityFunction | None[source]
stochastic: bool[source]
class negmas.sao.TopFractionNegotiator(min_utility=0.95, top_fraction=0.05, best_first=True, can_propose=True, **kwargs)[source]

Bases: MAPNegotiator

Offers and accepts only one of the top outcomes for the negotiator.

Parameters:
  • name – Negotiator name

  • parent – Parent controller if any

  • can_propose – If False the negotiator will never propose but can only accept

  • preferences – The preferences of the negotiator

  • ufun – The ufun of the negotiator (overrides preferences)

  • min_utility – The minimum utility to offer or accept

  • top_fraction – The fraction of the outcomes (ordered decreasingly by utility) to offer or accept

  • best_first – Guarantee offering will non-increasing in terms of utility value

  • probabilistic_offering – Offer randomly from the outcomes selected based on top_fraction and min_utility

  • owner – The Agent that owns the negotiator.

propose(state, dest: str | None = None)[source]

Propose.

Parameters:
  • state – Current state.

  • dest – Dest.

class negmas.sao.ToughNegotiator(can_propose=True, **kwargs)[source]

Bases: MAPNegotiator

Accepts and proposes only the top offer (i.e. the one with highest utility).

Parameters:
  • name – Negotiator name

  • parent – Parent controller if any

  • can_propose – If False the negotiator will never propose but can only accept

  • preferences – The preferences of the negotiator

  • ufun – The ufun of the negotiator (overrides preferences)

  • owner – The Agent that owns the negotiator.

Remarks:
  • If there are multiple outcome with the same maximum utility, only one of them will be used.

class negmas.sao.TraceElement(time, relative_time, step, negotiator, offer, responses, state, text, data)[source]

Bases: tuple

data[source]

Alias for field number 8

negotiator[source]

Alias for field number 3

offer[source]

Alias for field number 4

relative_time[source]

Alias for field number 1

responses[source]

Alias for field number 5

state[source]

Alias for field number 6

step[source]

Alias for field number 2

text[source]

Alias for field number 7

time[source]

Alias for field number 0

class negmas.sao.UFunModel(*, negotiator: GBNegotiator | None = None)[source]

Bases: GBComponent, BaseUtilityFunction

A SAOComponent that can model the opponent’s utility function.

Classes implementing this ufun-model, must implement the abstract eval() method to return the utility value of an outcome. They can use any callbacks available to SAOComponent to update the model.

class negmas.sao.UnanimousConcensusOfferingPolicy(strategies: list[OfferingPolicy], *, negotiator: GBNegotiator | None = None)[source]

Bases: ConcensusOfferingPolicy

Offers only if all offering strategies gave exactly the same outcome

decide(indices: list[int], responses: list[Outcome | ExtendedOutcome | None]) Outcome | ExtendedOutcome | None[source]

Returns the outcome only if all strategies agree, otherwise None.

Parameters:
  • indices – Indices of strategies that passed the filter.

  • responses – Outcomes proposed by the filtered strategies.

Returns:

The unanimous outcome, or None if strategies disagree.

class negmas.sao.UtilBasedConcensusOfferingPolicy(strategies: list[OfferingPolicy], *, negotiator: GBNegotiator | None = None)[source]

Bases: ConcensusOfferingPolicy, ABC

Offers from the list of stratgies (different strategy every time) based on outcome utilities

decide(indices: list[int], responses: list[Outcome | ExtendedOutcome | None]) Outcome | ExtendedOutcome | None[source]

Selects an outcome based on utility values using the decide_util method.

Parameters:
  • indices – Indices of strategies that passed the filter.

  • responses – Outcomes proposed by the filtered strategies.

Returns:

The outcome selected by the utility-based decision rule.

abstractmethod decide_util(utils: list[Distribution | float]) int[source]

Returns the index to chose based on utils

class negmas.sao.UtilBasedNegotiator(*args, stochastic: bool = False, rank_only: bool = False, ufun_inverter: Callable[[BaseUtilityFunction], InverseUFun] | None = None, offer_selector: OfferSelector | None = None, max_cardinality: int = 10000000, eps: float = 0.0001, **kwargs)[source]

Bases: GBNegotiator

A negotiator that bases its decisions on the utility value of outcomes only.

Parameters:
  • inverter (UtilityInverter) – A component used to keep track of the ufun inverse

  • stochastic (bool) – If False the worst outcome in the current utility range will be used

  • rank_only (bool) – If True then the ranks of outcomes not their actual utilities will be used for decision making

  • max_cardinality (int) – The number of outocmes at which we switch to use the slower SamplingInverseUtilityFunction instead of the PresortingInverseUtilityFunction . Will only be used if ufun_inverter is None

  • eps (float) – A tolearnace around the utility range used when sampling outocmes

on_preferences_changed(changes: list[PreferencesChange])[source]

On preferences changed.

Parameters:

changes – Changes.

propose(state, dest: str | None = None)[source]

Propose.

Parameters:
  • state – Current state.

  • dest – Dest.

respond(state, source: str | None = None) ResponseType | ExtendedResponseType[source]

Respond.

Parameters:
  • state – Current state.

  • source – Source identifier.

Returns:

The result.

Return type:

ResponseType

abstractmethod utility_range_to_accept(state) tuple[float, float][source]

Utility range to accept.

Parameters:

state – Current state.

Returns:

The result.

Return type:

tuple[float, float]

abstractmethod utility_range_to_propose(state) tuple[float, float][source]

Utility range to propose.

Parameters:

state – Current state.

Returns:

The result.

Return type:

tuple[float, float]

class negmas.sao.UtilityBasedOutcomeSetRecommender(rank_only: bool = False, ufun_inverter: Callable[[BaseUtilityFunction], InverseUFun] | None = None, max_cardinality: int | float = inf, eps: float = 0.0001, inversion_method: Literal['min', 'max', 'one', 'some', 'all'] = 'some')[source]

Bases: GBComponent

Recommends a set of outcome appropriate for proposal

before_proposing(state: GBState, dest: str | None = None)[source]

Ensures the inverter is initialized before making a proposal.

on_preferences_changed(changes: list[PreferencesChange])[source]

Rebuilds the inverse utility function when preferences change.

scale_utilities(urange: tuple[float, ...]) tuple[float, ...][source]

Scales given utilities to the range of the ufun.

Remarks:

  • Assumes that the input utilities are in the range [0-1] no matter what is the range of the ufun.

  • Subtracts the tolerance from the first and adds it to the last utility value which slightly enlarges the range to account for small rounding errors

set_negotiator(negotiator: GBNegotiator) None[source]

Attaches this component to a negotiator and resets internal state.

property tolerance[source]

Returns the epsilon value used to expand utility ranges.

property ufun_max[source]

Returns the maximum utility value from the utility function.

property ufun_min[source]

Returns the minimum utility value from the utility function.

class negmas.sao.UtilityInverter(*args, offer_selector: OfferSelectorProtocol | Literal['min'] | Literal['max'] | None = None, **kwargs)[source]

Bases: GBComponent

A component that can recommend an outcome based on utility

before_proposing(state: GBState, dest: str | None = None)[source]

Prepares the recommender before making a proposal.

on_preferences_changed(changes: list[PreferencesChange])[source]

Forwards preference changes to the underlying recommender.

scale_utilities(urange)[source]

Scales normalized [0-1] utilities to the actual ufun range.

set_negotiator(negotiator: GBNegotiator) None[source]

Attaches this component and its recommender to a negotiator.

property tolerance[source]

Returns the epsilon value used to expand utility ranges.

property ufun_max[source]

Returns the maximum utility value from the recommender.

property ufun_min[source]

Returns the minimum utility value from the recommender.

class negmas.sao.WABNegotiator(*args, **kwargs)[source]

Bases: MAPNegotiator

Wasting Accepting Better (neither complete nor an equilibrium)

Parameters:
  • name – Negotiator name

  • parent – Parent controller if any

  • preferences – The preferences of the negotiator

  • ufun – The ufun of the negotiator (overrides preferences)

  • owner – The Agent that owns the negotiator.

class negmas.sao.WANNegotiator(*args, **kwargs)[source]

Bases: MAPNegotiator

Wasting Accepting Any (an equilibrium but not complete)

Parameters:
  • name – Negotiator name

  • parent – Parent controller if any

  • preferences – The preferences of the negotiator

  • ufun – The ufun of the negotiator (overrides preferences)

  • owner – The Agent that owns the negotiator.

class negmas.sao.WARNegotiator(*args, **kwargs)[source]

Bases: MAPNegotiator

Wasting Accepting Any (an equilibrium but not complete)

Parameters:
  • name – Negotiator name

  • parent – Parent controller if any

  • preferences – The preferences of the negotiator

  • ufun – The ufun of the negotiator (overrides preferences)

  • owner – The Agent that owns the negotiator.

class negmas.sao.WAROfferingPolicy(next_indx: int = 0, sorter: PresortingInverseUtilityFunction | None = None, *, negotiator: GBNegotiator | None = None)[source]

Bases: OfferingPolicy

WAROffering policy implementation.

next_indx: int[source]
on_negotiation_start(state) None[source]

Resets state to start with irrational (worst) offers.

on_preferences_changed(changes: list[PreferencesChange])[source]

Initializes outcome sorter and irrational offer tracking on preference changes.

sorter: PresortingInverseUtilityFunction | None[source]
class negmas.sao.WorstOfferSelector(*args, **kwargs)[source]

Bases: OfferSelector

Selects the outcome with the lowest utility value.

class negmas.sao.ZeroSumModel(above_reserve: bool = True, rank_only: bool = False, *, negotiator: GBNegotiator | None = None)[source]

Bases: UFunModel

Assumes a zero-sum negotiation (i.e. $u_o$ = $-u_s$ )

Remarks:

  • Because some negotiators do not work well with negative ufun values, we return (max - u(w)) instead of (- u(w))

above_reserve: bool[source]
eval(offer: Outcome) Value[source]

Eval.

Parameters:

offer – Offer being considered.

Returns:

The result.

Return type:

Value

eval_normalized(offer: Outcome | None, above_reserve: bool = True, expected_limits: bool = True) Value[source]

Eval normalized.

Parameters:
  • offer – Offer being considered.

  • above_reserve – Above reserve.

  • expected_limits – Expected limits.

Returns:

The result.

Return type:

Value

on_preferences_changed(changes: list[PreferencesChange])[source]

On preferences changed.

Parameters:

changes – Changes.

rank_only: bool[source]
negmas.sao.all_negotiator_types() list[type[SAONegotiator]][source]

Returns all the negotiator types defined in negmas.sao.negotiators