We need peer-reviewed tests! Implements #7pull/9/head
parent
6770108f4c
commit
f40e301d58
@ -0,0 +1,61 @@
|
||||
package fr.mieuxvoter.mj;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.InvalidParameterException;
|
||||
|
||||
public class TallyNormalized extends Tally implements TallyInterface {
|
||||
|
||||
public TallyNormalized(ProposalTallyInterface[] proposalsTallies) {
|
||||
super(proposalsTallies);
|
||||
Integer amountOfProposals = getAmountOfProposals();
|
||||
|
||||
// Compute the Least Common Multiple
|
||||
BigInteger amountOfJudges = BigInteger.ONE;
|
||||
for (ProposalTallyInterface proposalTally : proposalsTallies) {
|
||||
amountOfJudges = lcm(amountOfJudges, proposalTally.getAmountOfJudgments());
|
||||
}
|
||||
|
||||
if (0 == amountOfJudges.compareTo(BigInteger.ZERO)) {
|
||||
throw new InvalidParameterException("Cannot normalize: one or more proposals have no judgments.");
|
||||
}
|
||||
|
||||
// Normalize proposals to the LCM
|
||||
ProposalTally[] normalizedTallies = new ProposalTally[amountOfProposals];
|
||||
for (int i = 0 ; i < amountOfProposals ; i++ ) {
|
||||
ProposalTallyInterface proposalTally = proposalsTallies[i];
|
||||
ProposalTally normalizedTally = new ProposalTally(proposalTally);
|
||||
BigInteger factor = amountOfJudges.divide(proposalTally.getAmountOfJudgments());
|
||||
Integer amountOfGrades = proposalTally.getTally().length;
|
||||
BigInteger[] gradesTallies = normalizedTally.getTally();
|
||||
for (int j = 0 ; j < amountOfGrades; j++ ) {
|
||||
gradesTallies[j] = gradesTallies[j].multiply(factor);
|
||||
}
|
||||
normalizedTallies[i] = normalizedTally;
|
||||
}
|
||||
|
||||
setProposalsTallies(normalizedTallies);
|
||||
setAmountOfJudges(amountOfJudges);
|
||||
}
|
||||
|
||||
/**
|
||||
* Least Common Multiple
|
||||
*
|
||||
* http://en.wikipedia.org/wiki/Least_common_multiple
|
||||
*
|
||||
* lcm( 6, 9 ) = 18
|
||||
* lcm( 4, 9 ) = 36
|
||||
* lcm( 0, 9 ) = 0
|
||||
* lcm( 0, 0 ) = 0
|
||||
*
|
||||
* @author www.java2s.com
|
||||
* @param a first integer
|
||||
* @param b second integer
|
||||
* @return least common multiple of a and b
|
||||
*/
|
||||
public static BigInteger lcm(BigInteger a, BigInteger b) {
|
||||
if (a.signum() == 0 || b.signum() == 0)
|
||||
return BigInteger.ZERO;
|
||||
return a.divide(a.gcd(b)).multiply(b).abs();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue