feat: median default grade tally

pull/12/head
Dominique Merle 3 years ago
parent 54b64bb48d
commit 86d893f53f

@ -140,17 +140,17 @@ ResultInterface result = mj.deliberate(tally);
- [x] Ranking
- [x] Release v0.1.0
- [x] Guess the amount of judges
- [ ] Allow defining a default grade
- [x] Allow defining a default grade
- [x] Static Grade (configurable)
- [x] Normalization (using least common multiple)
- [ ] Median Grade
- [x] Normalization (using Least Common Multiple)
- [x] Median Grade
- [ ] Release v0.2.0
- [ ] Publish on package repositories
- [ ] Gradle
- [ ] Maven
- [ ] … ? (please share your knowledge to help us!)
- [ ] Release v0.3.0
- [ ] Use it somewhere in another app, adjust API as needed (one last time)
- [ ] Use it somewhere in an application, adjust API as needed (one last time)
- [ ] Release v1.0.0

@ -0,0 +1,43 @@
package fr.mieuxvoter.mj;
import java.math.BigInteger;
/**
* Fill the missing judgments into the median grade.
* Useful when the proposals have not received the exact same amount of votes and
* the median grade is considered a sane default.
*/
public class MedianDefaultTally extends Tally implements TallyInterface {
public MedianDefaultTally(ProposalTallyInterface[] proposalsTallies, BigInteger amountOfJudges) {
super(proposalsTallies, amountOfJudges);
fillWithDefaultGrade();
}
public MedianDefaultTally(ProposalTallyInterface[] proposalsTallies, Long amountOfJudges) {
super(proposalsTallies, amountOfJudges);
fillWithDefaultGrade();
}
public MedianDefaultTally(ProposalTallyInterface[] proposalsTallies, Integer amountOfJudges) {
super(proposalsTallies, amountOfJudges);
fillWithDefaultGrade();
}
protected void fillWithDefaultGrade() {
int amountOfProposals = getAmountOfProposals();
for (int i = 0 ; i < amountOfProposals ; i++) {
ProposalTallyInterface proposal = getProposalsTallies()[i];
ProposalTallyAnalysis analysis = new ProposalTallyAnalysis(proposal);
Integer defaultGrade = analysis.getMedianGrade();
BigInteger amountOfJudgments = proposal.getAmountOfJudgments();
BigInteger missingAmount = this.amountOfJudges.subtract(amountOfJudgments);
int missingSign = missingAmount.compareTo(BigInteger.ZERO);
assert(0 <= missingSign); // ERROR: More judgments than judges!
if (0 < missingSign) {
proposal.getTally()[defaultGrade] = proposal.getTally()[defaultGrade].add(missingAmount);
}
}
}
}

@ -213,7 +213,7 @@ class MajorityJudgmentDeliberatorTest {
}
@Test
@DisplayName("Test static default grade with thousands of proposals")
@DisplayName("Test static default grade with thousands of proposals and millions of judges")
public void testStaticDefaultWithThousandsOfProposals() {
int amountOfProposals = 1337;
Integer amountOfJudges = 60000000;
@ -257,6 +257,30 @@ class MajorityJudgmentDeliberatorTest {
// }
// }
@Test
@DisplayName("Test with a median default grade")
public void testMedianDefaultGrade() {
Integer amountOfJudges = 42;
DeliberatorInterface mj = new MajorityJudgmentDeliberator();
TallyInterface tally = new MedianDefaultTally(new ProposalTallyInterface[] {
new ProposalTally(new Integer[]{ 0, 0, 1 }),
new ProposalTally(new Integer[]{ 0, 1, 0 }),
new ProposalTally(new Integer[]{ 1, 1, 1 }),
new ProposalTally(new Integer[]{ 1, 0, 1 }),
new ProposalTally(new Integer[]{ 1, 0, 0 }),
}, amountOfJudges);
ResultInterface result = mj.deliberate(tally);
assertNotNull(result);
assertEquals(5, result.getProposalResults().length);
assertEquals(1, result.getProposalResults()[0].getRank());
assertEquals(2, result.getProposalResults()[1].getRank());
assertEquals(3, result.getProposalResults()[2].getRank());
assertEquals(4, result.getProposalResults()[3].getRank());
assertEquals(5, result.getProposalResults()[4].getRank());
}
@Test
@DisplayName("Test normalized tallies with thousands of (prime) proposals")
public void testNormalizedWithThousandsOfPrimeProposals() {

Loading…
Cancel
Save