negmas.elicitation

” The interface to all negotiators capable of eliciting user preferences before , and during negotiations.

class negmas.elicitation.Answer(outcomes: list[tuple], constraint: Constraint, cost: float = 0.0, name: str = '')[source]

Bases: object

Answer implementation.

constraint: Constraint[source]
cost: float = 0.0[source]
name: str = ''[source]
outcomes: list[tuple][source]
class negmas.elicitation.AspiringElicitor(strategy: EStrategy, user: User, *, max_aspiration: float = 1.0, aspiration_type: float | str = 'linear', **kwargs)[source]

Bases: OptimalIncrementalElicitor

Same as OptimalIncrementalElicitor using aspiration level for estimating utilities.

class negmas.elicitation.BalancedElicitor(strategy: EStrategy, user: User, **kwargs)[source]

Bases: OptimalIncrementalElicitor

Same as OptimalIncrementalElicitor using MeanExpector for estimating utilities

class negmas.elicitation.BaseElicitor(user: ~negmas.elicitation.user.User, *, strategy: ~negmas.elicitation.strategy.EStrategy | None = None, base_negotiator: ~negmas.sao.negotiators.base.SAOPRNegotiator = <negmas.gb.negotiators.timebased.AspirationNegotiator object>, opponent_model_factory: None | ~typing.Callable[[~negmas.common.NegotiatorMechanismInterface], ~negmas.models.acceptance.DiscreteAcceptanceModel] = <function BaseElicitor.<lambda>>, expector_factory: ~negmas.elicitation.expectors.Expector | ~typing.Callable[[], ~negmas.elicitation.expectors.Expector] = <class 'negmas.elicitation.expectors.MeanExpector'>, single_elicitation_per_round=False, continue_eliciting_past_reserved_val=False, epsilon=0.001, true_utility_on_zero_cost=False)[source]

Bases: SAOPRNegotiator

BaseElicitor implementation.

accuracy_limit(cost: float) float[source]

The accuracy limit given the cost and epsilon.

before_eliciting() None[source]

Called by apply just before continuously calling elicit_single

best_offer(state: MechanismState) tuple[tuple | None, float][source]

The outcome with maximum expected utility given the expector and its utility

Parameters:

state – The mechanism state

Returns:

A tuple containing the best outcome (or None) and its expected utility using the expector (or reserved value)

Remarks:
  • if there are no offerable outcomes, elicitation is done and if still there are no offerable outcomes, the reserved value is returned (with None as outcome)

  • Only offerable outcomes are checked.

  • The best outcome is defined as the one with maximum expect applied to offering_utility.

abstractmethod can_elicit() bool[source]

Returns whether we can do more elicitation

elicit(state: MechanismState) None[source]

Called to do utility elicitation whenever needed.

Parameters:

state – mechanism state

Remarks:
  • Keeps track of elicitation time and asking time.

  • If the maximum attainable utility minus elicitation cost is less than the reserved value, no elicitation will take place because we will end this negotiation anyway. Note that the maximum attainable utility can never go up.

  • Calls before_eliciting once to initialize the process then calls elicit_single which does the actual elicitation. This is done only once if single_elicitation is set, otherwise it is repeated until one of the following conditiosn is met:

    • elicit_single returns False

    • The maximum attainable utility (minus elicitation cost) is less than the reserved value.

abstractmethod elicit_single(state: MechanismState) None[source]

Does a single elicitation act

Parameters:

state – mechanism state

property elicitation_cost: float[source]

The total elicitation cost.

property elicitation_time: float[source]

The total elicitation time in seconds.

init_elicitation(preferences: None | IPUtilityFunction | ScipyDistribution | list[ScipyDistribution], **kwargs) None[source]

Called once to initialize the elicitation process

Parameters:
  • preferences – The probabilistic utility function

  • **kwargs

Remarks:
  • If no ufun is given one will be created with 0-1 uniform distributions and zero reserved value.

  • If a single Distribution is given as ufun, it is repeated for all outcomes (and the reserved value is set to zero).

  • If a list of Distribution s is given, it must have the same length as the list of outcomes of this negotiation and is used to set the ufun.

  • The opponent model

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

Called to join a negotiation.

Remarks:
  • uses the base_negotiator to join the negotiation.

  • creates a MappingUtilityFunction that maps every outcome to the result of the expector applied to the corresponding utility value.

  • The reserved value of the created ufun is set to -inf

maximum_attainable_utility() float[source]

Maximum utility that could even in principle be attained which simply means the utility value of the outcome with maximum utility.

minimum_guaranteed_utility()[source]

Minimum utility that could even in principle be attained which simply means the utility value of the outcome with minimum utility.

offering_utilities(state) ndarray[source]

Calculates the offering utility for all outcomes

Parameters:

state – Calculates the state at which the offering utilities are to be calculated

Returns:

An ndarray with the offering utility of every outcome (in order)

Remarks:
offering_utility(outcome, state) Distribution | float[source]

returns expected utlity of offering outcome in state

Parameters:
  • outcome – The outcome

  • state – The state

Returns:

A utility value

Remarks:
  • returns $u(o) p(o) + ru(o) (1-p(o))$ where $p$ is the opponent model, $u$ is the utility function, and $r$ is the utility in case of rejections.

  • state is needed when calculating $r(o)$ by calling utility_on_rejection.

  • Note that if $u$ or $r$ return a Distribution, this method will return a Distribution not a real number.

on_negotiation_start(state: MechanismState)[source]

Called when the negotiation starts. Just passes the call to base_negotiator.

on_opponent_model_updated(outcomes: list[tuple], old: list[float], new: list[float]) None[source]

Called whenever an opponents model is updated.

Parameters:
  • outcomes – A list of outcomes for which the acceptance probability are changed

  • old – The old acceptance probability

  • new – The new acceptance probability

on_partner_proposal(state: MechanismState, partner_id: str, offer: tuple)[source]

Called when one of the partners propose (only if enable_callbacks is set in the SAOMechanism).

Parameters:
  • state – mechanism state

  • partner_id – the partner who proposed

  • offer – The offer from the partner

Remarks:
on_partner_response(state: MechanismState, partner_id: str, outcome: tuple, response: ResponseType)[source]

Called when one of the partners respond (only if enable_callbacks is set in the SAOMechanism).

Parameters:
  • state – mechanism state

  • partner_id – the partner who offered

  • outcome – The outcome responded to

  • response – The partner response including both the response and outcome

Remarks:
  • Used to update the opponent model by calling update_rejected or update_accepted1 then `on_opponent_model_updated.

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

Called to propose an outcome

Parameters:

state – mechanism state

Remarks:

  • if the negotiator can_elicit, it will elicit.

  • always then calls the base negotiator to propose.

respond_(state: MechanismState, offer: tuple) ResponseType[source]

Called by the mechanism directly (through counter ) to respond to offers.

Parameters:
  • state – mechanism state

  • offer – the offer to respond to

Remarks:
  • Does the following steps:

    1. Finds the the best offer using best_offer and uses the base negotiator to respond if that offer was None

    2. Looks at offerable_outcomes and applies the elicitation strategy (one step) to the outcome if it was not offerable (or if there are no offerable outcomes defined).

    3. Finds the utility of the offer using utility_function not taking into accout elicitation cost and uses the base negotiator if that fails (i.e. utility_function returns None).

    4. Finds the expected utility of the offer using the expect () method which calls the expector passed during construction.

    5. If the maximum attainable utility now (judging from the current estimation of the utility value of each outcome taking elicitation cost into account) is less than the reserved value, end the negotiation

    6. If the utility of my best offer (returned from best_offer) is less than the offered utility, accept the offer

    7. Otherwise, call bhe base negotiator to respond.

user_preferences(outcome: tuple | None) float[source]

Finds the total utility obtained by the user for this outcome after discounting elicitation cost.

Parameters:

outcome – The outcome to find the user utility for. If None, it returns the reserved value.

Remarks:

The total elicitation cost is not discounted from the reserved value when the input is None

utilities_on_rejection(state: MechanismState) list[Distribution | float][source]

Finds the utility of rejection for all outputs.

Remarks:
  • By default it calls utility_on_rejection repeatedly for all outcomes. Override this method if a faster versin can be implemented

utility_distributions() list[ScipyDistribution][source]

Returns a Distribution for every outcome

utility_on_acceptance(outcome: tuple) Distribution | float[source]

The utility of acceptance which is simply the utility function applied to outcome.

utility_on_rejection(outcome: tuple, state: MechanismState) Distribution | float[source]

Estimated utility if this outcome rejected at this state.

Parameters:
  • outcome – The outcome tested

  • state – The mechanism state

Remarks:
  • MUST be implemented by any Elicitor.

class negmas.elicitation.BasePandoraElicitor(user: User, strategy: EStrategy, *, base_negotiator: SAONegotiator = <negmas.gb.negotiators.timebased.AspirationNegotiator object>, deep_elicitation: bool, opponent_model_factory: None | Callable[[NegotiatorMechanismInterface], DiscreteAcceptanceModel] = <function BasePandoraElicitor.<lambda>>, expector_factory: Expector | Callable[[], Expector] = <class 'negmas.elicitation.expectors.MeanExpector'>, single_elicitation_per_round=False, continue_eliciting_past_reserved_val=False, epsilon=0.001, true_utility_on_zero_cost=False, assume_uniform=True, user_model_in_index=True, precalculated_index=False, incremental=True, max_aspiration=0.99, aspiration_type='boulware')[source]

Bases: BaseElicitor

The base class of all Pandora’s box based algorithms.

Parameters:
  • user – A User object that can be elicited

  • strategy – An elicitation strategy that determines the questions to be asked and their order.

  • base_negotiator – The base negotiator used for responding and proposing

  • deep_elicitation – If True, a single elicitation act (elicit_single) will elicit the utility value of an outcome until its uncertainty is under epsilon.

  • opponent_model_factory – A callable to create opponent models. An opponent model is used to estimate acceptance probability of outcomes.

  • expector_factory – A callable to create an Expector

  • single_elicitation_per_round – If True, only a single elicitation act (call to elicit_single is allowed per negotiation round.

  • continue_eliciting_past_reserved_val – If True, continue elicitation even if the estimated utility is under the reserved value.

  • epsilon – A small number to represent small uncertainty after which no more elicitation is done.

  • true_utility_on_zero_cost – If True, zero cost will force the final elicited value of any outcome to exactly match the utility function. If False, the final utility value after elicitation may be within epsilon from the true value.

  • assume_uniform – If True, assume that all utility distributions are uniform

  • user_model_in_index – Use the user model in the index

  • precalculated_index – The index is calculated once and never updated when the opponent model probabilities of acceptance change.

  • incremental – Only valid if precalculated_index is not set. If set, only the outcomes for which the opponemt model acceptance probability have changed will be updated whenever such a change occures. Otherwise, all outcomes will be updated on every change.

  • max_aspiration – Maximum aspiration.

  • aspiration_type – Aspiration type. Can be “boulware”, “linear”, “conceder” or a numric exponent.

before_eliciting()[source]

Called before starting elicitation at every negotiation round.

Remarks:
  • It just updates cutoff utility

can_elicit() bool[source]

Checks whether there are any unknowns in the unknowns list.

do_elicit(outcome: tuple, state: MechanismState) Distribution | float[source]

Does a real elicitation step.

Parameters:
  • outcome – The outcome to elicit

  • state – The state at which elicitation is happening

Remarks:
  • If deep_elicitation is set, the strategy is applied until the uncertainty in the utility value for outcome is less than the accuracty limit otherwise, apply it once.

elicit_single(state: MechanismState)[source]

Does a single elicitation act

Parameters:

state – mechanism state

Remarks:

The process goes as follows:

  1. Find the offer to elicit using offer_to_elicit.

  2. If the utility of that offer is less than the cutoff utility, or the best offer to elicit is None, stop eliciting and return.

  3. call do_elicit once.

  4. update the distribution of the elicited outcome

  5. add the elicited outcome to the offerable outcomes

  6. If the utility of the best outcome is a number, remove it from the unknown outcomes list otherwise jsut update it

  7. Update the cutoff utility and elicitation history.

init_elicitation(preferences: IPUtilityFunction | Distribution | None, **kwargs)[source]

Initializes the elicitation process (called only once).

Remarks:

init_unknowns()[source]

Initializes the unknowns list which is a list of Tuples [-u(o), o] for o in outcomes.

offer_to_elicit() tuple[float, int | None][source]

Returns the maximum estimaged utility and the corresponding outocme

Remarks:
  • This method assumes that each element of the unkown list is a tuple of negative the utility value and the outcome.

  • It also assumest that the first item in the unknown list contains the outocme with maximum estimated utility and the negative of the corresponding estimated utility.

on_opponent_model_updated(outcomes: list[tuple], old: list[float], new: list[float]) None[source]

Called when the opponent model is updated.

Parameters:
  • outcomes – changed outcomes

  • old – old probabilities of acceptance

  • new – new probabilities of acceptance

Remarks:

Updates the unknown list only if precalculated_index was not set.

remove_best_offer_from_unknown_list() tuple[float, int][source]

Removes the best offer from the unkonwn list and returns it.

update_best_offer_utility(outcome: tuple, u: Distribution | float)[source]

Updates the unknown list (and makes sure it is a heap) given the given utility value for the given outcome.

update_cutoff_utility() None[source]

Updates the cutoff utility under which no elicitation is done.

Remarks:
  • By default it uses \(max_{o \in \Omega \cup \phi}{u(o)}\) for all outcomes \(o \in \Omega\) and the None outcome representing reserved value

utility_at(x)[source]

Utility at.

Parameters:

x

utility_on_rejection(outcome: tuple, state: MechanismState) Distribution | float[source]

Uses the aspiration level as the utility of rejection.

Remarks:
z_index(updated_outcomes: list[tuple] | None = None)[source]

Update the internal z-index or create it if needed.

Parameters:

updated_outcomes – A list of the outcomes with updated utility values.

class negmas.elicitation.BaseVOIElicitor(strategy: EStrategy, user: User, *, dynamic_query_set=False, queries=None, adaptive_answer_probabilities=True, each_outcome_once=False, update_related_queries=True, **kwargs)[source]

Bases: BaseElicitor

Base class for all value of information (VOI) elicitation algorithms

Parameters:
  • strategy – The elicitation strategy. It is only used if dynamic_query_set is set. In that case, the strategy is used to compile the set of all possible queries during construction. If using dynamic_query_set pass None for the strategy.

  • user – The User to elicit.

  • base_negotiator – The base negotiator used for proposing and responding.

  • dynamic_query_set – If given, the user of the object is supposed to manage the queries manually and the strategy is not used.

  • queries – An optinal list of queries to use.

  • adaptive_answer_probabilities – If True, answer probabilities will not be considered equal for all possible answers. The probability of getting an answer will be based on the current estimate of the utility value distribution.

  • expector_factory – A Callable used to estimate real-valued utilities given a distribution.

  • opponent_model_factory – A Callable used to construct the opponent model.

  • single_elicitation_per_round – If set, a single query is allowed per round.

  • continue_eliciting_past_reserved_val – If set, elicition will continue even if the estimated utility of an outcome is less than the reserved value.

  • epsilon – A small number used to stop elicitation when the uncertainty in the utility value is within it.

  • true_utility_on_zero_cost – If set, the true utility will be elicited for outcomes if the elicitation cost is zero.

  • each_outcome_once – If set, each outcome is to be offered exactly once.

  • update_related_queries – If set, queries that are related to one that was asked and answered will get updated based on the answer.

add_query(qeeu: tuple[float, int]) None[source]

Adds a query to the heap of queries

Parameters:

qeeu – A Tuple giving (-EEU, query_index)

Remarks:
  • Note that the first member of the tuple is minus the EEU

  • The sedond member of the tuple is an index of the query in the queries list (not the query itself).

before_eliciting()[source]

Called every round before trying to elicit. Does nothing

best_offer(state: MechanismState) tuple[tuple | None, float][source]

The best offer and its corresponding utility

Parameters:

state – The mechanism state

Remarks:
  • It will return (None, reserved-value) if the best outcome has a utility less than the reserved value.

  • It uses the internal eu_policy heap to find the best outcome.

  • If each-outcome-once is set, the best outcome is popped from the heap which prevents it from ever being selected again.

best_offers(n: int) list[tuple[tuple | None, float]][source]

Returns the best offer repeated n times

can_elicit() bool[source]

Always can elicit

elicit_single(state: MechanismState)[source]

Called to conduct a single eliciataion act.

Parameters:

state – The mechanism state

Remarks:
  • It returns False ending eliciatation if eeu_query is empty or can_elicit returns False

  • The algorithm outline is as follows:

    1. Pops the top query with its EEU from the heap

    2. elicitation is stopped if the top query is None, the eeu is less than the current EEU, or the EEU after asking will be less than the reserved value.

    3. If dynamic_query_set, the strategy is invoked to get the next query, otherwise, the user is asked the top query and the related queries are updated.

    4. The expected utility is updated base on the answer received from the user and update_optimal_policy is called followed by init_query_eeus.

init_elicitation(preferences: IPUtilityFunction | Distribution | None, queries: list[Query] | None = None, **kwargs) None[source]

Initializes the elicitation process once.

Remarks:
  • After calling parent, it checks that dynamic_query_set, queries and strategy settings are consistent.

  • It then calls, init_optimal_policy to initialize the optimal policy

  • The set of queries is updated from the strategy if needed and a mapping from outcomes to their queries is created if update_related_queries is set to be used for updating related queries later.

  • It then calls init_query_eeus to initialize the EEU of all queries.

abstractmethod init_optimal_policy() None[source]

Gets the optimal policy given Negotiator utility_priors.

The optimal plicy should be sorted ascendingly on -EU or -EU * Acceptance

init_query_eeus() None[source]

Updates the heap eeu_query which has records of (-EEU, quesion)

on_opponent_model_updated(outcomes: list[tuple], old: list[float], new: list[float]) None[source]

Called whenever the opponent model is updated.

Parameters:
  • outcomes – The updated outomes. None means all outcomes

  • old – The old acceptance probabilities

  • new – The new acceptance probabilities

Remarks:

It calls init_optimal_policy and init_query_eeus if any old value is not equal to a new value.

update_optimal_policy(index: int, outcome: tuple, oldu: float, newu: float)[source]

Updates the optimal policy after a change to the utility value of some outcome.

Parameters:
  • outcome – The outcome whose utiltiy have changed

  • oldu – The old utility

  • newu – The new utility

Remarks:

It just calls update_optimal_policy

utility_on_rejection(outcome: tuple, state: MechanismState) Distribution | float[source]

Utility on rejection.

Parameters:
  • outcome – Outcome to evaluate.

  • state – Current state.

Returns:

The result.

Return type:

Value

class negmas.elicitation.ComparisonConstraint(op: str | Callable[[Distribution | float, Distribution | float], bool], full_range: Sequence[tuple[float, float]] | tuple[float, float] = (0.0, 1.0), outcomes: list[tuple] = None)[source]

Bases: MarginalNeutralConstraint

Constraints the utility of given two outcomes (must be exactly two) to satisfy the given operation (e.g. >, <)

is_satisfied(preferences: Preferences, outcomes: Iterable[tuple] | None = None) bool[source]

Check if satisfied.

Parameters:
  • preferences – Preferences.

  • outcomes – Outcomes.

Returns:

The result.

Return type:

bool

class negmas.elicitation.Constraint(full_range: Sequence[tuple[float, float]] | tuple[float, float] = (0.0, 1.0), outcomes: list[tuple] = None)[source]

Bases: ABC

Some constraint on allowable utility values for given outcomes.

abstractmethod is_satisfied(preferences: Preferences, outcomes: Iterable[tuple] | None = None) bool[source]

Whether or not the constraint is satisfied.

abstractmethod marginal(outcome: tuple) ScipyDistribution[source]

Marginal.

Parameters:

outcome – Outcome to evaluate.

Returns:

The result.

Return type:

ScipyDistribution

abstractmethod marginals(outcomes: Iterable[tuple] = None) list[ScipyDistribution][source]

Marginals.

Parameters:

outcomes – Outcomes.

Returns:

The result.

Return type:

list[ScipyDistribution]

class negmas.elicitation.CostEvaluator(cost: float)[source]

Bases: object

CostEvaluator implementation.

class negmas.elicitation.DummyElicitor(user: ~negmas.elicitation.user.User, *, strategy: ~negmas.elicitation.strategy.EStrategy | None = None, base_negotiator: ~negmas.sao.negotiators.base.SAOPRNegotiator = <negmas.gb.negotiators.timebased.AspirationNegotiator object>, opponent_model_factory: None | ~typing.Callable[[~negmas.common.NegotiatorMechanismInterface], ~negmas.models.acceptance.DiscreteAcceptanceModel] = <function BaseElicitor.<lambda>>, expector_factory: ~negmas.elicitation.expectors.Expector | ~typing.Callable[[], ~negmas.elicitation.expectors.Expector] = <class 'negmas.elicitation.expectors.MeanExpector'>, single_elicitation_per_round=False, continue_eliciting_past_reserved_val=False, epsilon=0.001, true_utility_on_zero_cost=False)[source]

Bases: BaseElicitor

A dummy elicitation algorithm that does not do any elicitation.

can_elicit() bool[source]

Can elicit.

Returns:

The result.

Return type:

bool

elicit_single(state: MechanismState)[source]

Elicit single.

Parameters:

state – Current state.

init_elicitation(preferences: IPUtilityFunction | Distribution | None, **kwargs)[source]

Init elicitation.

Parameters:
  • preferences – Preferences.

  • **kwargs – Additional keyword arguments.

utility_on_rejection(outcome: tuple, state: MechanismState) Distribution | float[source]

Utility on rejection.

Parameters:
  • outcome – Outcome to evaluate.

  • state – Current state.

Returns:

The result.

Return type:

Value

class negmas.elicitation.EStrategy(strategy: str, resolution=0.0001, stop_at_cost: bool = True)[source]

Bases: object

A proxy for a user that have some true utilities which can be elicited.

Parameters:

strategy – a string specifying the elicitation strategy or a callable.

Remarks:

  • Supported string elicitation_strategies can be found using the supported_strategies class method

  • If a callable is passed then it must receive four float numbers indicating the lower and upper boundaries of the current Negotiator distribution, the true Negotiator and a threshold (resolution). It must return a new lower and upper values. To stop eliciting and return an exact number, the callable should set lower to the same value as upper

apply(user: User, outcome: Outcome) tuple[Value | None, QResponse | None][source]

Do the elicitation and incur the cost.

Remarks:

  • This function returns a uniform distribution whenever it returns a distribution

  • Can return None which indicates that elicitation failed

  • If it could find an exact value, it will return a float not a Distribution

next_query(outcome: Outcome) Query | None[source]

Next query.

Parameters:

outcome – Outcome to evaluate.

Returns:

The result.

Return type:

Query | None

on_enter(nmi: NegotiatorMechanismInterface, preferences: IPUtilityFunction = None) None[source]

On enter.

Parameters:
  • nmi – Nmi.

  • preferences – Preferences.

classmethod supported_strategies()[source]

Supported strategies.

until(outcome: Outcome, user: User, dist: list[Value] | Value) Value[source]

Until.

Parameters:
  • outcome – Outcome to evaluate.

  • user – User.

  • dist – Dist.

Returns:

The result.

Return type:

Value

utility_estimate(outcome: Outcome) Value[source]

Gets a probability distribution of the Negotiator for this outcome without elicitation. Costs nothing

class negmas.elicitation.ElicitationRecord(cost: float, query: Query, answer_index: int, step: int | None = None)[source]

Bases: object

ElicitationRecord implementation.

answer_index: int[source]
cost: float[source]
query: Query[source]
step: int | None = None[source]
class negmas.elicitation.FastElicitor(*args, **kwargs)[source]

Bases: PandoraElicitor

Same as PandoraElicitor but does not use deep elicitation.

do_elicit(outcome: tuple, state: MechanismState)[source]

Do elicit.

Parameters:
  • outcome – Outcome to evaluate.

  • state – Current state.

update_best_offer_utility(outcome: tuple, u: Distribution | float)[source]

We need not do anything here as we will remove the outcome anyway to the known list

class negmas.elicitation.FullElicitor(strategy: EStrategy, user: User, epsilon=0.001, true_utility_on_zero_cost=False, base_negotiator: SAONegotiator = <negmas.gb.negotiators.timebased.AspirationNegotiator object>, **kwargs)[source]

Bases: BasePandoraElicitor

Does full deep elicitation in the first call to elicit.

elicit(state: MechanismState)[source]

Elicit.

Parameters:

state – Current state.

init_elicitation(preferences: IPUtilityFunction | Distribution | None, **kwargs)[source]

Init elicitation.

Parameters:
  • preferences – Preferences.

  • **kwargs – Additional keyword arguments.

init_unknowns() list[tuple[float, int]][source]

Init unknowns.

Returns:

The result.

Return type:

list[tuple[float, int]]

update_best_offer_utility(outcome: tuple, u: Distribution | float)[source]

Update best offer utility.

Parameters:
  • outcome – Outcome to evaluate.

  • u

class negmas.elicitation.FullKnowledgeElicitor(user: ~negmas.elicitation.user.User, *, strategy: ~negmas.elicitation.strategy.EStrategy | None = None, base_negotiator: ~negmas.sao.negotiators.base.SAOPRNegotiator = <negmas.gb.negotiators.timebased.AspirationNegotiator object>, opponent_model_factory: None | ~typing.Callable[[~negmas.common.NegotiatorMechanismInterface], ~negmas.models.acceptance.DiscreteAcceptanceModel] = <function BaseElicitor.<lambda>>, expector_factory: ~negmas.elicitation.expectors.Expector | ~typing.Callable[[], ~negmas.elicitation.expectors.Expector] = <class 'negmas.elicitation.expectors.MeanExpector'>, single_elicitation_per_round=False, continue_eliciting_past_reserved_val=False, epsilon=0.001, true_utility_on_zero_cost=False)[source]

Bases: BaseElicitor

An elicitor that does not need to do any elicitation because it has full access to the user ufun.

can_elicit() bool[source]

Can elicit.

Returns:

The result.

Return type:

bool

elicit_single(state: MechanismState)[source]

Elicit single.

Parameters:

state – Current state.

init_elicitation(preferences: IPUtilityFunction | Distribution | None, **kwargs)[source]

Init elicitation.

Parameters:
  • preferences – Preferences.

  • **kwargs – Additional keyword arguments.

utility_on_rejection(outcome: tuple, state: MechanismState) Distribution | float[source]

Utility on rejection.

Parameters:
  • outcome – Outcome to evaluate.

  • state – Current state.

Returns:

The result.

Return type:

Value

class negmas.elicitation.MarginalNeutralConstraint(full_range: Sequence[tuple[float, float]] | tuple[float, float] = (0.0, 1.0), outcomes: list[tuple] = None)[source]

Bases: Constraint

Constraints that do not affect the marginals of any outcomes. These constraints may only affect the joint distribution.

marginal(outcome: tuple) ScipyDistribution[source]

Marginal.

Parameters:

outcome – Outcome to evaluate.

Returns:

The result.

Return type:

ScipyDistribution

marginals(outcomes: Iterable[tuple] = None) list[ScipyDistribution][source]

Marginals.

Parameters:

outcomes – Outcomes.

Returns:

The result.

Return type:

list[ScipyDistribution]

class negmas.elicitation.MeanElicitor(strategy: EStrategy, user: User, **kwargs)[source]

Bases: OptimalIncrementalElicitor

Same as OptimalIncrementalElicitor using MeanExpector for estimating utilities

negmas.elicitation.OQA[source]

alias of VOIElicitor

class negmas.elicitation.OptimalIncrementalElicitor(strategy: EStrategy, user: User, **kwargs)[source]

Bases: FastElicitor

Same as FastElicitor but uses incremental elicitation which simply means that it only updates the index for outcomes that are affected by changes in the opponent model.

class negmas.elicitation.OptimisticElicitor(strategy: EStrategy, user: User, **kwargs)[source]

Bases: OptimalIncrementalElicitor

Same as OptimalIncrementalElicitor using the maximum to estimate utilities.

class negmas.elicitation.PandoraElicitor(strategy: EStrategy, user: User, **kwargs)[source]

Bases: BasePandoraElicitor

Implements the original [Baarslag and Gerding]_’s Pandora’s box based elicitation algorithm (when used with the default parameters).

Parameters:
  • strategy – The elicitation strategy

  • user – The user to elicit

class negmas.elicitation.PessimisticElicitor(strategy: EStrategy, user: User, **kwargs)[source]

Bases: OptimalIncrementalElicitor

Same as OptimalIncrementalElicitor using the minimum to estimate utilities.

class negmas.elicitation.QResponse(answer: Answer | None, indx: int, cost: float)[source]

Bases: object

QResponse implementation.

answer: Answer | None[source]
cost: float[source]
indx: int[source]
class negmas.elicitation.Query(answers: list[Answer], probs: list[float], cost: float = 0.0, name: str = '')[source]

Bases: object

Query implementation.

answers: list[Answer][source]
cost: float = 0.0[source]
name: str = ''[source]
probs: list[float][source]
class negmas.elicitation.RandomElicitor(strategy: EStrategy, user: User, deep_elicitation=True, true_utility_on_zero_cost=False, base_negotiator: SAONegotiator = <negmas.gb.negotiators.timebased.AspirationNegotiator object>, opponent_model_factory: None | Callable[[NegotiatorMechanismInterface], DiscreteAcceptanceModel] = <function RandomElicitor.<lambda>>, single_elicitation_per_round=False, **kwargs)[source]

Bases: BasePandoraElicitor

Uses a random index instead of the optimal z-index used by the Pandora’s box solution.

init_unknowns() None[source]

Init unknowns.

update_best_offer_utility(outcome: tuple, u: Distribution | float)[source]

Update best offer utility.

Parameters:
  • outcome – Outcome to evaluate.

  • u

class negmas.elicitation.RangeConstraint(rng: tuple = (None, None), full_range: Sequence[tuple[float, float]] | tuple[float, float] = (0.0, 1.0), outcomes: list[tuple] = None, eps=1e-05)[source]

Bases: Constraint

Constraints the utility of each of the given outcomes to lie within the given range

is_satisfied(preferences: Preferences, outcomes: Iterable[tuple] | None = None) bool[source]

Check if satisfied.

Parameters:
  • preferences – Preferences.

  • outcomes – Outcomes.

Returns:

The result.

Return type:

bool

marginal(outcome: tuple) ScipyDistribution[source]

Marginal.

Parameters:

outcome – Outcome to evaluate.

Returns:

The result.

Return type:

ScipyDistribution

marginals(outcomes: Iterable[tuple] = None) list[ScipyDistribution][source]

Marginals.

Parameters:

outcomes – Outcomes.

Returns:

The result.

Return type:

list[ScipyDistribution]

class negmas.elicitation.RankConstraint(rankings: list[int], full_range: Sequence[tuple[float, float]] | tuple[float, float] = (0.0, 1.0), outcomes: list[tuple] = None)[source]

Bases: MarginalNeutralConstraint

Constraints the utilities of given outcomes to be in ascending order

is_satisfied(preferences: Preferences, outcomes: Iterable[tuple] | None = None) bool[source]

Check if satisfied.

Parameters:
  • preferences – Preferences.

  • outcomes – Outcomes.

Returns:

The result.

Return type:

bool

class negmas.elicitation.SAOElicitingMechanism(priors, true_utilities, elicitor_reserved_value, cost, opp_utility, opponent, n_steps, time_limit, base_agent, opponent_model, elicitation_strategy='pingpong', toughness=0.95, elicitor_type='balanced', history_file_name: str = None, screen_log: bool = False, dynamic_queries=True, each_outcome_once=False, rational_answer_probs=True, update_related_queries=True, resolution=0.1, cost_assuming_titration=False, name: str | None = None)[source]

Bases: SAOMechanism

SAOEliciting mechanism.

classmethod generate_config(cost, n_outcomes: int = None, rand_preferencess=True, conflict: float = None, conflict_delta: float = None, winwin=None, genius_folder: str = None, n_steps=None, time_limit=None, own_utility_uncertainty=0.5, own_uncertainty_variablility=0.0, own_reserved_value=0.0, own_base_agent='aspiration', opponent_model_uncertainty=0.5, opponent_model_adaptive=False, opponent_proposes=True, opponent_type='best_only', opponent_toughness=0.9, opponent_reserved_value=0.0) dict[str, Any][source]

Generate config.

Parameters:
  • cost – Cost.

  • n_outcomes – N outcomes.

  • rand_preferencess – Rand preferencess.

  • conflict – Conflict.

  • conflict_delta – Conflict delta.

  • winwin – Winwin.

  • genius_folder – Genius folder.

  • n_steps – N steps.

  • time_limit – Time limit.

  • own_utility_uncertainty – Own utility uncertainty.

  • own_uncertainty_variablility – Own uncertainty variablility.

  • own_reserved_value – Own reserved value.

  • own_base_agent – Own base agent.

  • opponent_model_uncertainty – Opponent model uncertainty.

  • opponent_model_adaptive – Opponent model adaptive.

  • opponent_proposes – Opponent proposes.

  • opponent_type – Opponent type.

  • opponent_toughness – Opponent toughness.

  • opponent_reserved_value – Opponent reserved value.

Returns:

The result.

Return type:

dict[str, Any]

logdebug(s) None[source]

logs debug-level information

Parameters:

s (str) – The string to log

logerror(s) None[source]

logs error-level information

Parameters:

s (str) – The string to log

loginfo(s: str) None[source]

logs nmi-level information

Parameters:

s (str) – The string to log

logwarning(s) None[source]

logs warning-level information

Parameters:

s (str) – The string to log

on_negotiation_end()[source]

On negotiation end.

on_negotiation_start()[source]

On negotiation start.

plot(visible_negotiators=(0, 1), consider_costs=False, show: bool = True)[source]

Plot.

Parameters:
  • visible_negotiators – Visible negotiators.

  • consider_costs – Consider costs.

  • show – Whether to display the figures immediately.

Returns:

A tuple of two plotly Figure objects (utility figure, outcome figure).

step() SAOState[source]

Step.

Returns:

The result.

Return type:

SAOState

class negmas.elicitation.User(cost: float = 0.0, nmi=None, *args, **kwargs)[source]

Bases: Rational

Abstract base class for all representations of users used for elicitation

Parameters:
  • preferences – The real utility function of the user (pass either ufun or preferences).

  • ufun – The real utility function of the user (pass either ufun or preferences).

  • cost – A cost to be added for every question asked to the user.

  • nmi – [Optional] The AgentMechanismInterface representing the negotiation session engaged in by this user using this ufun.

ask(q: Query | None) QResponse[source]

Query the user and get a response.

cost_of_asking(q: Query | None = None, answer_id: int = -1, estimate_answer_cost=True) float[source]

Returns the cost of asking the given Quers.

Parameters:
  • q – The query

  • answer_id – If >= 0, the answer expected. Used to add the specific cost of the answer if estimate_answer_cost is True

  • estimate_answer_cost – If True and answer_id >= 0, the specific cost of getting this answer is added.

elicited_queries() list[ElicitationRecord][source]

Returns a list of elicited queries.

For each elicited query, the following dataclass is returned: ElicitationRecord(query, cost, answer_index, step)

is_satisfied(constraint: Constraint, outcomes=list[tuple]) bool[source]

Checks if the given constraint is satisfied for the user utility function and the given outcomes.

Parameters:
  • constraint – The Constraint.

  • outcomes – A list of Outcome objects to be passed to the constraint along with the user’s ufun.

set(preferences: Preferences | None = None, cost: float = None)[source]

Sets the ufun and/or cost for this user <0:desc>

Parameters:
  • preferences – The ufun if given

  • cost – The cost if given

property ufun: UtilityFunction[source]

Gets a UtilityFunction representing the real utility_function of the user

class negmas.elicitation.VOIElicitor(strategy: EStrategy, user: User, *, dynamic_query_set=False, queries=None, adaptive_answer_probabilities=True, each_outcome_once=False, update_related_queries=True, **kwargs)[source]

Bases: BaseVOIElicitor

The Optimal Querying Agent (OQA) proposed by [Baarslag and Kaisers]_

eeu(policy: ndarray, eus: ndarray) float[source]

Expected Expected Negotiator for following the policy

init_optimal_policy() None[source]

Gets the optimal policy given Negotiator utility_priors

class negmas.elicitation.VOIFastElicitor(strategy: EStrategy, user: User, *, dynamic_query_set=False, queries=None, adaptive_answer_probabilities=True, each_outcome_once=False, update_related_queries=True, **kwargs)[source]

Bases: BaseVOIElicitor

FastVOI algorithm proposed by Mohammad and Nakadai [MN2018]

[MN2018]

Mohammad, Y., & Nakadai, S. (2018, October). FastVOI: Efficient utility elicitation during negotiations. In International Conference on Principles and Practice of Multi-Agent Systems (pp. 560-567). Springer. (https://link.springer.com/chapter/10.1007/978-3-030-03098-8_42)

init_optimal_policy() None[source]

Gets the optimal policy given Negotiator utility_priors

class negmas.elicitation.VOINoUncertaintyElicitor(strategy: EStrategy, user: User, *, dynamic_query_set=False, queries=None, adaptive_answer_probabilities=True, each_outcome_once=False, update_related_queries=True, **kwargs)[source]

Bases: BaseVOIElicitor

A dummy VOI Elicitation Agent. It simply assumes no uncertainty in own utility function

add_query(qeeu: tuple[float, int]) None[source]

Add query.

Parameters:

qeeu – Qeeu.

eeu(policy: ndarray, eup: ndarray) float[source]

Expected Expected Negotiator for following the policy

elicit_single(state: MechanismState)[source]

Elicit single.

Parameters:

state – Current state.

init_optimal_policy() None[source]

Gets the optimal policy given Negotiator utility_priors

init_query_eeus() None[source]

Init query eeus.

class negmas.elicitation.VOIOptimalElicitor(user: User, *, base_negotiator: SAONegotiator = <negmas.gb.negotiators.timebased.AspirationNegotiator object>, adaptive_answer_probabilities=True, expector_factory: Expector | Callable[[], Expector] = <class 'negmas.elicitation.expectors.MeanExpector'>, single_elicitation_per_round=False, continue_eliciting_past_reserved_val=False, epsilon=0.001, resolution=0.025, true_utility_on_zero_cost=False, each_outcome_once=False, update_related_queries=True, prune=True, opponent_model_factory: None | Callable[[NegotiatorMechanismInterface], DiscreteAcceptanceModel] = <function VOIOptimalElicitor.<lambda>>)[source]

Bases: BaseElicitor

Optimal VOI elicitor proposed by [Mohammad and Nakadai]_

This algorithm restricts the type of queries that can be asked but does not require the user to set the set of queries apriori and can use unconuntable sets of queries of the form: “Is u(o) > x?”

add_query(qeeu: tuple[float, int]) None[source]

Add query.

Parameters:

qeeu – Qeeu.

before_eliciting()[source]

Before eliciting.

best_offer(state: MechanismState) tuple[tuple | None, float][source]

Maximum Expected Utility at a given aspiration level (alpha)

Parameters:

state

can_elicit() bool[source]

Can elicit.

Returns:

The result.

Return type:

bool

elicit_single(state: MechanismState)[source]

Elicit single.

Parameters:

state – Current state.

init_elicitation(preferences: IPUtilityFunction | Distribution | None, queries: list[Query] | None = None) None[source]

Init elicitation.

Parameters:
  • preferences – Preferences.

  • queries – Queries.

init_optimal_policy() None[source]

Gets the optimal policy given Negotiator utility_priors

init_query_eeus() None[source]

Updates the heap eeu_query which has records of (-EEU, quesion)

on_opponent_model_updated(outcomes: list[tuple], old: list[float], new: list[float]) None[source]

On opponent model updated.

Parameters:
  • outcomes – Outcomes.

  • old – Old.

  • new – New.

update_optimal_policy(index: int, outcome: tuple, oldu: float, newu: float)[source]

Updates the optimal policy after a change happens to some utility

utility_on_rejection(outcome: tuple, state: MechanismState) Distribution | float[source]

Utility on rejection.

Parameters:
  • outcome – Outcome to evaluate.

  • state – Current state.

Returns:

The result.

Return type:

Value

negmas.elicitation.argmax(iterable: Iterable[Any])[source]

Returns the index of the maximum

negmas.elicitation.argmin(iterable)[source]

Returns the index of the minimum

negmas.elicitation.next_query(strategy: EStrategy, user: User, outcome: Outcome = None) list[tuple[Outcome, Query, float]][source]

Gets the possible outcomes for the next ask with its cost.

The following tuple is returned: (outcome, query, cost)

negmas.elicitation.possible_queries(nmi: NegotiatorMechanismInterface, strategy: EStrategy, user: User, outcome: Outcome = None) list[tuple[Outcome, list[ScipyDistribution], float]][source]

Gets all queries that could be asked for that outcome until an exact value of ufun is found.

For each ask, the following tuple is returned: (outcome, query, cost)

negmas.elicitation.weitzman_index_uniform(loc: float, scale: float, cost: float, time_discount: float = 1.0) float[source]

Implements Weitzman’s 1979 Bandora’s Box index calculation.

Parameters:
  • loc – Loc of the uniform distribution to update

  • scale – Scale of the uniform distribution to update

  • cost – cost of opening a box

  • time_discount – time discount. Assumed unity (no discounting) for negotiation.

Returns:

The index value of this distribution.