Algorithm 等计数随机对
我正在编写一些代码,允许评估员评估某些东西(含糊不清,对吧?)。在进行评估之前,需要对提交的项目进行随机抽样。那部分相当简单 困扰我的部分是要求每个项目需要由两名不同的评估员进行评估,我们希望每个评估员执行的评估的最终数量尽可能均匀分布 示例:如果我有10个项目,那么总共应该有20个评估(每个项目2个评估)。20项评估除以4名评估员,得出每个评估员5项评估。显然,这些数字并不总是如此清晰(每个评估员11个项目的结果仍然是5个,剩下的两个在每个人都平衡后分配到顶部)Algorithm 等计数随机对,algorithm,Algorithm,我正在编写一些代码,允许评估员评估某些东西(含糊不清,对吧?)。在进行评估之前,需要对提交的项目进行随机抽样。那部分相当简单 困扰我的部分是要求每个项目需要由两名不同的评估员进行评估,我们希望每个评估员执行的评估的最终数量尽可能均匀分布 示例:如果我有10个项目,那么总共应该有20个评估(每个项目2个评估)。20项评估除以4名评估员,得出每个评估员5项评估。显然,这些数字并不总是如此清晰(每个评估员11个项目的结果仍然是5个,剩下的两个在每个人都平衡后分配到顶部) 只是想在这里找到一些算法帮助。
只是想在这里找到一些算法帮助。我能得到的最接近的结果是比我希望的更像钟形曲线。对我来说,似乎需要在M名评估员之间分配N个项目的2N个评估,以便每个评估员都能得到与其份额相等或尽可能接近的结果 有一个身份:
2N = ceil(2N/M) + ceil((2N-1)/M) + ... + ceil((2N-M+1)/M)
可用于此目的ceil
这里是最接近的非较小整数:ceil(2.3)=3,ceil(4)=4
例如,11个项目中有22个=5+5+4+4+4
它是如何工作的?请参阅Knuth,Patashnik&Graham的《具体数学》,第3章,第4部分进行解释:)
我对Anttis的方法和“具体数学”中描述的方法进行了编码:
publicstaticvoidmain(字符串[]args){
第一条(5,7);
System.out.println(“=======”);
第二条(5,7);
}
私人静态无效方式一(内部评估员、内部项目){
整数评估[][]=新整数[2][项];
int评估员=0;
对于(int pass=0;pass<2;pass++){
对于(int item=0;item0){
int batch=(int)Math.ceil((2.0*项目-步骤)/评估员);
评估-=批次;
对于(int i=prevBatch;i
如果我是正确的,第二种方法将提供更多期望的输出。例如,尝试7个项目和5个评估员。或11项和4名评估员
更新在我修复了Antti指出的错误之后,两个例程给出了相同的结果。这并不难。假设您有一个访问器和一个项目。只需运行以下循环(所有内容都是基于零的索引):
a=0
对于0,是的,但在我的算法的实现中存在错误。您在两次通过之间重置了评估员索引,导致了完全不同的算法,而且性能肯定会更差!分配评估器=0在我的代码中的循环传递之外!:)它在迭代结束之前就已经存在了。难怪你会得到不好的结果。算法中仍然有一个错误:)在行,而(assessments[pass][item]!=null)
你需要检查所有过程,而不仅仅是pass的当前值。
public static void main(String[] args) {
wayOne(5, 7);
System.out.println("======");
wayTwo(5, 7);
}
private static void wayOne(int assessors, int items) {
Integer assessments[][] = new Integer[2][items];
int assessor = 0;
for (int pass = 0; pass < 2; pass++) {
for (int item = 0; item < items; item++) {
while (assessments[pass][item] != null)
assessor = (assessor + 1) % assessors;
assessments[pass][item] = assessor;
assessor = (assessor + 1) % assessors;
}
}
for (int pass = 0; pass < assessments.length; pass++) {
for (int item = 0; item < assessments[pass].length; item++)
System.out.println("Pass " + pass + " item " + item + " is assessed by " + assessments[pass][item]);
}
}
private static void wayTwo(int assessors, int items) {
Integer distribution[][] = new Integer[2][items];
int assessments = 2 * items;
int step = 0, prevBatch = 0;
while (assessments > 0) {
int batch = (int) Math.ceil(( 2.0 * items - step) / assessors);
assessments -= batch;
for (int i = prevBatch; i < batch + prevBatch; i++) {
distribution[i / items][i % items] = i % assessors;
}
prevBatch += batch;
step++;
}
for (int pass = 0; pass < distribution.length; pass++) {
for (int item = 0; item < distribution[pass].length; item++)
System.out.println("Pass " + pass + " item " + item + " is assessed by " + distribution[pass][item]);
}
}
a = 0
for 0 <= r < 2:
for 0 <= i < I:
while (assessor a is already assessing item i):
a = (a + 1) mod A
assessor a will assess item i on round r
a = (a + 1) mod A