如何使用固定行/列求和来混洗数组?

时间:2013-01-30 16:27:17

标签: algorithm math random shuffle

我需要为一个班级的学生分配随机论文,但我有以下约束:

  1. 每位学生应分配两篇论文。
  2. 每篇论文应分配给()相同数量的学生。
  3. 是否有优雅方式生成具有此属性的矩阵?即它被洗牌但行和列的总和是不变的?举例说明:

    Student A   1  0  0  1  1  0 |  3
    Student B   1  0  1  0  0  1 |  3
    Student C   0  1  1  0  1  0 |  3
    Student D   0  1  0  1  0  1 |  3
                ---------------- 
                2  2  2  2  2  2
    

    我想过首先用正确的行/列总和构建一个“初始矩阵”,然后先随机置换行,然后是列,但是如何生成这个初始矩阵?这里的问题是我会在(例如)以下备选方案之间做出选择,并且有两个学生分配了相同的论文(在左侧设置中)不会改变行/列改组:< / p>

    INITIAL (MA):            OR (MB):
    A   1  1  1  0  0  0  ||  1  1  1  0  0  0  
    B   1  1  1  0  0  0  ||  0  1  1  1  0  0
    C   0  0  0  1  1  1  ||  0  0  0  1  1  1
    D   0  0  0  1  1  1  ||  1  0  0  0  1  1
    

    我知道我可以提出一些快速/肮脏的东西,并在必要时进行调整,但这似乎是一种有趣的练习。

2 个答案:

答案 0 :(得分:1)

您可以按如下方式生成初始矩阵(伪Python语法):

column_sum = [0] * n_students

for i in range(n_students):
    if column_sum[i] < max_allowed:
        for j in range(i + 1, n_students):
            if column_sum[j] < max_allowed:
                generate_row_with_ones_at(i, j)
                column_sum[i] += 1
                column_sum[j] += 1

                if n_rows == n_wanted:
                    return

这是对所有 n 选择2个不同行的直接迭代,但对列总和的约束尽早实施。

答案 1 :(得分:1)

如果你想进行排列,那么:

  • 随机选择学生,说学生1

  • 对于这名学生,他选择了一份随机论文,比如论文A

  • 随机选择另一名学生

  • 对于这名学生,他选择了一张随机纸,说纸B(不同于A)

  • 将纸B交给学生1,将纸A交给学生2.

这样,您可以保留不同论文的数量和每位学生的论文数量。实际上,两位学生都给了一篇论文并收到一份。此外,没有创建或删除纸张。

就表而言,它意味着找到两对索引(i1,i2)和(j1,j2),使得A(i1,j1)= 1,A(i2,j2)= 1,A(i1, j2)= 0并且A(i2,j1)= 0并且将0s改变1s并且将0s改变为0s =&gt;行和列的总和不会改变。

备注1:如果你不想按排列进行处理,你可以简单地将所有纸张放入一个矢量(放2张纸A,2张纸B,......)。然后,随机改变矢量并将k首先归属于第一个学生,将k个接下来归属于学生2,......但是,您可以以具有多次相同纸张的学生结束。在这种情况下,从外部论文开始做一些排列。