This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit b393f6b356e0ba98b1318d22bcdf725d2c3a8ea4 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Fri May 25 11:37:05 2018 +0200 refs #187 : Améliorer l'affichage des résultats en 'Coombs' en précisant le tour d'élimintation --- pollen-ui-riot-js/src/main/web/i18n/en.json | 4 +- pollen-ui-riot-js/src/main/web/i18n/fr.json | 4 +- .../src/main/web/tag/poll/EditVoteOrder.tag.html | 10 +- .../src/main/web/tag/poll/Results.tag.html | 10 +- .../votecounting/AbstractVoteCountingStrategy.java | 7 +- .../pollen/votecounting/model/ChoiceScore.java | 10 - .../votecounting/model/VoteCountingResult.java | 2 +- .../BordaVoteCountingStrategyTest.java | 184 +++++++++--------- .../CondorcetVoteCountingStrategyTest.java | 212 ++++++++++----------- .../votecounting/CoombsVoteCountingStrategy.java | 179 ++++++++--------- .../CoombsVoteCountingStrategyTest.java | 210 ++++++++++---------- .../CumulativeVoteCountingStrategyTest.java | 148 +++++++------- .../InstantRunoffVoteCountingStrategy.java | 155 +++++++-------- .../InstantRunoffVoteCountingStrategyTest.java | 184 +++++++++--------- .../MajorityJudgmentVoteCountingStrategyTest.java | 108 +++++------ .../NormalVoteCountingStrategyTest.java | 140 +++++++------- .../NumberVoteCountingStrategyTest.java | 144 +++++++------- 17 files changed, 831 insertions(+), 880 deletions(-) diff --git a/pollen-ui-riot-js/src/main/web/i18n/en.json b/pollen-ui-riot-js/src/main/web/i18n/en.json index 6695945c..3bc6e723 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/en.json +++ b/pollen-ui-riot-js/src/main/web/i18n/en.json @@ -87,7 +87,7 @@ "poll_results_results": "Result", "poll_results_scores": "Score", "poll_results_totals": "Total", - "poll_results_eliminated": "Eliminated", + "poll_results_eliminated": "Eliminated round {0}", "poll_results_unit_1_one": "vote", "poll_results_unit_1_many": "votes", "poll_results_unit_2_one": "point", @@ -150,7 +150,7 @@ "poll_votes_results": "Result", "poll_votes_scores": "Score", "poll_votes_totals": "Total", - "poll_votes_eliminated": "Eliminated", + "poll_votes_eliminated": "Eliminated round {0}", "poll_votes_noVote": "No vote", "poll_votes_choicesScaleHelper": "Place here the choices below in the order of your preferences", "poll_votes_choicesScaleHelper_withMax": "Place here the {0} firsts choices below in the order of your preferences", diff --git a/pollen-ui-riot-js/src/main/web/i18n/fr.json b/pollen-ui-riot-js/src/main/web/i18n/fr.json index 1ef3059a..958bdef1 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/fr.json +++ b/pollen-ui-riot-js/src/main/web/i18n/fr.json @@ -87,7 +87,7 @@ "poll_results_results": "Résultat", "poll_results_scores": "Scores", "poll_results_totals": "Totaux", - "poll_results_eliminated": "Éliminé", + "poll_results_eliminated": "Éliminé tour {0}", "poll_results_unit_1_one": "vote", "poll_results_unit_1_many": "votes", "poll_results_unit_2_one": "point", @@ -150,7 +150,7 @@ "poll_votes_results": "Résultat", "poll_votes_scores": "Score", "poll_votes_totals": "Total", - "poll_votes_eliminated": "Éliminé", + "poll_votes_eliminated": "Éliminé tour {0}", "poll_votes_noVote": "Aucun vote", "poll_votes_choicesScaleHelper": "Placez ici les choix ci-dessous dans l'ordre de vos préférences", "poll_votes_choicesScaleHelper_withMax": "Placez ici vos {0} premiers choix ci-dessous dans l'ordre de vos préférences", diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/EditVoteOrder.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/EditVoteOrder.tag.html index 204aea04..3846cb59 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/EditVoteOrder.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/EditVoteOrder.tag.html @@ -94,12 +94,12 @@ <span if={!choice.score}>{parent.parent._t.noVote}</span> <span if={choice.score}> <i if="{choice.score.scoreOrder === 0}" class="fa fa-trophy fa-15x winner"></i> - {choice.score.scoreValue} - <span if={choice.score.scoreValue || !parent.pollTypeCoombs}> + <span if={choice.score.scoreValue >= 0 || !parent.pollTypeRound}> + {choice.score.scoreValue} {parent.parent._t["results_unit_" + parent.poll.voteCountingType + "_" + (choice.score.scoreValue > 1 ? "many" : "one")]} </span> - <span if={!choice.score.scoreValue && parent.pollTypeCoombs}> - {parent.parent._t.eliminated} + <span if={choice.score.scoreValue < 0 && parent.pollTypeRound}> + {parent.parent._l("eliminated", parent.poll.choiceCount + choice.score.scoreValue + 1)} </span> </span> </div> @@ -128,7 +128,7 @@ this.onPollChange = poll2 => { this.poll = poll2; - this.pollTypeCoombs = poll2.voteCountingType && poll2.voteCountingType === 7; + this.pollTypeRound = poll2.voteCountingType && (poll2.voteCountingType === 7 || poll2.voteCountingType === 6); this.maxChoiceNumber = this.poll.voteCountingConfig.maxChoiceNumber; this.update(); this.placeChoices(true); diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Results.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Results.tag.html index 4bf0c4c0..da3826dd 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Results.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Results.tag.html @@ -46,12 +46,12 @@ import "../voteCountingType/MajorityJudgmentDetailResult.tag.html"; <td class="score separator-top">{result.scoreOrder + 1}</td> <td class="votes separator-top"> <span if={parent.poll.voteCountingType !== 8}> - {result.scoreValue} - <span if={result.scoreValue || !pollTypeCoombs}> + <span if={result.scoreValue >= 0 || !pollTypeRound}> + {result.scoreValue} {parent._t["unit_" + poll.voteCountingType + "_" + (result.scoreValue > 1 ? "many" : "one")]} </span> - <span if={!result.scoreValue && pollTypeCoombs}> - {parent._t.eliminated} + <span if={result.scoreValue < 0 && pollTypeRound}> + {parent._l("eliminated", parent.poll.choiceCount + result.scoreValue + 1)} </span> </span> <span if={parent.poll.voteCountingType === 8}> @@ -85,7 +85,7 @@ import "../voteCountingType/MajorityJudgmentDetailResult.tag.html"; this.onPollChange = poll2 => { this.loaded = !poll2.resultIsVisible || poll2.results !== undefined; this.poll = poll2; - this.pollTypeCoombs = poll2.voteCountingType && poll2.voteCountingType === 7; + this.pollTypeRound = poll2.voteCountingType && (poll2.voteCountingType === 7 || poll2.voteCountingType === 6); this.update(); }; diff --git a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java index 0500b312..439bf931 100644 --- a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java +++ b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java @@ -75,7 +75,7 @@ public abstract class AbstractVoteCountingStrategy<C extends VoteCountingConfig> } public Map<String, ChoiceScore> newEmptyChoiceScoreMap(Set<Voter> voters) { - return newEmptyChoiceScoreMap(voters, null); + return newEmptyChoiceScoreMap(voters, ZERO_D); } public Map<String, ChoiceScore> newEmptyChoiceScoreMap(Set<Voter> voters, BigDecimal defaultScore) { @@ -96,7 +96,7 @@ public abstract class AbstractVoteCountingStrategy<C extends VoteCountingConfig> // get scores by score value Multimap<BigDecimal, ChoiceScore> map = Multimaps.index( - scores, ChoiceScore.SCORE_BY_VALUE::apply + scores, ChoiceScore::getScoreValue ); // get all distinct score values @@ -141,8 +141,7 @@ public abstract class AbstractVoteCountingStrategy<C extends VoteCountingConfig> for (Voter voter : voters) { - List<Set<String>> sortedChoices = sortVoteForChoices( - voter.getVoteForChoices()); + List<Set<String>> sortedChoices = sortVoteForChoices(voter.getVoteForChoices()); voterSortedChoices.put(voter, sortedChoices); } return voterSortedChoices; diff --git a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/ChoiceScore.java b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/ChoiceScore.java index 59e70b4c..ade20e4d 100644 --- a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/ChoiceScore.java +++ b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/ChoiceScore.java @@ -23,7 +23,6 @@ package org.chorem.pollen.votecounting.model; import java.io.Serializable; import java.math.BigDecimal; import java.util.Objects; -import java.util.function.Function; /** * Score for a given choice. @@ -38,15 +37,6 @@ public class ChoiceScore implements ChoiceIdAble, Comparable<ChoiceScore>, Seria private static final long serialVersionUID = 1L; - public static final Function<ChoiceScore, Integer> SCORE_BY_ORDER = ChoiceScore::getScoreOrder; - - protected static final BigDecimal MIN_VALUE = BigDecimal.valueOf(Double.MIN_VALUE); - - public static final Function<ChoiceScore, BigDecimal> SCORE_BY_VALUE = input -> { - BigDecimal value = input.getScoreValue(); - return value == null ? MIN_VALUE : value; - }; - /** Id of the choice. */ private String choiceId; diff --git a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingResult.java b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingResult.java index ecb109ca..66d587f1 100644 --- a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingResult.java +++ b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingResult.java @@ -89,7 +89,7 @@ public class VoteCountingResult implements Serializable { public ArrayListMultimap<Integer, ChoiceScore> getScoresByRank() { if (scoresByRank == null) { scoresByRank = ArrayListMultimap.create( - Multimaps.index(scores, ChoiceScore.SCORE_BY_ORDER::apply)); + Multimaps.index(scores, ChoiceScore::getScoreOrder)); } return scoresByRank; } diff --git a/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategyTest.java b/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategyTest.java index 53b07c12..83f6e841 100644 --- a/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategyTest.java +++ b/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategyTest.java @@ -83,28 +83,28 @@ public class BordaVoteCountingStrategyTest { // D 17 15 26 42 207 (=17*4+15*3+26*2+42) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("Ville A", 42.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 3.). - addVoteForChoice(CHOICE_D, 4.). - newVoter("Ville B", 26.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 2.). - addVoteForChoice(CHOICE_D, 3.). - addVoteForChoice(CHOICE_A, 4.). - newVoter("Ville C", 15.). - addVoteForChoice(CHOICE_C, 1.). - addVoteForChoice(CHOICE_D, 2.). - addVoteForChoice(CHOICE_B, 3.). - addVoteForChoice(CHOICE_A, 4.). - newVoter("Ville D", 17.). - addVoteForChoice(CHOICE_D, 1.). - addVoteForChoice(CHOICE_C, 2.). - addVoteForChoice(CHOICE_B, 3.). - addVoteForChoice(CHOICE_A, 4.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("Ville A", 42.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 3.) + .addVoteForChoice(CHOICE_D, 4.) + .newVoter("Ville B", 26.) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, 2.) + .addVoteForChoice(CHOICE_D, 3.) + .addVoteForChoice(CHOICE_A, 4.) + .newVoter("Ville C", 15.) + .addVoteForChoice(CHOICE_C, 1.) + .addVoteForChoice(CHOICE_D, 2.) + .addVoteForChoice(CHOICE_B, 3.) + .addVoteForChoice(CHOICE_A, 4.) + .newVoter("Ville D", 17.) + .addVoteForChoice(CHOICE_D, 1.) + .addVoteForChoice(CHOICE_C, 2.) + .addVoteForChoice(CHOICE_B, 3.) + .addVoteForChoice(CHOICE_A, 4.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -127,20 +127,20 @@ public class BordaVoteCountingStrategyTest { // 2 (a=3 b=2 c=1) c(3) > b(2) > a(1) // 3 (a=1 b=null c=2) a(3) > c(2) > b(1) // Result a = 2*3+1=7, b =2*2+1=5, c = 1*3+1*2+1=6 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 3.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 3.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 1.) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, 2.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -163,20 +163,20 @@ public class BordaVoteCountingStrategyTest { // 3 (a=null b=null c=2) c>a|b // Result (a=3*2+2=8 b=2*3=6 c=1+2*3=7) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 1.) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, 2.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -199,20 +199,20 @@ public class BordaVoteCountingStrategyTest { // 3 (a=null b=null c=1) c(3) > a|c(2) // Result (a=3+2*2=7 b=3+2*2=7 c=3+2*2=7) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, 1.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -235,20 +235,20 @@ public class BordaVoteCountingStrategyTest { // 3 (x1) (a=null b=1 c=2) b(3) > c(2) > a(1) // Result (a=2*3+1*2+1*1=9 b=2*2+1*3+1*3=10 c=2*2+1*2+1*2=8) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 2.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, 2.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -271,20 +271,20 @@ public class BordaVoteCountingStrategyTest { // 3 (x3) (a=null b=2 c=1) c(3) > b(2) > a(1) // Result (a=1*3*2+1*2+1*1*3=11 b=2*2+1*3+3*2=13 c=2*2+1*2+3*3=15) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 3.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 2.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 3.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 1.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); diff --git a/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategyTest.java b/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategyTest.java index 04f811b8..2a96c5b6 100644 --- a/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategyTest.java +++ b/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategyTest.java @@ -84,20 +84,20 @@ public class CondorcetVoteCountingStrategyTest { //-------------------- // Result 2 -2 0 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 3.). - addVoteForChoice(CHOICE_C, 2.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 3.) + .addVoteForChoice(CHOICE_C, 2.) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, 2.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -126,20 +126,20 @@ public class CondorcetVoteCountingStrategyTest { //-------------------- // Result 2 -2 0 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 3.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 3.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 1.) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, 2.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -168,20 +168,20 @@ public class CondorcetVoteCountingStrategyTest { //-------------------- // Result 1 -2 1 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 1.) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, 2.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -210,20 +210,20 @@ public class CondorcetVoteCountingStrategyTest { //-------------------- // Result 0 0 0 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, 1.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -252,20 +252,20 @@ public class CondorcetVoteCountingStrategyTest { //-------------------- // Result 1 1 -2 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 2.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, 2.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -294,20 +294,20 @@ public class CondorcetVoteCountingStrategyTest { //-------------------- // Result -2 0 2 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 3.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 2.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 3.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 1.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -415,28 +415,28 @@ public class CondorcetVoteCountingStrategyTest { //-------------------- // Result 2 0 -2 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 3.). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 3.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 3.). - newVoter("4", 1.). - addVoteForChoice(CHOICE_A, 3.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 2.). - newVoter("5", 1.). - addVoteForChoice(CHOICE_A, 3.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 3.) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 3.) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 3.) + .newVoter("4", 1.) + .addVoteForChoice(CHOICE_A, 3.) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, 2.) + .newVoter("5", 1.) + .addVoteForChoice(CHOICE_A, 3.) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, 2.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); diff --git a/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java b/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java index 15758598..63d73292 100644 --- a/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java +++ b/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java @@ -20,7 +20,6 @@ */ package org.chorem.pollen.votecounting; -import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.apache.commons.collections4.CollectionUtils; @@ -31,16 +30,22 @@ import org.chorem.pollen.votecounting.model.VoteForChoice; import org.chorem.pollen.votecounting.model.Voter; import java.math.BigDecimal; +import java.util.Collection; import java.util.Comparator; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; /** * Coombs vote counting strategy. * + * use negative score value for indicate elimination round + * from -1 * nb choices + * + * exemple : for 5 choices, score value for first elimination is -5, for next -4, ... + * * @author Tony Chemit - dev@tchemit.fr * @since 1.4.5 */ @@ -54,26 +59,19 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy<Emp CoombsDetailResult detailResult = new CoombsDetailResult(); // calcul du score minimum pour atteindre la majorité absolue - double totalWeight = 0.; - for (Voter voter : voters) { - totalWeight += voter.getWeight(); - } - totalWeight /= 2; + double totalWeight = voters.stream().mapToDouble(Voter::getWeight).sum() / 2; // calcul pour chaque votant de ses choix préférés - Map<Voter, List<Set<String>>> topRankChoices = - buildVoterSortedChoices(voters); + Map<Voter, List<Set<String>>> topRankChoices = buildVoterSortedChoices(voters); - Set<String> choiceIdsToExclude = Sets.newHashSet(); Set<String> choiceIdsToKeep = Sets.newHashSet(scores.keySet()); - //FIXME Must use round of elemination to order scores round(topRankChoices, - choiceIdsToExclude, - choiceIdsToKeep, - scores, - totalWeight, - detailResult); + choiceIdsToKeep, + scores, + totalWeight, + detailResult, + - scores.keySet().size()); // order scores (using their value) and return result return orderByValues(scores.values(), detailResult); @@ -95,21 +93,21 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy<Emp } protected void round(Map<Voter, List<Set<String>>> topRankChoices, - Set<String> idsToExclude, - Set<String> idsToInclude, + Set<String> idsEnabled, Map<String, ChoiceScore> resultByChoice, double totalWeight, - CoombsDetailResult detailResult) { + CoombsDetailResult detailResult, + int roundIndex) { CoombsRound round = new CoombsRound(); detailResult.getRounds().add(round); - List<ChoiceScore> results = applyScores(topRankChoices, - idsToExclude, - idsToInclude, - resultByChoice, - round); + List<ChoiceScore> results = applyScores( + topRankChoices, + idsEnabled, + resultByChoice, + round); if (!results.isEmpty()) { @@ -117,58 +115,56 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy<Emp BigDecimal scoreValue = results.get(results.size() - 1).getScoreValue(); double max = scoreValue == null ? 0 : scoreValue.doubleValue(); - if (max < totalWeight || max == totalWeight && idsToInclude.size() > 2) { + if (max < totalWeight || max == totalWeight && idsEnabled.size() > 2) { // pas de majorité absolue, il faut éliminer le(s) choix les plus mauvais - - guessChoiceIdsToRemove(idsToInclude, idsToExclude, topRankChoices, round); + Set<String> idsToExclude = guessChoiceIdsToRemove(idsEnabled, topRankChoices, round); // on ne veux plus utiliser ces choix dans le tour suivant - idsToInclude.removeAll(idsToExclude); + idsEnabled.removeAll(idsToExclude); - // nouveau tour - round(topRankChoices, - idsToExclude, - idsToInclude, - resultByChoice, - totalWeight, - detailResult); + topRankChoices.values() + .stream() + .flatMap(Collection::stream) + .forEach(choiceIds -> choiceIds.removeAll(idsToExclude)); - } else { - - // majorité absolue trouvée plus rien à faire en fait :) - // ou 2 choix égaux - } - } - } + topRankChoices.values().forEach(list -> + list.removeIf(Collection::isEmpty) + ); - protected List<ChoiceScore> applyScores(Map<Voter, List<Set<String>>> topRankChoices, - Set<String> idsToExclude, - Set<String> idsToInclude, - Map<String, ChoiceScore> resultByChoice, CoombsRound round) { - if (CollectionUtils.isNotEmpty(idsToExclude)) { + if (CollectionUtils.isNotEmpty(idsEnabled)) { - // on supprime des classements les ids données + idsToExclude.stream() + .map(resultByChoice::get) + .forEach(score -> score.setScoreValue(BigDecimal.valueOf(roundIndex))); - for (List<Set<String>> choicesByLevel : topRankChoices.values()) { - Iterator<Set<String>> itr = choicesByLevel.iterator(); - while (itr.hasNext()) { - Set<String> choiceIds = itr.next(); - choiceIds.removeAll(idsToExclude); - if (choiceIds.isEmpty()) { - // remove this level - itr.remove(); - } + // nouveau tour + round(topRankChoices, + idsEnabled, + resultByChoice, + totalWeight, + detailResult, + roundIndex + 1); } + +// } else { + // majorité absolue trouvée plus rien à faire en fait :) + // ou 2 choix égaux } } + } + + protected List<ChoiceScore> applyScores(Map<Voter, List<Set<String>>> topRankChoices, + Set<String> idsEnabled, + Map<String, ChoiceScore> resultByChoice, + CoombsRound round) { // on remet à zero les scores pour les ids a conserver - for (String id : idsToInclude) { - resultByChoice.get(id).setScoreValue(null); - getRoundChoice(round, id); + for (String id : idsEnabled) { + resultByChoice.get(id).setScoreValue(ZERO_D); + addRoundChoiceFirst(round, id, 0); } // on calcule les scores à partir des classements @@ -181,42 +177,24 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy<Emp Voter voter = entry.getKey(); double voterWeight = voter.getWeight(); for (String id : winnerIds) { - if (idsToInclude.contains(id)) { - ChoiceScore choiceScore = resultByChoice.get(id); - choiceScore.addScoreValue(voterWeight); - addRoundChoiceFirst(round, id, voterWeight); - } + ChoiceScore choiceScore = resultByChoice.get(id); + choiceScore.addScoreValue(voterWeight); + addRoundChoiceFirst(round, id, voterWeight); } } } // recopy choices to run rounds on it and eliminates choices until // there is a choice > 50 - List<ChoiceScore> results = Lists.newArrayList(); - - for (String id : idsToInclude) { - results.add(resultByChoice.get(id)); - } + List<ChoiceScore> results = idsEnabled.stream() + .map(resultByChoice::get) + .sorted(Comparator.comparing(ChoiceScore::getScoreValue, Comparator.nullsFirst(Comparator.naturalOrder()))) + .collect(Collectors.toList()); - results.sort(Comparator.comparing(ChoiceScore::getScoreValue, Comparator.nullsFirst(Comparator.naturalOrder()))); - - // on supprime tout score à 0 - Iterator<ChoiceScore> itr = results.iterator(); - while (itr.hasNext()) { - ChoiceScore choiceScore = itr.next(); - if (choiceScore.getScoreValue() == null || - ZERO_D.equals(choiceScore.getScoreValue())) { - itr.remove(); - } else { - // score > 0 on peut s'arreter - break; - } - } return results; } - protected void guessChoiceIdsToRemove(Set<String> idsToInclude, - Set<String> idsToExclude, + protected Set<String> guessChoiceIdsToRemove(Set<String> idsToInclude, Map<Voter, List<Set<String>>> results, CoombsRound round) { @@ -244,28 +222,21 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy<Emp } // on construit alors la liste des scores - List<ChoiceScore> scores = Lists.newArrayList(badScores.values()); - - // que l'on trie - scores.sort(Comparator.comparing(ChoiceScore::getScoreValue, Comparator.nullsLast(Comparator.naturalOrder())).reversed()); - - BigDecimal firstScoreValue = scores.get(0).getScoreValue(); - double maxScore = firstScoreValue == null ? 0 : firstScoreValue.doubleValue(); + BigDecimal maxScore = badScores.values() + .stream() + .map(ChoiceScore::getScoreValue) + .max(BigDecimal::compareTo) + .orElse(ZERO_D); - idsToExclude.clear(); + Set<String> idsToExclude = badScores.values() + .stream() + .filter(score -> maxScore.equals(score.getScoreValue())) + .map(ChoiceScore::getChoiceId) + .collect(Collectors.toSet()); - for (ChoiceScore choiceScore : scores) { - BigDecimal scoreValue = choiceScore.getScoreValue(); - if (maxScore == (scoreValue == null ? 0 : scoreValue.doubleValue())) { - - idsToExclude.add(choiceScore.getChoiceId()); - } else { - // value < max, on peut s'arreter là - break; - } - } round.getChoiceIdsExclude().addAll(idsToExclude); + return idsToExclude; } protected void addRoundChoiceFirst(CoombsRound round, String choiceId, double score) { diff --git a/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategyTest.java b/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategyTest.java index 9cddab39..884018b9 100644 --- a/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategyTest.java +++ b/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategyTest.java @@ -78,28 +78,28 @@ public class CoombsVoteCountingStrategyTest { // C 15 43 42 0 15 15 // D 17 15 26 42 17 17 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("Ville A", 42.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 3.). - addVoteForChoice(CHOICE_D, 4.). - newVoter("Ville B", 26.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 2.). - addVoteForChoice(CHOICE_D, 3.). - addVoteForChoice(CHOICE_A, 4.). - newVoter("Ville C", 15.). - addVoteForChoice(CHOICE_C, 1.). - addVoteForChoice(CHOICE_D, 2.). - addVoteForChoice(CHOICE_B, 3.). - addVoteForChoice(CHOICE_A, 4.). - newVoter("Ville D", 17.). - addVoteForChoice(CHOICE_D, 1.). - addVoteForChoice(CHOICE_C, 2.). - addVoteForChoice(CHOICE_B, 3.). - addVoteForChoice(CHOICE_A, 4.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("Ville A", 42.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 3.) + .addVoteForChoice(CHOICE_D, 4.) + .newVoter("Ville B", 26.) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, 2.) + .addVoteForChoice(CHOICE_D, 3.) + .addVoteForChoice(CHOICE_A, 4.) + .newVoter("Ville C", 15.) + .addVoteForChoice(CHOICE_C, 1.) + .addVoteForChoice(CHOICE_D, 2.) + .addVoteForChoice(CHOICE_B, 3.) + .addVoteForChoice(CHOICE_A, 4.) + .newVoter("Ville D", 17.) + .addVoteForChoice(CHOICE_D, 1.) + .addVoteForChoice(CHOICE_C, 2.) + .addVoteForChoice(CHOICE_B, 3.) + .addVoteForChoice(CHOICE_A, 4.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -107,10 +107,10 @@ public class CoombsVoteCountingStrategyTest { assertThat(result.getScores()) .isNotNull() .containsExactlyInAnyOrder( - ChoiceScore.newScore(CHOICE_A, BigDecimal.valueOf(42.0), 1), + ChoiceScore.newScore(CHOICE_A, BigDecimal.valueOf(-4), 3), ChoiceScore.newScore(CHOICE_B, BigDecimal.valueOf(68.0), 0), - ChoiceScore.newScore(CHOICE_C, BigDecimal.valueOf(15.0), 3), - ChoiceScore.newScore(CHOICE_D, BigDecimal.valueOf(17.0), 2)) + ChoiceScore.newScore(CHOICE_C, BigDecimal.valueOf(15.0), 2), + ChoiceScore.newScore(CHOICE_D, BigDecimal.valueOf(17.0), 1)) .isSortedAccordingTo(ChoiceScore::compareTo); } @@ -122,20 +122,20 @@ public class CoombsVoteCountingStrategyTest { // 2 (a=3 b=2 c=1) b 1 // 3 (a=1 b=null c=2) c - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 3.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 3.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 1.) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, 2.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -144,7 +144,7 @@ public class CoombsVoteCountingStrategyTest { .isNotNull() .containsExactlyInAnyOrder( ChoiceScore.newScore(CHOICE_A, BigDecimal.valueOf(2.0), 0), - ChoiceScore.newScore(CHOICE_B, null, 2), + ChoiceScore.newScore(CHOICE_B, BigDecimal.valueOf(0.0), 2), ChoiceScore.newScore(CHOICE_C, BigDecimal.valueOf(1.0), 1)) .isSortedAccordingTo(ChoiceScore::compareTo); } @@ -157,20 +157,20 @@ public class CoombsVoteCountingStrategyTest { // 2 (a=1 b=2 c=1) b - // 3 (a=null b=null c=2) c 2 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 1.) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, 2.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -179,7 +179,7 @@ public class CoombsVoteCountingStrategyTest { .isNotNull() .containsExactlyInAnyOrder( ChoiceScore.newScore(CHOICE_A, BigDecimal.valueOf(2.0), 0), - ChoiceScore.newScore(CHOICE_B, null, 1), + ChoiceScore.newScore(CHOICE_B, BigDecimal.valueOf(0.0), 1), ChoiceScore.newScore(CHOICE_C, BigDecimal.valueOf(2.0), 0)) .isSortedAccordingTo(ChoiceScore::compareTo); } @@ -192,20 +192,20 @@ public class CoombsVoteCountingStrategyTest { // 2 (a=null b=1 c=null) b 1 // 3 (a=null b=null c=1) c 1 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, 1.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -227,20 +227,20 @@ public class CoombsVoteCountingStrategyTest { // 2 (x1) (a=null b=1 c=null) b 2 // 3 (x1) (a=null b=1 c=2) c - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 2.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, 2.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -250,7 +250,7 @@ public class CoombsVoteCountingStrategyTest { .containsExactlyInAnyOrder( ChoiceScore.newScore(CHOICE_A, BigDecimal.valueOf(2.0), 0), ChoiceScore.newScore(CHOICE_B, BigDecimal.valueOf(2.0), 0), - ChoiceScore.newScore(CHOICE_C, null, 1)) + ChoiceScore.newScore(CHOICE_C, BigDecimal.valueOf(-3), 1)) .isSortedAccordingTo(ChoiceScore::compareTo); } @@ -269,20 +269,20 @@ public class CoombsVoteCountingStrategyTest { // 2 tour---------------- // 1er X 3 5 // gagnant C - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 3.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 2.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 3.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 1.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -290,7 +290,7 @@ public class CoombsVoteCountingStrategyTest { assertThat(result.getScores()) .isNotNull() .containsExactlyInAnyOrder( - ChoiceScore.newScore(CHOICE_A, BigDecimal.valueOf(2.0), 2), + ChoiceScore.newScore(CHOICE_A, BigDecimal.valueOf(-3), 2), ChoiceScore.newScore(CHOICE_B, BigDecimal.valueOf(3.0), 1), ChoiceScore.newScore(CHOICE_C, BigDecimal.valueOf(5.0), 0)) .isSortedAccordingTo(ChoiceScore::compareTo); @@ -307,12 +307,12 @@ public class CoombsVoteCountingStrategyTest { @Test public void majorityOnFirstRoundTest() throws Exception { - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 2.). - addVoteForChoice(CHOICE_B, 4.). - addVoteForChoice(CHOICE_C, 3.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 2.) + .addVoteForChoice(CHOICE_B, 4.) + .addVoteForChoice(CHOICE_C, 3.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); diff --git a/pollen-votecounting-cumulative/src/test/java/org/chorem/pollen/votecounting/CumulativeVoteCountingStrategyTest.java b/pollen-votecounting-cumulative/src/test/java/org/chorem/pollen/votecounting/CumulativeVoteCountingStrategyTest.java index b6bb2fe9..6d9fa8d1 100644 --- a/pollen-votecounting-cumulative/src/test/java/org/chorem/pollen/votecounting/CumulativeVoteCountingStrategyTest.java +++ b/pollen-votecounting-cumulative/src/test/java/org/chorem/pollen/votecounting/CumulativeVoteCountingStrategyTest.java @@ -8,12 +8,12 @@ * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% @@ -79,20 +79,20 @@ public class CumulativeVoteCountingStrategyTest { // 3 (a=50 b=50 c=null) // Result (a=50 b=50 c=null) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 100.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 100.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 50.). - addVoteForChoice(CHOICE_B, 50.). - addVoteForChoice(CHOICE_C, null). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 100.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 100.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, 50.) + .addVoteForChoice(CHOICE_B, 50.) + .addVoteForChoice(CHOICE_C, null) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -102,7 +102,7 @@ public class CumulativeVoteCountingStrategyTest { .containsExactlyInAnyOrder( ChoiceScore.newScore(CHOICE_A, BigDecimal.valueOf(50.0), 0), ChoiceScore.newScore(CHOICE_B, BigDecimal.valueOf(50.0), 0), - ChoiceScore.newScore(CHOICE_C, null, 1)) + ChoiceScore.newScore(CHOICE_C, BigDecimal.valueOf(0.0), 1)) .isSortedAccordingTo(ChoiceScore::compareTo); } @@ -114,20 +114,20 @@ public class CumulativeVoteCountingStrategyTest { // 2 (a=50 b=20 c=30) // 3 (a=10 b=50 c=40) // Result (a=26.67 b=33.33 c=40) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 20.). - addVoteForChoice(CHOICE_B, 30.). - addVoteForChoice(CHOICE_C, 50.). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 50.). - addVoteForChoice(CHOICE_B, 20.). - addVoteForChoice(CHOICE_C, 30.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 10.). - addVoteForChoice(CHOICE_B, 50.). - addVoteForChoice(CHOICE_C, 40.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 20.) + .addVoteForChoice(CHOICE_B, 30.) + .addVoteForChoice(CHOICE_C, 50.) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 50.) + .addVoteForChoice(CHOICE_B, 20.) + .addVoteForChoice(CHOICE_C, 30.) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, 10.) + .addVoteForChoice(CHOICE_B, 50.) + .addVoteForChoice(CHOICE_C, 40.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -149,20 +149,20 @@ public class CumulativeVoteCountingStrategyTest { // 2 (a=50 b=50 c=null) // 3 (a=50 b=50 c=null) // Result (a=50 b=50 c=null) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 50.). - addVoteForChoice(CHOICE_B, 50.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 50.). - addVoteForChoice(CHOICE_B, 50.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 50.). - addVoteForChoice(CHOICE_B, 50.). - addVoteForChoice(CHOICE_C, null). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 50.) + .addVoteForChoice(CHOICE_B, 50.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 50.) + .addVoteForChoice(CHOICE_B, 50.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, 50.) + .addVoteForChoice(CHOICE_B, 50.) + .addVoteForChoice(CHOICE_C, null) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -172,7 +172,7 @@ public class CumulativeVoteCountingStrategyTest { .containsExactlyInAnyOrder( ChoiceScore.newScore(CHOICE_A, BigDecimal.valueOf(50.0),0), ChoiceScore.newScore(CHOICE_B, BigDecimal.valueOf(50.0),0), - ChoiceScore.newScore(CHOICE_C, null, 1)) + ChoiceScore.newScore(CHOICE_C, BigDecimal.valueOf(0.0), 1)) .isSortedAccordingTo(ChoiceScore::compareTo); } @@ -184,20 +184,20 @@ public class CumulativeVoteCountingStrategyTest { // 2 (x1) (a=null b=100 c=null) // 3 (x1) (a=null b=50 c=50) // Result (a=50 b=37.5 c=12.5) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 100.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 100.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 50.). - addVoteForChoice(CHOICE_C, 50.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 2.) + .addVoteForChoice(CHOICE_A, 100.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 100.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 50.) + .addVoteForChoice(CHOICE_C, 50.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -219,20 +219,20 @@ public class CumulativeVoteCountingStrategyTest { // 2 (x1) (a=null b=100 c=null) // 3 (x3) (a=null b=50 c=50) // Result (a=33.3 b=41.7 c=25) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 100.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 100.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 3.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 50.). - addVoteForChoice(CHOICE_C, 50.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 2.) + .addVoteForChoice(CHOICE_A, 100.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 100.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 3.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 50.) + .addVoteForChoice(CHOICE_C, 50.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); diff --git a/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java b/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java index 4d0900bb..2775b3f1 100644 --- a/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java +++ b/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java @@ -20,7 +20,6 @@ */ package org.chorem.pollen.votecounting; -import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.apache.commons.collections4.CollectionUtils; import org.chorem.pollen.votecounting.model.ChoiceScore; @@ -30,16 +29,22 @@ import org.chorem.pollen.votecounting.model.VoteForChoice; import org.chorem.pollen.votecounting.model.Voter; import java.math.BigDecimal; +import java.util.Collection; import java.util.Comparator; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; /** * InstantRunoff. * + * use negative score value for indicate elimination round + * from -1 * nb choices + * + * exemple : for 5 choices, score value for first elimination is -5, for next -4, ... + * * @author Tony Chemit - dev@tchemit.fr * @since 1.4.5 */ @@ -53,26 +58,19 @@ public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrat InstantRunoffDetailResult detailResult = new InstantRunoffDetailResult(); // calcul du score minimum pour atteindre la majorité absolue - double totalWeight = 0.; - for (Voter voter : voters) { - totalWeight += voter.getWeight(); - } - totalWeight /= 2; + double totalWeight = voters.stream().mapToDouble(Voter::getWeight).sum() / 2; // calcul pour chaque votant de ses choix préférés - Map<Voter, List<Set<String>>> topRankChoices = - buildVoterSortedChoices(voters); + Map<Voter, List<Set<String>>> topRankChoices = buildVoterSortedChoices(voters); - Set<String> choiceIdsToExclude = Sets.newHashSet(); Set<String> choiceIdsToKeep = Sets.newHashSet(scores.keySet()); - //FIXME Must use round of elimination to order scores round(topRankChoices, - choiceIdsToExclude, - choiceIdsToKeep, - scores, - totalWeight, - detailResult); + choiceIdsToKeep, + scores, + totalWeight, + detailResult, + - scores.keySet().size()); // order scores (using their value) and return result return orderByValues(scores.values(), detailResult); @@ -94,21 +92,21 @@ public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrat } protected void round(Map<Voter, List<Set<String>>> topRankChoices, - Set<String> idsToExclude, - Set<String> idsToInclude, + Set<String> idsEnabled, Map<String, ChoiceScore> resultByChoice, double totalWeight, - InstantRunoffDetailResult detailResult) { + InstantRunoffDetailResult detailResult, + int roundIndex) { InstantRunoffRound round = new InstantRunoffRound(); detailResult.getRounds().add(round); - List<ChoiceScore> results = applyScores(topRankChoices, - idsToExclude, - idsToInclude, - resultByChoice, - round); + List<ChoiceScore> results = applyScores( + topRankChoices, + idsEnabled, + resultByChoice, + round); if (!results.isEmpty()) { @@ -119,52 +117,51 @@ public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrat if (max < totalWeight) { // pas de majorité absolue, il faut éliminer le(s) choix les plus mauvais - - guessChoiceIdsToRemove(idsToExclude, results, round); - + Set<String> idsToExclude = guessChoiceIdsToRemove(results, round); // on ne veux plus utiliser ces choix dans le tour suivant - idsToInclude.removeAll(idsToExclude); + idsEnabled.removeAll(idsToExclude); - // nouveau tour - round(topRankChoices, - idsToExclude, - idsToInclude, - resultByChoice, - totalWeight, detailResult); + topRankChoices.values() + .stream() + .flatMap(Collection::stream) + .forEach(choiceIds -> choiceIds.removeAll(idsToExclude)); - } else { + topRankChoices.values().forEach(list -> + list.removeIf(Collection::isEmpty) + ); - // majorité absolue trouvée plus rien à faire en fait :) - } - } - } - protected List<ChoiceScore> applyScores(Map<Voter, List<Set<String>>> topRankChoices, - Set<String> idsToExclude, - Set<String> idsToInclude, - Map<String, ChoiceScore> resultByChoice, InstantRunoffRound round) { + if (CollectionUtils.isNotEmpty(idsEnabled)) { - if (CollectionUtils.isNotEmpty(idsToExclude)) { + idsToExclude.stream() + .map(resultByChoice::get) + .forEach(score -> score.setScoreValue(BigDecimal.valueOf(roundIndex))); - // on supprime des classements les ids données - for (List<Set<String>> choicesByLevel : topRankChoices.values()) { - Iterator<Set<String>> itr = choicesByLevel.iterator(); - while (itr.hasNext()) { - Set<String> choiceIds = itr.next(); - choiceIds.removeAll(idsToExclude); - if (choiceIds.isEmpty()) { - - // remove this level - itr.remove(); - } + // nouveau tour + round(topRankChoices, + idsEnabled, + resultByChoice, + totalWeight, + detailResult, + roundIndex + 1); } + +// } else { + // majorité absolue trouvée plus rien à faire en fait :) + // ou 2 choix égaux } } + } + + protected List<ChoiceScore> applyScores(Map<Voter, List<Set<String>>> topRankChoices, + Set<String> idsEnabled, + Map<String, ChoiceScore> resultByChoice, + InstantRunoffRound round) { // on remet à zero les scores pour les ids a conserver - for (String id : idsToInclude) { + for (String id : idsEnabled) { resultByChoice.get(id).setScoreValue(BigDecimal.ZERO); addRoundChoice(round, id, 0); } @@ -179,47 +176,41 @@ public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrat Voter voter = entry.getKey(); double voterWeight = voter.getWeight(); for (String id : winnerIds) { - if (idsToInclude.contains(id)) { - ChoiceScore choiceScore = resultByChoice.get(id); - choiceScore.addScoreValue(voterWeight); - addRoundChoice(round, id, voterWeight); - } + ChoiceScore choiceScore = resultByChoice.get(id); + choiceScore.addScoreValue(voterWeight); + addRoundChoice(round, id, voterWeight); } } } // recopy choices to run rounds on it and eliminates choices until // there is a choice > 50 - List<ChoiceScore> results = Lists.newArrayList(); - - for (String id : idsToInclude) { - results.add(resultByChoice.get(id)); - } - - results.sort(Comparator.comparing(ChoiceScore::getScoreValue, Comparator.nullsFirst(Comparator.naturalOrder()))); + List<ChoiceScore> results = idsEnabled.stream() + .map(resultByChoice::get) + .sorted(Comparator.comparing(ChoiceScore::getScoreValue, Comparator.nullsFirst(Comparator.naturalOrder()))) + .collect(Collectors.toList()); return results; } - protected void guessChoiceIdsToRemove(Set<String> idsToExclude, - List<ChoiceScore> results, InstantRunoffRound round) { + protected Set<String> guessChoiceIdsToRemove(List<ChoiceScore> results, InstantRunoffRound round) { - double min = results.get(0).getScoreValue().doubleValue(); + BigDecimal minScore = results + .stream() + .map(ChoiceScore::getScoreValue) + .min(BigDecimal::compareTo) + .orElse(ZERO_D); - idsToExclude.clear(); + Set<String> idsToExclude = results + .stream() + .filter(score -> minScore.equals(score.getScoreValue())) + .map(ChoiceScore::getChoiceId) + .collect(Collectors.toSet()); - for (ChoiceScore choiceScore : results) { + round.getChoiceIdsExclude().addAll(idsToExclude); - BigDecimal scoreValue = choiceScore.getScoreValue(); - if (min == (scoreValue == null ? 0 : scoreValue.doubleValue())) { + return idsToExclude; - idsToExclude.add(choiceScore.getChoiceId()); - } else { - // value > min, on peut s'arreter là - break; - } - } - round.getChoiceIdsExclude().addAll(idsToExclude); } protected void addRoundChoice(InstantRunoffRound round, String choiceId, double score) { diff --git a/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategyTest.java b/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategyTest.java index 96b78afc..41c2a14a 100644 --- a/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategyTest.java +++ b/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategyTest.java @@ -79,28 +79,28 @@ public class InstantRunoffVoteCountingStrategyTest { // C 15 43 42 0 15 - - // D 17 15 26 42 17 32 58 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("Ville A", 42.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 3.). - addVoteForChoice(CHOICE_D, 4.). - newVoter("Ville B", 26.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 2.). - addVoteForChoice(CHOICE_D, 3.). - addVoteForChoice(CHOICE_A, 4.). - newVoter("Ville C", 15.). - addVoteForChoice(CHOICE_C, 1.). - addVoteForChoice(CHOICE_D, 2.). - addVoteForChoice(CHOICE_B, 3.). - addVoteForChoice(CHOICE_A, 4.). - newVoter("Ville D", 17.). - addVoteForChoice(CHOICE_D, 1.). - addVoteForChoice(CHOICE_C, 2.). - addVoteForChoice(CHOICE_B, 3.). - addVoteForChoice(CHOICE_A, 4.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("Ville A", 42.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 3.) + .addVoteForChoice(CHOICE_D, 4.) + .newVoter("Ville B", 26.) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, 2.) + .addVoteForChoice(CHOICE_D, 3.) + .addVoteForChoice(CHOICE_A, 4.) + .newVoter("Ville C", 15.) + .addVoteForChoice(CHOICE_C, 1.) + .addVoteForChoice(CHOICE_D, 2.) + .addVoteForChoice(CHOICE_B, 3.) + .addVoteForChoice(CHOICE_A, 4.) + .newVoter("Ville D", 17.) + .addVoteForChoice(CHOICE_D, 1.) + .addVoteForChoice(CHOICE_C, 2.) + .addVoteForChoice(CHOICE_B, 3.) + .addVoteForChoice(CHOICE_A, 4.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -126,20 +126,20 @@ public class InstantRunoffVoteCountingStrategyTest { //-------------------- // tour 1 2 0 1 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 3.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 3.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 1.) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, 2.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -165,20 +165,20 @@ public class InstantRunoffVoteCountingStrategyTest { // Tour 1 2 0 2 -> elimination B // Tour 2 2 0 2 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 1.) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, 2.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -200,20 +200,20 @@ public class InstantRunoffVoteCountingStrategyTest { // 2 (a=null b=1 c=null) b 1 // 3 (a=null b=null c=1) c 1 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, 1.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -235,20 +235,20 @@ public class InstantRunoffVoteCountingStrategyTest { // 2 (x1) (a=null b=1 c=null) b 2 // 3 (x1) (a=null b=1 c=2) c - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 2.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, 2.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -270,20 +270,20 @@ public class InstantRunoffVoteCountingStrategyTest { // 2 (x1) (a=null b=1 c=null) b 1 // 3 (x3) (a=null b=2 c=1) c 3 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 3.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 2.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 3.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, 1.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); diff --git a/pollen-votecounting-majority-judgment/src/test/java/org/chorem/pollen/votecounting/MajorityJudgmentVoteCountingStrategyTest.java b/pollen-votecounting-majority-judgment/src/test/java/org/chorem/pollen/votecounting/MajorityJudgmentVoteCountingStrategyTest.java index 4a9117ac..dfe7e4a5 100644 --- a/pollen-votecounting-majority-judgment/src/test/java/org/chorem/pollen/votecounting/MajorityJudgmentVoteCountingStrategyTest.java +++ b/pollen-votecounting-majority-judgment/src/test/java/org/chorem/pollen/votecounting/MajorityJudgmentVoteCountingStrategyTest.java @@ -109,33 +109,33 @@ public class MajorityJudgmentVoteCountingStrategyTest { // order 0 3 2 1 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("Voter 1", 1.). - addVoteForChoice(CHOICE_A, GOOD). - addVoteForChoice(CHOICE_B, FAIR). - addVoteForChoice(CHOICE_C, GOOD). - addVoteForChoice(CHOICE_D, POOR). - newVoter("Voter 2", 1.). - addVoteForChoice(CHOICE_A, GOOD). - addVoteForChoice(CHOICE_B, POOR). - addVoteForChoice(CHOICE_C, POOR). - addVoteForChoice(CHOICE_D, GOOD). - newVoter("Voter 3", 1.). - addVoteForChoice(CHOICE_A, POOR). - addVoteForChoice(CHOICE_B, FAIR). - addVoteForChoice(CHOICE_C, POOR). - addVoteForChoice(CHOICE_D, FAIR). - newVoter("Voter 4", 1.). - addVoteForChoice(CHOICE_A, FAIR). - addVoteForChoice(CHOICE_B, POOR). - addVoteForChoice(CHOICE_C, FAIR). - addVoteForChoice(CHOICE_D, GOOD). - newVoter("Voter 5", 1.). - addVoteForChoice(CHOICE_A, GOOD). - addVoteForChoice(CHOICE_B, POOR). - addVoteForChoice(CHOICE_C, GOOD). - addVoteForChoice(CHOICE_D, FAIR). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("Voter 1", 1.) + .addVoteForChoice(CHOICE_A, GOOD) + .addVoteForChoice(CHOICE_B, FAIR) + .addVoteForChoice(CHOICE_C, GOOD) + .addVoteForChoice(CHOICE_D, POOR) + .newVoter("Voter 2", 1.) + .addVoteForChoice(CHOICE_A, GOOD) + .addVoteForChoice(CHOICE_B, POOR) + .addVoteForChoice(CHOICE_C, POOR) + .addVoteForChoice(CHOICE_D, GOOD) + .newVoter("Voter 3", 1.) + .addVoteForChoice(CHOICE_A, POOR) + .addVoteForChoice(CHOICE_B, FAIR) + .addVoteForChoice(CHOICE_C, POOR) + .addVoteForChoice(CHOICE_D, FAIR) + .newVoter("Voter 4", 1.) + .addVoteForChoice(CHOICE_A, FAIR) + .addVoteForChoice(CHOICE_B, POOR) + .addVoteForChoice(CHOICE_C, FAIR) + .addVoteForChoice(CHOICE_D, GOOD) + .newVoter("Voter 5", 1.) + .addVoteForChoice(CHOICE_A, GOOD) + .addVoteForChoice(CHOICE_B, POOR) + .addVoteForChoice(CHOICE_C, GOOD) + .addVoteForChoice(CHOICE_D, FAIR) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -167,33 +167,33 @@ public class MajorityJudgmentVoteCountingStrategyTest { // median P F F P // order 3 0 1 2 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("Voter 1", 2.). - addVoteForChoice(CHOICE_A, POOR). - addVoteForChoice(CHOICE_B, FAIR). - addVoteForChoice(CHOICE_C, GOOD). - addVoteForChoice(CHOICE_D, FAIR). - newVoter("Voter 2", 3.). - addVoteForChoice(CHOICE_A, POOR). - addVoteForChoice(CHOICE_B, FAIR). - addVoteForChoice(CHOICE_C, POOR). - addVoteForChoice(CHOICE_D, POOR). - newVoter("Voter 3", 1.). - addVoteForChoice(CHOICE_A, POOR). - addVoteForChoice(CHOICE_B, GOOD). - addVoteForChoice(CHOICE_C, FAIR). - addVoteForChoice(CHOICE_D, POOR). - newVoter("Voter 4", 1.). - addVoteForChoice(CHOICE_A, FAIR). - addVoteForChoice(CHOICE_B, POOR). - addVoteForChoice(CHOICE_C, FAIR). - addVoteForChoice(CHOICE_D, GOOD). - newVoter("Voter 5", 1.). - addVoteForChoice(CHOICE_A, POOR). - addVoteForChoice(CHOICE_B, POOR). - addVoteForChoice(CHOICE_C, FAIR). - addVoteForChoice(CHOICE_D, POOR). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("Voter 1", 2.) + .addVoteForChoice(CHOICE_A, POOR) + .addVoteForChoice(CHOICE_B, FAIR) + .addVoteForChoice(CHOICE_C, GOOD) + .addVoteForChoice(CHOICE_D, FAIR) + .newVoter("Voter 2", 3.) + .addVoteForChoice(CHOICE_A, POOR) + .addVoteForChoice(CHOICE_B, FAIR) + .addVoteForChoice(CHOICE_C, POOR) + .addVoteForChoice(CHOICE_D, POOR) + .newVoter("Voter 3", 1.) + .addVoteForChoice(CHOICE_A, POOR) + .addVoteForChoice(CHOICE_B, GOOD) + .addVoteForChoice(CHOICE_C, FAIR) + .addVoteForChoice(CHOICE_D, POOR) + .newVoter("Voter 4", 1.) + .addVoteForChoice(CHOICE_A, FAIR) + .addVoteForChoice(CHOICE_B, POOR) + .addVoteForChoice(CHOICE_C, FAIR) + .addVoteForChoice(CHOICE_D, GOOD) + .newVoter("Voter 5", 1.) + .addVoteForChoice(CHOICE_A, POOR) + .addVoteForChoice(CHOICE_B, POOR) + .addVoteForChoice(CHOICE_C, FAIR) + .addVoteForChoice(CHOICE_D, POOR) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); diff --git a/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategyTest.java b/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategyTest.java index afca95a7..1ec22829 100644 --- a/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategyTest.java +++ b/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategyTest.java @@ -78,20 +78,20 @@ public class NormalVoteCountingStrategyTest { // 3 (a=null b=1 c=1) // Result (a=1 b=2 c=1) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, 1.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -174,20 +174,20 @@ public class NormalVoteCountingStrategyTest { // 2 (a=1 b=1 c=null) // 3 (a=1 b=1 c=null) // Result (a=3 b=2 c=null) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -210,20 +210,20 @@ public class NormalVoteCountingStrategyTest { // 2 (a=1 b=1 c=null) // 3 (a=1 b=1 c=null) // Result (a=3 b=3 c=null) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -245,20 +245,20 @@ public class NormalVoteCountingStrategyTest { // 2 (x1) (a=null b=1 c=null) // 3 (x1) (a=null b=1 c=1) // Result (a=2 b=2 c=1) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 2.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, 1.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -280,20 +280,20 @@ public class NormalVoteCountingStrategyTest { // 2 (x1) (a=null b=1 c=null) // 3 (x3) (a=null b=1 c=1) // Result (a=2 b=4 c=3) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 3.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 2.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 3.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, 1.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); diff --git a/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategyTest.java b/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategyTest.java index 4dc057a7..9f3a2bb7 100644 --- a/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategyTest.java +++ b/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategyTest.java @@ -79,20 +79,20 @@ public class NumberVoteCountingStrategyTest { // 3 (a=7 b=12 c=20) // Result (a=10 b=14 c=23) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 2.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 3.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 7.). - addVoteForChoice(CHOICE_B, 12.). - addVoteForChoice(CHOICE_C, 20.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 2.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 2.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, 3.) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, 7.) + .addVoteForChoice(CHOICE_B, 12.) + .addVoteForChoice(CHOICE_C, 20.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -114,20 +114,20 @@ public class NumberVoteCountingStrategyTest { // 2 (a=1 b=1 c=null) // 3 (a=1 b=1 c=null) // Result (a=3 b=2 c=null) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -137,7 +137,7 @@ public class NumberVoteCountingStrategyTest { .containsExactlyInAnyOrder( ChoiceScore.newScore(CHOICE_A, BigDecimal.valueOf(3.0), 0), ChoiceScore.newScore(CHOICE_B, BigDecimal.valueOf(2.0), 1), - ChoiceScore.newScore(CHOICE_C, null, 2)) + ChoiceScore.newScore(CHOICE_C, BigDecimal.valueOf(0.0), 2)) .isSortedAccordingTo(ChoiceScore::compareTo); } @@ -149,20 +149,20 @@ public class NumberVoteCountingStrategyTest { // 2 (a=1 b=1 c=null) // 3 (a=1 b=1 c=null) // Result (a=3 b=3 c=null) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -172,7 +172,7 @@ public class NumberVoteCountingStrategyTest { .containsExactlyInAnyOrder( ChoiceScore.newScore(CHOICE_A, BigDecimal.valueOf(3.0), 0), ChoiceScore.newScore(CHOICE_B, BigDecimal.valueOf(3.0), 0), - ChoiceScore.newScore(CHOICE_C, null, 1)) + ChoiceScore.newScore(CHOICE_C, BigDecimal.valueOf(0.0), 1)) .isSortedAccordingTo(ChoiceScore::compareTo); } @@ -184,20 +184,20 @@ public class NumberVoteCountingStrategyTest { // 2 (x1) (a=null b=1 c=null) // 3 (x1) (a=null b=1 c=1) // Result (a=2 b=2 c=1) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 2.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, 1.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); @@ -219,20 +219,20 @@ public class NumberVoteCountingStrategyTest { // 2 (x1) (a=null b=1 c=null) // 3 (x3) (a=null b=1 c=1) // Result (a=2 b=4 c=3) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 3.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); + Set<Voter> voters = new SimpleVoterBuilder() + .newVoter("1", 2.) + .addVoteForChoice(CHOICE_A, 1.) + .addVoteForChoice(CHOICE_B, null) + .addVoteForChoice(CHOICE_C, null) + .newVoter("2", 1.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, null) + .newVoter("3", 3.) + .addVoteForChoice(CHOICE_A, null) + .addVoteForChoice(CHOICE_B, 1.) + .addVoteForChoice(CHOICE_C, 1.) + .getVoters(); VoteCountingResult result = strategy.votecount(voters); -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.