简介
在使用 Echarts 可视化数据的时候,往往饼图中每块占比加和不等于100%,所以就有了最大余额法。下面是最大余额法的简介:
最大余额方法(英语:largest remainder method)又称数额制、汉弥尔顿法(英语:Hamilton method),是比例代表制投票制度下,一种议席分配的方法,相对于最高均数方法。
这个方法要求候选人透过名单形式参选。每个名单上的候选人数不能超过该选区的议席数。候选人在名单上是有排名顺序的。选民投票时,是投给整个名单,而不是单个候选人。
投票结束后,会用一个特定的“数额”(见下)去除所有有效票数。每个名单如果得票数达到这个数额的整数倍,就可以获得相应数量的议席。名单上的候选人按照名单上的排名顺序获得议席。
如果还有剩余的议席没分配完,就会看每个名单超过上一轮数额整数倍的票数(即“余额”)。这些剩余议席会根据各名单的余额大小顺序分配,所以这种方法叫做“最大余额法”。
https://www.cnblogs.com/CoderSilence/p/16775866.html
算法实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| package com.github.problem;
import java.util.Arrays;
public class LargestRemainderMethod { public static void main(String[] args) { int[] arr = {1, 4, 6, 8, 10, 88}; System.out.println(Arrays.toString(getPercentValue(arr, 2))); }
public static double getPercentValue(int[] arr, int idx, int precision) { if ((arr.length - 1) < idx) { return 0; } double sum = 0; for (int j : arr) { sum += j; } if (sum == 0) { return 0; } double digits = Math.pow(10, precision); double[] votesPerQuota = new double[arr.length]; for (int i = 0; i < arr.length; i++) { double val = arr[i] / sum * digits * 100; votesPerQuota[i] = val; } double targetSeats = digits * 100; double[] seats = new double[arr.length]; for (int i = 0; i < votesPerQuota.length; i++) { seats[i] = Math.floor(votesPerQuota[i]); } double currentSum = 0; for (double seat : seats) { currentSum += seat; } double[] remainder = new double[arr.length]; for (int i = 0; i < seats.length; i++) { remainder[i] = votesPerQuota[i] - seats[i]; } while (currentSum < targetSeats) { double max = 0; int maxId = 0; for (int i = 0; i < remainder.length; ++i) { if (remainder[i] > max) { max = remainder[i]; maxId = i; } } ++seats[maxId]; remainder[maxId] = 0; ++currentSum; } return seats[idx] / digits; }
public static double[] getPercentValue(int[] arr, int precision) { double[] result = new double[arr.length]; for (int i = 0; i < arr.length; i++) { result[i] = getPercentValue(arr, i, precision); } return result; } }
|
结果
1
| [0.85, 3.42, 5.13, 6.84, 8.55, 75.21]
|
完~