ProfileHistogram

class poisson_approval.ProfileHistogram(d_ranking_share, d_ranking_histogram=None, d_weak_order_share=None, normalization_warning=True, ratio_sincere=0, ratio_fanatic=0, voting_rule='Approval', symbolic=False)[source]

A profile of preference with histogram distributions of utility.

Parameters:
  • d_ranking_share (dict) – E.g. {'abc': 0.4, 'cab': 0.6}. d_ranking_share['abc'] is the probability that a voter prefers candidate a, then candidate b, then candidate c.
  • d_ranking_histogram (dict) –

    Each key is a ranking, e.g. 'abc'. Each value is a list that represents a piecewise constant probability density function (PDF) of having a utility u for the middle candidate, e.g. b. By convention, the list sums to 1 (contrary to the usual convention where the integral of the function would sum to 1).

    For example, if the list is [0.4, 0.3, 0.2, 0.1], it means that a fraction 0.4 of voters 'abc' have a utility for b that is in the first quarter, i.e. between 0 and 0.25. These voters are uniformly distributed in this segment.

  • d_weak_order_share (dict) – E.g. {'a~b>c': 0.2, 'a>b~c': 0.1}. d_weak_order_share['a~b>c'] is the probability that a voter likes candidates a and b equally and prefer them to candidate c.
  • normalization_warning (bool) – Whether a warning should be issued if the input distribution is not normalized.
  • ratio_sincere (Number) – The ratio of sincere voters, in the interval [0, 1]. This is used for tau().
  • ratio_fanatic (Number) – The ratio of fanatic voters, in the interval [0, 1]. This is used for tau(). The sum of ratio_sincere and ratio_fanatic must not exceed 1.
  • voting_rule (str) – The voting rule. Possible values are APPROVAL, PLURALITY and ANTI_PLURALITY.
  • symbolic (bool) – Whether the computations are symbolic or numeric.

Notes

If the input distribution is not normalized, the profile will be normalized anyway and a warning is issued (unless normalization_warning is False).

Examples

>>> from fractions import Fraction
>>> profile = ProfileHistogram(
...     {'abc': Fraction(1, 10), 'bac': Fraction(6, 10), 'cab': Fraction(3, 10)},
...     {'abc': [1], 'bac': [1, 0], 'cab': [Fraction(2, 3), 0, 0, 0, 0, 0, 0, 0, 0, Fraction(1, 3)]})
>>> profile  # doctest: +NORMALIZE_WHITESPACE
ProfileHistogram({'abc': Fraction(1, 10), 'bac': Fraction(3, 5), 'cab': Fraction(3, 10)}, {'abc': array([1]), 'bac': array([1, 0]), 'cab': array([Fraction(2, 3), 0, 0, 0, 0, 0, 0, 0, 0, Fraction(1, 3)],
    dtype=object)})
>>> print(profile)
<abc: 1/10 [1], bac: 3/5 [1 0], cab: 3/10 [Fraction(2, 3) 0 0 0 0 0 0 0 0 Fraction(1, 3)]> (Condorcet winner: b)
>>> profile.abc
Fraction(1, 10)
>>> profile.d_ranking_share['abc']  # Alternate syntax for profile.abc
Fraction(1, 10)
>>> profile.weighted_maj_graph
array([[0, Fraction(-1, 5), Fraction(2, 5)],
       [Fraction(1, 5), 0, Fraction(2, 5)],
       [Fraction(-2, 5), Fraction(-2, 5), 0]], dtype=object)
>>> profile.condorcet_winners
Winners({'b'})
>>> profile.is_profile_condorcet
1.0
>>> profile.has_majority_favorite  # Is one candidate 'top' in a majority of ballots?
True
>>> profile.has_majority_ranking  # Does one ranking represent a majority of ballots?
True
>>> profile.is_single_peaked  # Is the profile single-peaked?
True
>>> profile.support_in_rankings
{'abc', 'bac', 'cab'}
>>> profile.is_generic_in_rankings  # Are all rankings there?
False
>>> strategy = StrategyThreshold({'abc': 0, 'bac': 1, 'cab': Fraction(1, 2)}, profile=profile)
>>> print(profile.tau_sincere)
<a: 1/20, ab: 1/20, ac: 1/10, b: 3/5, c: 1/5> ==> b
>>> print(profile.tau_fanatic)
<a: 1/10, b: 3/5, c: 3/10> ==> b
>>> print(profile.tau_strategic(strategy))
<ab: 1/10, ac: 1/10, b: 3/5, c: 1/5> ==> b
>>> print(profile.tau(strategy))
<ab: 1/10, ac: 1/10, b: 3/5, c: 1/5> ==> b
>>> profile.is_equilibrium(strategy)
EquilibriumStatus.EQUILIBRIUM
>>> profile.analyzed_strategies_group
Equilibria:
<abc: ab, bac: b, cab: utility-dependent (1/2)> ==> b (FF)
<abc: a, bac: ab, cab: c> ==> a (D)
<abc: a, bac: b, cab: ac> ==> b (FF)
<BLANKLINE>
Non-equilibria:
<abc: ab, bac: ab, cab: ac> ==> a (D)
<abc: ab, bac: ab, cab: utility-dependent (1/2)> ==> a (D)
<abc: ab, bac: ab, cab: c> ==> a, b (FF)
<abc: ab, bac: b, cab: ac> ==> b (FF)
<abc: ab, bac: b, cab: c> ==> b (FF)
<abc: a, bac: ab, cab: ac> ==> a (D)
<abc: a, bac: ab, cab: utility-dependent (1/2)> ==> a (D)
<abc: a, bac: b, cab: utility-dependent (1/2)> ==> b (FF)
<abc: a, bac: b, cab: c> ==> b (FF)
>>> strategy_ini = StrategyThreshold({'abc': .5, 'bac': .5, 'cab': .5})
>>> cycle = profile.iterated_voting(strategy_ini, 100)['cycle_strategies']
>>> len(cycle)
1
>>> print(cycle[0])
<abc: ab, bac: utility-dependent (0.7199316142046179), cab: utility-dependent (0.28006838579538196)> ==> b
>>> limit_strategy = profile.fictitious_play(strategy_ini, 100, perception_update_ratio=1)['strategy']
>>> print(limit_strategy)
<abc: ab, bac: utility-dependent (0.7199316142046179), cab: utility-dependent (0.28006838579538196)> ==> b

The profile can include weak orders:

>>> profile = ProfileHistogram(
...     {'abc': Fraction(1, 10), 'bac': Fraction(6, 10)},
...     {'abc': [1], 'bac': [1, 0]},
...     d_weak_order_share={'c~a>b': Fraction(3, 10)})
>>> profile
ProfileHistogram({'abc': Fraction(1, 10), 'bac': Fraction(3, 5)}, {'abc': array([1]), 'bac': array([1, 0])}, d_weak_order_share={'a~c>b': Fraction(3, 10)})
>>> print(profile)
<abc: 1/10 [1], bac: 3/5 [1 0], a~c>b: 3/10> (Condorcet winner: b)

An alternate syntax to define a profile:

>>> profile = ProfileHistogram({
...     ('abc', (1, )): Fraction(1, 10), ('bac', (1, 0)): Fraction(6, 10),
...     ('cab', (Fraction(2, 3), 0, 0, 0, 0, 0, 0, 0, 0, Fraction(1, 3))): Fraction(2, 10),
...     'a~b>c': Fraction(1, 10)
... })
>>> print(profile)
<abc: 1/10 [1], bac: 3/5 [1 0], cab: 1/5 [Fraction(2, 3) 0 0 0 0 0 0 0 0 Fraction(1, 3)], a~b>c: 1/10> (Condorcet winner: b)
abc

Share of voters with this ranking.

Type:Number
acb

Share of voters with this ranking.

Type:Number
analyzed_strategies(strategies)

Analyze a list of strategies for the profile.

Parameters:strategies (iterable) – An iterator of strategies, such as a list of strategies.
Returns:The analyzed strategies of the profile.
Return type:AnalyzedStrategies

Examples

Cf. ProfileOrdinal.analyzed_strategies_ordinal().

analyzed_strategies_group

Analyzed group strategies.

Cf. analyzed_strategies() and strategies_group. This is implemented only for profiles where we consider that there is a natural notion of group, such as ProfileNoisyDiscrete.

Type:AnalyzedStrategies
analyzed_strategies_ordinal

Analyzed ordinal strategies.

Cf. analyzed_strategies() and strategies_ordinal.

Type:AnalyzedStrategies
analyzed_strategies_pure

Analyzed pure strategies.

Cf. analyzed_strategies() and strategies_pure. This is implemented only for discrete profiles such as ProfileTwelve or ProfileDiscrete.

Type:AnalyzedStrategies
bac

Share of voters with this ranking.

Type:Number
bca

Share of voters with this ranking.

Type:Number
best_responses_to_strategy(d_ranking_best_response)

Convert best responses to a StrategyThreshold.

Parameters:d_ranking_best_response (dict) – Key: ranking. Value: BestResponse.
Returns:The conversion of the best responses into a strategy. Only the rankings present in this profile are mentioned in the strategy.
Return type:StrategyThreshold
cab

Share of voters with this ranking.

Type:Number
cba

Share of voters with this ranking.

Type:Number
condorcet_winners

Condorcet winner(s).

Type:Winners
contains_rankings

Whether the profile contains some rankings.

Type:bool
contains_weak_orders

Whether the profile contains some weak orders.

Type:bool
d_ballot_share_weak_voters_fanatic

Ballot shares due to the weak orders if they vote fanatically

Voters of the type 'a>b~c':

  • In Approval or Plurality, they vote for a.
  • In Anti-plurality, half of them vote for ab (i.e. against c) and half of them vote for ac (i.e. against b).

Voters of the type 'a~b>c':

  • In Approval or Plurality, half of them vote for a and half of them vote for b.
  • In Anti-plurality, they vote for ab (i.e. against c).
Type:dict
d_ballot_share_weak_voters_sincere

Ballot shares due to the weak orders if they vote sincerely

Voters of the type 'a>b~c':

  • In Approval or Plurality, they vote for a.
  • In Anti-plurality, half of them vote for ab (i.e. against c) and half of them vote for ac (i.e. against b).

Voters of the type 'a~b>c':

  • In Approval or Anti-plurality, they vote for ab (i.e. against c).
  • In Plurality, half of them vote for a and half of them vote for b.
Type:dict
fictitious_play(init, n_max_episodes, perception_update_ratio=<function one_over_t>, ballot_update_ratio=1, winning_frequency_update_ratio=<function one_over_t>, verbose=False)

Seek for convergence by fictitious play.

Parameters:
  • init (Strategy or TauVector or str) –

    The initialization.

    • If it is a strategy, it must be an argument accepted by tau(), i.e. by tau_strategic().
    • If it is a tau-vector, it is used directly.
    • If it is a string:
  • n_max_episodes (int) – Maximal number of iterations.
  • perception_update_ratio (callable or Number) – The coefficient when updating the perceived tau: tau_perceived = (1 - perception_update_ratio(t)) * tau_perceived + perception_update_ratio(t) * tau_actual. For any t from 1 to n_max_episodes included, the update ratio must be in [0, 1]. The default function is one_over_t(), which leads to an arithmetic average. However, the recommended function is one_over_log_t_plus_one(), which accelerates the convergence. If perception_update_ratio is a Number, it is considered as a constant function.
  • ballot_update_ratio (callable or Number) – The ratio of voters who update their ballot: tau_actual = (1 - ballot_update_ratio(t)) * tau_actual + ballot_update_ratio(t) * tau_response. For any t from 1 to n_max_episodes included, the update ratio must be in [0, 1]. The default function is the constant 1, which corresponds to a full update. If ballot_update_ratio is a Number, it is considered as a constant function.
  • winning_frequency_update_ratio (callable or Number) – The coefficient when updating the winning frequency of each candidate: d_candidate_winning_frequency[c] = (1 - winning_frequency_update_ratio(t)) * d_candidate_winning_frequency[c] + winning_frequency_update_ratio(t) * winning_probability[c]. The default function is one_over_t(), which leads to an arithmetic average. Note that this parameters has an influence only in case of non-convergence.
  • verbose (bool) – If True, print all intermediate steps.
Returns:

  • Key tau: TauVector or None. The limit tau-vector. If None, it means that the process did not converge.
  • Key strategy: StrategyThreshold or None. The limit strategy. If None, it means that the process did not converge.
  • Key n_episodes: the number of episodes until convergence. If the process did not converge, by convention, this value is n_max_episodes.
  • Key d_candidate_winning_frequency: dict. Key: candidate. Value: winning frequency. If the process reached a limit, the winning frequencies are computed in the limit only. If the process did not converge, the frequency is computed on the whole history.

Return type:

dict

Notes

Comparison between iterated_voting() and fictitious_play():

In general, you should use iterated_voting() only if you care about cycles, with the constraint that it implies having constant update ratios.

has_majority_favorite

Whether there is a majority favorite (a candidate ranked first by strictly more than half of the voters).

Type:bool
has_majority_ranking

Whether there is a majority ranking (a ranking shared by strictly more than half of the voters).

Type:bool
have_ranking_with_utility_above_u(ranking, u)[source]

Share of voters who have a given ranking and strictly above a given utility for their middle candidate.

Cf. ProfileCardinal.have_ranking_with_utility_above_u().

Examples

>>> from fractions import Fraction
>>> profile = ProfileHistogram(
...     {'abc': Fraction(1, 10), 'bac': Fraction(6, 10), 'cab': Fraction(3, 10)},
...     {'abc': [1], 'bac': [1, 0], 'cab': [Fraction(2, 3), 0, 0, 0, 0, 0, 0, 0, 0, Fraction(1, 3)]})
>>> profile.have_ranking_with_utility_above_u(ranking='cab', u=0)
Fraction(3, 10)
>>> profile.have_ranking_with_utility_above_u(ranking='cab', u=Fraction(1, 100))
Fraction(7, 25)
>>> profile.have_ranking_with_utility_above_u(ranking='cab', u=Fraction(99, 100))
Fraction(1, 100)
>>> profile.have_ranking_with_utility_above_u(ranking='cab', u=1)
0
have_ranking_with_utility_below_u(ranking, u)[source]

Share of voters who have a given ranking and strictly below a given utility for their middle candidate.

Cf. ProfileCardinal.have_ranking_with_utility_below_u().

Examples

>>> from fractions import Fraction
>>> profile = ProfileHistogram(
...     {'abc': Fraction(1, 10), 'bac': Fraction(6, 10), 'cab': Fraction(3, 10)},
...     {'abc': [1], 'bac': [1, 0], 'cab': [Fraction(2, 3), 0, 0, 0, 0, 0, 0, 0, 0, Fraction(1, 3)]})
>>> profile.have_ranking_with_utility_below_u(ranking='cab', u=0)
0
>>> profile.have_ranking_with_utility_below_u(ranking='cab', u=Fraction(1, 100))
Fraction(1, 50)
>>> profile.have_ranking_with_utility_below_u(ranking='cab', u=Fraction(99, 100))
Fraction(29, 100)
>>> profile.have_ranking_with_utility_below_u(ranking='cab', u=1)
Fraction(3, 10)
have_ranking_with_utility_u(ranking, u)

Share of voters who have a given ranking and a given utility for their middle candidate.

Since it is a continuous profile, this method always returns 0.

is_equilibrium(strategy)

Whether a strategy is an equilibrium.

Parameters:strategy (StrategyThreshold) – A strategy that specifies at least all the rankings that are present in the profile. If some voters have a utility for their second candidate that is equal to the threshold utility of the strategy, then the ratio of optimistic voters must be specified.
Returns:Whether strategy is an equilibrium in this profile. This is based on the assumption that:
  • A proportion ratio_sincere of voters cast their ballot sincerely (in the sense of tau_sincere),
  • A proportion ratio_fanatic of voters vote for their top candidate only,
  • And the rest of the voters use strategy.
Return type:EquilibriumStatus
is_generic_in_rankings

Whether the profile is generic in rankings (contains all rankings).

Type:bool
is_profile_condorcet

Whether the profile is Condorcet. 1. means there is a strict Condorcet winner, 0.5 means there are one or more weak Condorcet winner(s), 0. means there is no Condorcet winner.

Type:float
is_single_peaked

Whether the profile is single-peaked.

Type:bool
is_standardized

Whether the profile is standardized. Cf. standardized_version().

Type:bool
iterated_voting(init, n_max_episodes, perception_update_ratio=1, ballot_update_ratio=1, winning_frequency_update_ratio=<function one_over_t>, verbose=False)

Seek for convergence by iterated voting.

Parameters:
  • init (Strategy or TauVector or str) –

    The initialization.

    • If it is a strategy, it must be an argument accepted by tau(), i.e. by tau_strategic().
    • If it is a tau-vector, it is used directly.
    • If it is a string:
  • n_max_episodes (int) – Maximal number of iterations.
  • perception_update_ratio (Number in [0, 1]) – The coefficient when updating the perceived tau: tau_perceived = (1 - perception_update_ratio) * tau_perceived + perception_update_ratio * tau_actual.
  • ballot_update_ratio (Number in [0, 1]) – The ratio of voters who update their ballot: tau_actual = (1 - ballot_update_ratio) * tau_actual + ballot_update_ratio * tau_response.
  • winning_frequency_update_ratio (callable or Number) – The coefficient when updating the winning frequency of each candidate: d_candidate_winning_frequency[c] = (1 - winning_frequency_update_ratio(t)) * d_candidate_winning_frequency[c] + winning_frequency_update_ratio(t) * winning_probability[c]. The default function is one_over_t(), which leads to an arithmetic average. Note that this parameters has an influence only in case of non-convergence.
  • verbose (bool) – If True, print all intermediate steps.
Returns:

  • Key cycle_taus_perceived: list of TauVector. The limit cycle of perceived tau-vectors. cycle_taus_perceived[t] is a barycenter of cycle_taus_perceived[t - 1] with cycle_taus_actual[t - 1], parametrized by perception_update_ratio.
  • Key cycle_strategies: list of StrategyThreshold. The limit cycle of strategies. cycle_strategies[t] is the best response to cycle_taus_perceived[t].
  • Key cycle_taus_actual: list of TauVector. The limit cycle of actual tau-vectors. cycle_taus_actual[t] is a barycenter of cycle_taus_actual[t - 1] and the tau-vector resulting from strategies[t], parametrized by ballot_update_ratio.
  • Key n_episodes: the number of episodes until convergence. If the process did not converge, by convention, this value is n_max_episodes.
  • Key d_candidate_winning_frequency: dict. Key: candidate. Value: winning frequency. If the process reached a limit or a periodical orbit, the winning frequencies are computed in the limit only. If the process did not converge, the frequency is computed on the whole history.

cycle_taus_perceived, cycle_strategies and cycle_taus_actual have the same length. If it is 1, the process converges to this limit. If it is greater than 1, the process reaches a periodical orbit. If it is 0, by convention, it means that the process does not converge and does not reach a periodical orbit.

Return type:

dict

Notes

Comparison between iterated_voting() and fictitious_play():

In general, you should use iterated_voting() only if you care about cycles, with the constraint that it implies having constant update ratios.

classmethod order_and_label(t)[source]

Order and label of a discrete type.

Cf. Profile.order_and_label().

Examples

>>> ProfileHistogram.order_and_label(('abc', (0.1, 0.5, 0.4)))
('abc', '$r(abc)$')
>>> ProfileHistogram.order_and_label('a~b>c')
('a~b>c', '$r(a\\sim b>c)$')
classmethod order_and_label_weak(t)

Auxiliary function for order_and_label(), specialized for weak orders.

Parameters:t (object) – A weak order of the form 'a>b~c' or 'a~b>c'.
Returns:
  • order (str) – The weak order itself.
  • label (str) – The label to be used for the corner of the triangle.

Examples

>>> Profile.order_and_label_weak('a~b>c')
('a~b>c', '$r(a\\sim b>c)$')
plot_cdf(ranking, x_label=None, y_label=None, **kwargs)[source]

Plot the cumulative distribution function (CDF) for a given ranking.

Parameters:
  • ranking (str) – A ranking.
  • x_label (str, optional) – The label for x-axis. If not specified, an appropriate label is provided.
  • y_label – The label for y-axis. If not specified, an appropriate label is provided.
  • kwargs – The additional keyword arguments are passed to pyplot.plot().

Examples

>>> from fractions import Fraction
>>> profile = ProfileHistogram(
...     {'abc': Fraction(1, 10), 'bac': Fraction(6, 10), 'cab': Fraction(3, 10)},
...     {'abc': [1], 'bac': [1, 0], 'cab': [Fraction(2, 3), 0, 0, 0, 0, 0, 0, 0, 0, Fraction(1, 3)]})
>>> profile.plot_cdf('cab')
plot_histogram(ranking, x_label=None, y_label=None, **kwargs)[source]

Plot the histogram for a given ranking.

Up to a renormalization, it is the probability density function (PDF).

Parameters:
  • ranking (str) – A ranking.
  • x_label (str, optional) – The label for x-axis. If not specified, an appropriate label is provided.
  • y_label – The label for y-axis. If not specified, an appropriate label is provided.
  • kwargs – The additional keyword arguments are passed to pyplot.plot().

Examples

>>> from fractions import Fraction
>>> profile = ProfileHistogram(
...     {'abc': Fraction(1, 10), 'bac': Fraction(6, 10), 'cab': Fraction(3, 10)},
...     {'abc': [1], 'bac': [1, 0], 'cab': [Fraction(2, 3), 0, 0, 0, 0, 0, 0, 0, 0, Fraction(1, 3)]})
>>> profile.plot_histogram('cab')
random_tau_undominated()

Random tau based on undominated ballots.

This is used, for example, in ProfileCardinal.iterated_voting().

Returns:A random tau-vector. Independently for each ranking, a proportion uniformly drawn in [0, 1] of voters use one undominated ballot, and the rest use the other undominated ballot. For example, in Approval voting, voters with ranking abc are randomly split between ballots a and ab.
Return type:TauVector
standardized_version

Standardized version of the profile (makes it unique, up to permutations of the candidates).

Examples

>>> from fractions import Fraction
>>> profile = ProfileHistogram(
...     {'abc': Fraction(1, 10), 'bac': Fraction(6, 10), 'cab': Fraction(3, 10)},
...     {'abc': [1], 'bac': [1, 0], 'cab': [Fraction(2, 3), 0, 0, 0, 0, 0, 0, 0, 0, Fraction(1, 3)]})
>>> print(profile.standardized_version)
<abc: 3/5 [1 0], bac: 1/10 [1], cba: 3/10 [Fraction(2, 3) 0 0 0 0 0 0 0 0 Fraction(1, 3)]> (Condorcet winner: a)
>>> profile.is_standardized
False
Type:ProfileHistogram
strategies_group

group strategies of the profile.

Yields:StrategyThreshold – All possible group strategies of the profile. Each bin of each histogram is considered as a “group” of voters. In other words, the considered strategies are all the threshold strategies where for each ranking, the corresponding threshold is at a limit between two bins of the histogram.
Type:Iterator
strategies_ordinal

ordinal strategies of the profile.

Yields:StrategyOrdinal – All possible ordinal strategies for this profile.

Examples

Cf. ProfileOrdinal.

Type:Iterator
strategies_pure

pure strategies of the profile.

Yields:Strategy – All possible pure strategies of the profile. This is implemented only for discrete profiles such as ProfileTwelve or ProfileDiscrete.

Examples

Cf. ProfileDiscrete.

Type:Iterator
support_in_rankings

Support of the profile (in terms of rankings).

Type:SetPrintingInOrder of str
support_in_weak_orders

Support of the profile (in terms of weak orders).

Type:SetPrintingInOrder of str
tau(strategy)

Tau-vector associated to a strategy, with partial sincere and fanatic voting.

Parameters:strategy (an argument accepted by tau_strategic()) –
Returns:A share ratio_sincere of the voters vote sincerely (in the sense of tau_sincere), a share ratio_fanatic vote only for their top candidate, and the rest of the voters vote strategically (in the sense of tau_strategic()). In other words, this tau-vector is the barycenter of tau_sincere, tau_fanatic and tau_strategic(strategy), with respective weights self.ratio_sincere, self.ratio_fanatic and 1 - self.ratio_sincere - self.ratio_fanatic.
Return type:TauVector
tau_fanatic

Tau-vector associated to fanatic voting.

Returns:
  • In Approval or Plurality, all voters approve of their top candidate only.,
  • In Anti-plurality, all voters vote against their bottom candidate (i.e. for the other two).
Return type:TauVector

Notes

In Plurality and Anti-plurality, sincere and fanatic voting are the same. They differ only in Approval.

tau_sincere

Tau-vector associated to sincere voting.

Returns:
  • In Approval, all voters approve of their top candidate, and voters approve of their middle candidate if and only if their utility for her is strictly greater than 0.5.
  • In Plurality, all voters vote for their top candidate.
  • In Anti-plurality, all voters vote against their bottom candidate (i.e. for the other two).
Return type:TauVector

Notes

In Plurality and Anti-plurality, sincere and fanatic voting are the same. They differ only in Approval.

tau_strategic(strategy)

Tau-vector associated to a strategy (fully strategic voting).

Parameters:strategy (StrategyThreshold) – A strategy that specifies at least all the rankings that are present in the profile. If some voters have a utility for their second candidate that is equal to the threshold utility of the strategy, then the ratio of optimistic voters must be specified.
Returns:Tau-vector associated to this profile and strategy strategy.
Return type:TauVector
weighted_maj_graph

Weighted majority graph.

Type:np.ndarray
τ(strategy)

Tau-vector (alternate notation).

Parameters:strategy (Strategy) – A strategy that specifies at least all the rankings that are present in the profile.
Returns:Tau-vector associated to this profile and strategy strategy.
Return type:TauVector