UNPKG

ecclesia

Version:

Framework for political and electoral simulations

91 lines (90 loc) 2.59 kB
import { createRandomObj } from "../chunk-7OCVVPU4.js"; import { Scores } from "../chunk-W6BKA6NW.js"; // src/election/voting.ts import { min } from "@gouvernathor/python"; import { Counter } from "@gouvernathor/python/collections"; function toShuffledVote({ voting, ...rest }) { return (voters, candidates) => { const randomObj = createRandomObj(rest); const partees = randomObj.shuffled(candidates); return voting(voters, partees); }; } function singleVote({ disagree }) { return (voters, candidates) => { const scores = Counter.fromkeys(candidates, 0); for (const voter of voters) { scores.increment(min(candidates, (party) => disagree(voter, party))); } return scores; }; } function orderingVote({ disagree }) { return (voters, candidates) => { const order = []; for (const voter of voters) { order.push([...candidates].sort((a, b) => disagree(voter, a) - disagree(voter, b))); } return order; }; } function cardinalVote({ nGrades, disagree }) { return (voters, candidates) => { const scores = Scores.fromGrades(nGrades); for (const voter of voters) { for (const party of candidates) { const grade = Math.min( nGrades - 1, Math.floor(nGrades) * (1 - disagree(voter, party)) ); scores.get(party)[grade]++; } } return scores; }; } function balancedCardinalVote({ nGrades, disagree }) { return (voters, candidates) => { const scores = Scores.fromGrades(nGrades); for (const voter of voters) { const prefs = new Map(Array.from(candidates, (party) => [party, 1 - disagree(voter, party)])); const minPref = Math.min(...prefs.values()); let maxPref = Math.max(...prefs.values()); if (minPref !== maxPref) { maxPref -= minPref; } for (const party of candidates) { const grade = Math.min( nGrades - 1, Math.floor(nGrades * (prefs.get(party) - minPref) / maxPref) ); scores.get(party)[grade]++; } } return scores; }; } function approvalVote({ disagree }) { const cardinal = balancedCardinalVote({ nGrades: 2, disagree }); return (voters, candidates) => { const scores = cardinal(voters, candidates); const approvals = new Counter(); for (const [party, [_disapproval, approval]] of scores) { approvals.increment(party, approval); } return approvals; }; } export { approvalVote, balancedCardinalVote, cardinalVote, orderingVote, singleVote, toShuffledVote }; //# sourceMappingURL=voting.js.map