ecclesia
Version:
Framework for political and electoral simulations
91 lines (90 loc) • 2.59 kB
JavaScript
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