Algorithm 等计数随机对

Algorithm 等计数随机对,algorithm,Algorithm,我正在编写一些代码,允许评估员评估某些东西(含糊不清,对吧?)。在进行评估之前,需要对提交的项目进行随机抽样。那部分相当简单 困扰我的部分是要求每个项目需要由两名不同的评估员进行评估,我们希望每个评估员执行的评估的最终数量尽可能均匀分布 示例:如果我有10个项目,那么总共应该有20个评估(每个项目2个评估)。20项评估除以4名评估员,得出每个评估员5项评估。显然,这些数字并不总是如此清晰(每个评估员11个项目的结果仍然是5个,剩下的两个在每个人都平衡后分配到顶部) 只是想在这里找到一些算法帮助。

我正在编写一些代码,允许评估员评估某些东西(含糊不清,对吧?)。在进行评估之前,需要对提交的项目进行随机抽样。那部分相当简单

困扰我的部分是要求每个项目需要由两名不同的评估员进行评估,我们希望每个评估员执行的评估的最终数量尽可能均匀分布

示例:如果我有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