具有相同计数的随机配对

时间:2011-04-18 18:37:28

标签: algorithm

我正在研究一些允许评估员评估某些内容的代码(模糊,对吧?)。在评估可能发生之前,需要对提交的项目进行随机抽样。那部分很简单。

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

示例:如果我有10个项目,则应该进行20个评估(每个项目2个评估)。每个评估员进行20次评估,由4名评估员进行评估。显然,这些数字并不会总是如此干净(每个评估员仍会有11个项目,其余两个在每个人都已经平衡之后被分配到顶部)。

在这里寻找一些算法帮助。我能得到的最接近的曲线比我想要的更多。

2 个答案:

答案 0 :(得分:2)

这并不困难。假设你有一个存取器和我的物品。只需运行以下循环(一切都是从零开始索引):

 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

这将简单地以循环方式分配评估员,但会跳过同一评估员两次评估同一项目的情况。

答案 1 :(得分:1)

对我而言,您似乎需要在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&amp; amp;的“具体数学”。格雷厄姆,第3章,第4部分的解释:)

我编写了Anttis的方法和“具体数学”中描述的方法:

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]);
    }
}

如果我是正确的,第二种方式会提供更多所需的输出。例如,尝试7个项目和5个评估员。或11个项目和4个评估员。

更新我修复了Antti指出的bug后,两个例程给出了相同的结果。