Analysis module#

Module containing all kinds of tools to analyse participatory budgeting elections and their outcomes.

Basic Properties#

avg_project_cost(instance: Instance) int | float | mpq[source]#

Returns the average cost of a project.

Parameters:

instance (Instance) – The instance.

Returns:

The average cost of a project.

Return type:

Numeric

funding_scarcity(instance: Instance) int | float | mpq[source]#

Returns the ratio of the total cost of the instance, divided by the budget limit. This measure is called the funding scarcity.

Parameters:

instance (Instance) – The instance.

Returns:

The funding scarcity of the instance.

Return type:

Numeric

median_project_cost(instance: Instance) int | float | mpq[source]#

Returns the median cost of a project.

Parameters:

instance (Instance) – The instance.

Returns:

The median cost of a project.

Return type:

Numeric

std_dev_project_cost(instance: Instance) int | float | mpq[source]#

Returns the standard deviation of the costs of the projects.

Parameters:

instance (Instance) – The instance.

Returns:

The standard deviation.

Return type:

Numeric

sum_project_cost(instance: Instance) int | float | mpq[source]#

Returns the total cost of all the projects in the instance.

Parameters:

instance (Instance) – The instance.

Returns:

The total cost.

Return type:

Numeric

avg_approval_score(instance: Instance, profile: AbstractApprovalProfile) int | float | mpq[source]#

Returns the average approval score of projects.

Parameters:
Returns:

The average approval score of projects.

Return type:

Numeric

avg_ballot_cost(instance: Instance, profile: AbstractProfile) int | float | mpq[source]#

Returns the average cost of the ballots in the profile.

Parameters:
Returns:

The average cost of the ballots in the profile.

Return type:

Numeric

avg_ballot_length(instance: Instance, profile: AbstractProfile) int | float | mpq[source]#

Returns the average length of the ballots in the profile.

Parameters:
Returns:

The average length of the ballots in the profile.

Return type:

Numeric

avg_total_score(instance: Instance, profile: AbstractCardinalProfile) int | float | mpq[source]#

Returns the average score assigned to a project by the voters.

Parameters:
Returns:

The average score assigned to a project.

Return type:

Numeric

median_approval_score(instance: Instance, profile: AbstractApprovalProfile) int | float | mpq[source]#

Returns the median approval score of projects.

Parameters:
Returns:

The median approval score of projects.

Return type:

Numeric

median_ballot_cost(instance: Instance, profile: AbstractProfile) int | float | mpq[source]#

Returns the median cost of the ballots in the profile.

Parameters:
Returns:

The median cost of the ballots in the profile.

Return type:

Numeric

median_ballot_length(instance: Instance, profile: AbstractProfile) int[source]#

Returns the median length of the ballots in the profile.

Parameters:
Returns:

The median length of the ballots in the profile.

Return type:

Numeric

median_total_score(instance: Instance, profile: AbstractCardinalProfile) int | float | mpq[source]#

Returns the median score assigned to a project by the voters.

Parameters:
Returns:

The median score assigned to a project.

Return type:

Numeric

voter_flow_matrix(instance: Instance, profile: AbstractCardinalProfile) dict[str, dict[str, int]][source]#

Returns the voter flow matrix. The voter flow matrix is a 2D dictionary where voter_flow[a][b] is the number of voters for ‘a’ who voted for ‘b’

Parameters:

instance (Instance) – The instance.

Returns:

The voter flow matrix.

Return type:

dict[str, dict[str, int]]

votes_count_by_project(profile: AbstractCardinalProfile) dict[str, int][source]#

Returns the number of votes for each project.

Parameters:

profile (AbstractCardinalProfile) – The profile.

Returns:

The number of votes for each project.

Return type:

dict[str, int]

Voters’ Satisfaction Properties#

avg_satisfaction(instance: Instance, profile: AbstractProfile, budget_allocation: Collection[Project], sat_class: type[SatisfactionMeasure]) int | float | mpq[source]#

Computes the average satisfaction for a given instance, profile and satisfaction measure.

Parameters:
Returns:

The average satisfaction of a voter for the budget allocation.

Return type:

Numeric

gini_coefficient_of_satisfaction(instance: Instance, profile: AbstractProfile, budget_allocation: Collection[Project], sat_class: type[SatisfactionMeasure], invert: bool = False) int | float | mpq[source]#

Computes the Gini coefficient of the satisfaction of the voters.

Parameters:
  • instance (Instance) – The instance.

  • profile (AbstractProfile) – The profile.

  • budget_allocation (Iterable[Project]) – Collection of projects.

  • sat_class (type[SatisfactionMeasure]) – The satisfaction measure used to do the comparison.

  • invert (bool, optional) – Set to True to return 1 minus the Gini coefficient. Defaults to False.

Returns:

The Gini coefficient of the satisfaction of the voters.

Return type:

Numeric

percent_non_empty_handed(instance: Instance, profile: AbstractProfile, budget_allocation: Collection[Project]) int | float | mpq[source]#

Computes the percentage of voter for which at least one project from the budget allocation also appears in their ballot.

It mostly makes sense for approval ballots, though any profile of ballots supporting the in operator can be used.

Parameters:
Returns:

The percentage of non-empty handed voters.

Return type:

Numeric

percent_positive_satisfaction(profile: AbstractProfile, budget_allocation: Collection[Project], sat_class: type[SatisfactionMeasure]) int | float | mpq[source]#

Computes the percentage of voter who enjoy a positive (thus non-zero) satisfaction.

Parameters:
Returns:

The percentage of non-empty handed voters.

Return type:

Numeric

satisfaction_histogram(instance: Instance, profile: AbstractProfile, budget_allocation: Collection[Project], sat_class: type[SatisfactionMeasure], max_satisfaction: int | float | mpq, num_bins: int = 21) list[int | float | mpq][source]#

Computes the data necessary to plot a histogram of the satisfaction of the voters. Each bin contains the percentage of voters whose satisfaction corresponds to the bin.

Parameters:
  • instance (Instance) – The instance.

  • profile (AbstractProfile) – The profile.

  • budget_allocation (Iterable[Project]) – Collection of projects.

  • sat_class (type[SatisfactionMeasure]) – The satisfaction measure used to do the comparison.

  • max_satisfaction (Numeric) – The normaliser for the satisfaction.

  • num_bins (int, optional) – The number of bins of the histogram. Defaults to 20.

Returns:

A list of values, one per bin of the histogram.

Return type:

list[Numeric]

Projects’ Categories Properties#

category_proportionality(instance: Instance, profile: AbstractApprovalProfile, budget_allocation: Collection[Project]) int | float | mpq[source]#

Computes the difference between the cost allocated per category, and that existing in the profile. More specifically, for each category (an error is raised if not category are specified) we compute the amount of money dedicated to projects from the category in the budget allocation; together with the amount of money allocated to the category in the ballots of the voters. For each category, the average between these two scores is raised to the power 2, the global average over all categories is then considered and we return the exponential of minus that value.

It mostly makes sense for approval ballots, though any profile of ballots supporting the in operator can be used.

Parameters:
  • instance (Instance) – The instance.

  • profile (AbstractProfile) – The profile.

  • budget_allocation (Iterable[Project]) – The selected collection of projects.

Returns:

The score for the category proportionality.

Return type:

Numeric

Justified Representation Axioms#

is_EJR_any_approval(instance: Instance, profile: AbstractApprovalProfile, sat_class: type[SatisfactionMeasure], budget_allocation: Collection[Project]) bool[source]#

Test if a budget allocation satisfies EJR up to any project for the given instance and the given profile of approval ballots.

is_EJR_any_cardinal(instance: Instance, profile: AbstractCardinalProfile, budget_allocation: Collection[Project]) bool[source]#

Test if a budget allocation satisfies EJR up to any project for the given instance and the given profile of cardinal ballots.

is_EJR_approval(instance: Instance, profile: AbstractApprovalProfile, sat_class: type[SatisfactionMeasure], budget_allocation: Collection[Project], up_to_func: Callable[[Iterable[int | float | mpq]], int | float | mpq] | None = None) bool[source]#

Test if a budget allocation satisfies EJR for the given instance and the given profile of approval ballots.

is_EJR_cardinal(instance: ~pabutools.election.instance.Instance, profile: ~pabutools.election.profile.cardinalprofile.AbstractCardinalProfile, budget_allocation: ~collections.abc.Collection[~pabutools.election.instance.Project], sat_class: type[~pabutools.election.satisfaction.satisfactionmeasure.SatisfactionMeasure] = <class 'pabutools.election.satisfaction.additivesatisfaction.Additive_Cardinal_Sat'>, up_to_func: ~collections.abc.Callable[[~collections.abc.Iterable[int | float | ~gmpy2.mpq]], int | float | ~gmpy2.mpq] | None = None) bool[source]#

Test if a budget allocation satisfies EJR for the given instance and the given profile of cardinal ballots.

is_EJR_one_approval(instance: Instance, profile: AbstractApprovalProfile, sat_class: type[SatisfactionMeasure], budget_allocation: Collection[Project]) bool[source]#

Test if a budget allocation satisfies EJR up to one project for the given instance and the given profile of approval ballots.

is_EJR_one_cardinal(instance: Instance, profile: AbstractCardinalProfile, budget_allocation: Collection[Project]) bool[source]#

Test if a budget allocation satisfies EJR up to one project for the given instance and the given profile of cardinal ballots.

is_PJR_any_approval(instance: Instance, profile: AbstractApprovalProfile, sat_class: type[SatisfactionMeasure], budget_allocation: Collection[Project]) bool[source]#

Test if a budget allocation satisfies PJR up to any project for the given instance and the given profile of approval ballots.

is_PJR_any_cardinal(instance: Instance, profile: AbstractCardinalProfile, budget_allocation: Iterable[Project]) bool[source]#

Test if a budget allocation satisfies PJR up to any project for the given instance and the given profile of cardinal ballots.

is_PJR_approval(instance: Instance, profile: AbstractApprovalProfile, sat_class: type[SatisfactionMeasure], budget_allocation: Collection[Project], up_to_func: Callable[[Iterable[int | float | mpq]], int | float | mpq] | None = None) bool[source]#

Test if a budget allocation satisfies PJR for the given instance and the given profile of approval ballots.

is_PJR_cardinal(instance: Instance, profile: AbstractCardinalProfile, budget_allocation: Iterable[Project], up_to_func: Callable[[Iterable[int | float | mpq]], int | float | mpq] | None = None) bool[source]#

Test if a budget allocation satisfies PJR for the given instance and the given profile of cardinal ballots.

is_PJR_one_approval(instance: Instance, profile: AbstractApprovalProfile, sat_class: type[SatisfactionMeasure], budget_allocation: Collection[Project]) bool[source]#

Test if a budget allocation satisfies PJR up to one project for the given instance and the given profile of approval ballots.

is_PJR_one_cardinal(instance: Instance, profile: AbstractCardinalProfile, budget_allocation: Iterable[Project]) bool[source]#

Test if a budget allocation satisfies PJR up to one project for the given instance and the given profile of cardinal ballots.

is_in_core(instance: Instance, profile: AbstractProfile, sat_class: type[SatisfactionMeasure], budget_allocation: Collection[Project], up_to_func: Callable[[Iterable[int | float | mpq]], int | float | mpq] | None = None) bool[source]#

Test if a given budget allocation is in the core of the instance.

is_strong_EJR_approval(instance: Instance, profile: AbstractApprovalProfile, sat_class: type[SatisfactionMeasure], budget_allocation: Collection[Project]) bool[source]#

Test if a budget allocation satisfies strong EJR for the given instance and the given profile of approval ballots.

is_strong_EJR_cardinal(instance: ~pabutools.election.instance.Instance, profile: ~pabutools.election.profile.cardinalprofile.AbstractCardinalProfile, budget_allocation: ~collections.abc.Collection[~pabutools.election.instance.Project], sat_class: type[~pabutools.election.satisfaction.satisfactionmeasure.SatisfactionMeasure] = <class 'pabutools.election.satisfaction.additivesatisfaction.Additive_Cardinal_Sat'>) bool[source]#

Test if a budget allocation satisfies strong EJR for the given instance and the given profile of cardinal ballots.

Properties Specific to the Method of Equal Shares#

class ProjectLoss(project: Project, supporters_budget: int | float | mpq, budget_lost: dict[Project, int | float | mpq])[source]#

Class used to represent the projects and how much budget they lost due to other projects being picked. This extends the Project and thus represents the project itself.

Parameters:
  • project (Project) – Project for which analytics is calculated.

  • supporters_budget (Numeric) – The collective budget of the project supporters when project was considered by a rule.

  • budget_lost (dict[Project, Numeric]) – Describes the amount of budget project supporters spent on other projects prior to this projects’ consideration.

supporters_budget#

The collective budget of the project supporters when project was considered by rule.

Type:

Numeric

budget_lost#

Describes the amount of budget project supporters spent on other projects prior to this projects’ consideration.

Type:

dict[Project, Numeric]

total_budget_lost() int | float | mpq[source]#

Returns the total budget spent by project supporters on prior projects.

Returns:

The total budget spent.

Return type:

Numeric

calculate_effective_support(instance: Instance, profile: Profile, project: Project, was_picked: bool, mes_params: dict | None = None) int[source]#

Calculates the effective support of a given project in a given instance, profile and mes election. Effective support for a project is an analytical metric which allows to measure the ratio of initial budget received to minimal budget required to win. Effective support is represented in percentages.

Parameters:
  • instance (Instance) – The instance.

  • profile (AbstractProfile) – The profile.

  • project (Project) – Project for which effective support is calculated. Must be a part of the instance.

  • was_picked (bool) – Whether the considerd project was picked as a winner in the allocation.

  • mes_params (dict, optional) – Dictionary of additional parameters that are passed as keyword arguments to the MES rule. Defaults to {}.

Returns:

The effective support value in percentages for project.

Return type:

int

calculate_effective_supports(instance: Instance, profile: Profile, allocation: BudgetAllocation, mes_params: dict | None = None, final_budget: int | float | mpq | None = None) dict[Project, int][source]#

Returns a dictionary of project and their effective support in a given instance, profile and mes election. Effective support for a project is an analytical metric which allows to measure the ratio of initial budget received to minimal budget required to win. Effective support is represented in percentages.

Parameters:
  • instance (Instance) – The instance.

  • profile (AbstractProfile) – The profile.

  • allocation (BudgetAllocation) – Resulting allocation of the above instance & profile.

  • mes_params (dict, optional) – Dictionary of additional parameters that are passed as keyword arguments to the MES rule. Defaults to None.

  • final_budget (Numeric, optional) – Numeric value of the final budget which will replace the instance budget. Allows for simulating exhaustive MES.

Returns:

Dictionary of pairs (Project, effective support).

Return type:

dict[Project, int]

calculate_project_loss(allocation_details: AllocationDetails, verbose: bool = False) list[ProjectLoss][source]#

Returns a list of ProjectLoss objects for the projects.

Parameters:
  • allocation_details (AllocationDetails) – The details of the budget allocation considered.

  • verbose (bool, optional) – (De)Activate the display of additional information. Defaults to False.

Returns:

List of ProjectLoss objects.

Return type:

list[ProjectLoss]