docs: review, document and take a break

pull/9/head
Dominique Merle 3 years ago
parent f40e301d58
commit d9da3b2ec8

@ -3,16 +3,18 @@ package fr.mieuxvoter.mj;
/** /**
* A Deliberator takes in a poll's Tally, * A Deliberator takes in a poll's Tally,
* that is the amount of judgments of each grade received by each Proposal, * which holds the amount of judgments of each grade received by each Proposal,
* and outputs that poll's Result, * and outputs that poll's Result, that is the final rank of each Proposal.
* that is the final rank of each Proposal. *
* Ranks start at 1 ("best"), and increment towards "worst". * Ranks start at 1 ("best"), and increment towards "worst".
* Two proposal may share the same rank, in extreme equality cases. * Two proposal may share the same rank, in extreme equality cases.
* *
* This is the main API of this library. * This is the main API of this library.
* *
* See MajorityJudgmentDeliberator for an implementation. * See MajorityJudgmentDeliberator for an implementation.
* One could implement other deliberators, such as CentralJudgment or UsualJudgment. * One could implement other deliberators, such as:
* - CentralJudgmentDeliberator
* - UsualJudgmentDeliberator
*/ */
public interface DeliberatorInterface { public interface DeliberatorInterface {

@ -18,11 +18,10 @@ import java.util.Comparator;
* *
* https://en.wikipedia.org/wiki/Majority_judgment * https://en.wikipedia.org/wiki/Majority_judgment
* https://fr.wikipedia.org/wiki/Jugement_majoritaire * https://fr.wikipedia.org/wiki/Jugement_majoritaire
*
* Should this class be "final" ?
*/ */
public class MajorityJudgmentDeliberator implements DeliberatorInterface { final public class MajorityJudgmentDeliberator implements DeliberatorInterface {
@Override
public ResultInterface deliberate(TallyInterface tally) { public ResultInterface deliberate(TallyInterface tally) {
ProposalTallyInterface[] tallies = tally.getProposalsTallies(); ProposalTallyInterface[] tallies = tally.getProposalsTallies();
BigInteger amountOfJudges = tally.getAmountOfJudges(); BigInteger amountOfJudges = tally.getAmountOfJudges();
@ -41,7 +40,7 @@ public class MajorityJudgmentDeliberator implements DeliberatorInterface {
proposalResults[proposalIndex] = proposalResult; proposalResults[proposalIndex] = proposalResult;
} }
// II. Sort Proposals by score // II. Sort Proposals by score (lexicographical inverse)
ProposalResult[] proposalResultsSorted = proposalResults.clone(); ProposalResult[] proposalResultsSorted = proposalResults.clone();
assert(proposalResultsSorted[0].hashCode() == proposalResults[0].hashCode()); // we need a shallow clone assert(proposalResultsSorted[0].hashCode() == proposalResults[0].hashCode()); // we need a shallow clone
Arrays.sort(proposalResultsSorted, new Comparator<ProposalResultInterface>() { Arrays.sort(proposalResultsSorted, new Comparator<ProposalResultInterface>() {
@ -70,11 +69,21 @@ public class MajorityJudgmentDeliberator implements DeliberatorInterface {
return result; return result;
} }
public String computeScore(ProposalTallyInterface tally, BigInteger amountOfJudges) { protected String computeScore(ProposalTallyInterface tally, BigInteger amountOfJudges) {
return computeScore(tally, amountOfJudges, true, false); return computeScore(tally, amountOfJudges, true, false);
} }
public String computeScore( /**
* A higher score means a better rank.
* Assumes that grades' tallies are provided from "worst" grade to "best" grade.
*
* @param tally Holds the tallies of each Grade for a single Proposal
* @param amountOfJudges
* @param favorContestation
* @param onlyNumbers Do not use separation characters, match `^[0-9]+$`
* @return
*/
protected String computeScore(
ProposalTallyInterface tally, ProposalTallyInterface tally,
BigInteger amountOfJudges, BigInteger amountOfJudges,
Boolean favorContestation, Boolean favorContestation,
@ -82,8 +91,8 @@ public class MajorityJudgmentDeliberator implements DeliberatorInterface {
) { ) {
ProposalTallyAnalysis analysis = new ProposalTallyAnalysis(); ProposalTallyAnalysis analysis = new ProposalTallyAnalysis();
int amountOfGrades = tally.getTally().length; int amountOfGrades = tally.getTally().length;
int digitsForGrade = ("" + amountOfGrades).length(); int digitsForGrade = countDigits(amountOfGrades);
int digitsForGroup = ("" + amountOfJudges).length() + 1; int digitsForGroup = countDigits(amountOfJudges) + 1;
ProposalTallyInterface currentTally = tally.duplicate(); ProposalTallyInterface currentTally = tally.duplicate();
@ -107,6 +116,7 @@ public class MajorityJudgmentDeliberator implements DeliberatorInterface {
score += String.format( score += String.format(
"%0"+digitsForGroup+"d", "%0"+digitsForGroup+"d",
// We offset by amountOfJudges to keep a lexicographical order (no negatives)
// amountOfJudges + secondMedianGroupSize * secondMedianGroupSign // amountOfJudges + secondMedianGroupSize * secondMedianGroupSign
amountOfJudges.add( amountOfJudges.add(
analysis.getSecondMedianGroupSize().multiply( analysis.getSecondMedianGroupSize().multiply(
@ -121,4 +131,12 @@ public class MajorityJudgmentDeliberator implements DeliberatorInterface {
return score; return score;
} }
protected int countDigits(int number) {
return ("" + number).length();
}
protected int countDigits(BigInteger number) {
return ("" + number).length();
}
} }

@ -2,20 +2,21 @@ package fr.mieuxvoter.mj;
public interface ProposalResultInterface { public interface ProposalResultInterface {
/** /**
* Rank starts at 1 ("best" proposal), and goes upwards. * Rank starts at 1 ("best" proposal), and goes upwards.
* Multiple Proposals may receive the same rank, * Multiple Proposals may receive the same rank,
* in the extreme case where they received the exact same judgments. * in the extreme case where they received the exact same judgments,
* or judgment repartition in normalized tallies.
*/ */
public Integer getRank(); public Integer getRank();
/** /**
* This score was used to compute the rank. * This score was used to compute the rank.
* It is made of integer characters, with zeroes for padding. * It is made of integer characters, with zeroes for padding.
* Reverse lexicographical order: "higher" is "better". * Inverse lexicographical order: "higher" is "better".
* You're probably never going to need this, but it's here anyway. * You're probably never going to need this, but it's here anyway.
*/ */
public String getScore(); public String getScore();
} }

Loading…
Cancel
Save