Class: Equalshares::Rules::CardinalMes
- Defined in:
- lib/equalshares/rules/cardinal_mes.rb
Overview
Method of Equal Shares for ballots carrying per-voter utilities (vote_type "scoring"/"cumulative", or "ordinal" via Borda), where each voter i has a per-project utility u_i(c). Faithful port of the core of pabutools' method_of_equal_shares with an additive satisfaction (the "poor/rich" affordability computation), for the pure rule (no completion).
The approval path (Rules::MethodOfEqualShares) is kept separate; this general path is used when instance.cardinal? is true.
Instance Method Summary collapse
Methods inherited from Base
Constructor Details
This class inherits a constructor from Equalshares::Rules::Base
Instance Method Details
#call ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/equalshares/rules/cardinal_mes.rb', line 14 def call unless instance.cardinal? raise ComputeError, "CardinalMes applies to instances with per-voter scores (scoring/cumulative/ordinal)" end start = now voter_ids = election.voter_ids project_ids = election.project_ids approvers = election.approvers cost = election.costs budget_limit = election.budget util = project_ids.to_h { |c| [c, election.utilities(c)] } n = voter_ids.length budget = {} voter_ids.each { |i| budget[i] = budget_limit / n } # endowment B/|N| remaining = project_ids.select { |c| cost[c].positive? && !approvers[c].empty? } winners = [] loop do argmin = argmin_by_affordability(remaining, approvers, budget, util, cost) break if argmin.empty? selected = Tie.resolve_one(project_ids, cost, approvers, params, argmin) charge(selected, approvers, budget, util, cost) winners << selected remaining.delete(selected) progress&.call((100 * winners.sum { |c| cost[c] } / budget_limit).floor) end result(winners, start) end |