通义千问的介绍:
最大余额方法(Largest Remainder Method,也称为汉米尔顿方法)是一种在比例代表制投票制度下用于分配议席的方法。这种方法旨在根据各政党或候选名单所获得的选票数来公平地分配议席。以下是该方法的具体步骤和解释:
其中:⌊⌋表示Math.floor()
这里是实例,可能看完还是有点懵,我也是一样,但是看完这个,再去理解下代码就懂了。
看余额,如果剩余有2个,那就给C和B各一个。
然后是怎么和占比转换,我的理解就是占比就是你的上议席。
代码:用的Decimal库
/**
* 使用最大余额法计算百分比:确保和为百分之100
* @param arr 数组
* @param sum 总和
* @param curIndx 当前要计算的下标
* @param precision 小数精度
*/
function getPercentValue(
arr: number[] = [],
sum = 0,
curIndx = 0,
precision = 2
) {
if (!(arr.length > 0)) {
// 确保为数组以及长度大于0
return 0;
}
if (sum <= 0) {
// 求和
sum = arr.reduce((a, b) => new Decimal(a).add(b).toNumber(), 0);
}
// 计算需要确定的位数,这里假如是2位小数,则precision为2
let digits = Math.pow(10, precision);
// 计算投票数也就是占比(席位)
let setaArr = arr.map(item => {
return new Decimal(item).dividedBy(sum).mul(100).mul(digits).toNumber();
});
// 这里是最终的席位,原来就是100
let sumSeta = digits * 100;
// 向下取值,获取具体席位
let setaArr2 = setaArr.map(item => {
return Math.floor(item);
});
// 计算剩余席位
let diff =
sumSeta - setaArr2.reduce((a, b) => new Decimal(a).add(b).toNumber(), 0);
if (diff > 0) {
// 用席位-最终席位,找到余值
let diffArr = setaArr.map((item, index) => {
return new Decimal(item).sub(setaArr2[index]).toNumber();
});
while (diff > 0) {
// 拿到最大值的下标
let maxIndex = 0;
diffArr.find((item, index) => {
if (new Decimal(item).eq(Decimal.max(...diffArr).toNumber())) {
maxIndex = index;
return true;
}
return false;
});
// 找到最大值,并加1
setaArr2[maxIndex]++;
// 赋值为0,下次不能参与了,已经进一了
diffArr[maxIndex] = 0;
// 减去1
diff--;
}
}
return new Decimal(setaArr2[curIndx]).dividedBy(100).toNumber();
}