3

我需要将随机论文分配给班级的学生,但我有以下限制:

  1. 每个学生应分配两篇论文。
  2. 每篇论文应分配给(大约)相同数量的学生。

有没有一种优雅的方法来生成具有此属性的矩阵?即它是洗牌的,但行和列的总和是恒定的?举例说明:

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

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

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

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

4

2 回答 2

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 个不同行的直接迭代,但尽可能早地强制执行对列总和的约束。

于 2013-01-30T16:39:10.820 回答
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 并将 0 更改为 1,将 1 更改为 0 => 行和列的总和不会改变。

备注1:如果您不想通过排列进行,您可以简单地将所有纸张放入一个向量(放入2次纸张A,2次纸张B,......)。然后,随机打乱向量并将 k 首先归因于第一个学生,接下来的 k 个归因于学生 2,......但是,您可以以一个学生有多次相同的论文结束。在这种情况下,从姓氏文件开始进行一些排列。

于 2013-01-30T20:09:06.150 回答