根据排名为学生分配主题

Posted

技术标签:

【中文标题】根据排名为学生分配主题【英文标题】:Assign students to topics based on rankings 【发布时间】:2019-06-14 08:37:45 【问题描述】:

假设我想为 3 名学生分配 3 个主题。允许学生从 1 到 3 对每个主题进行排名。稍后添加:每个主题都不能有超过 2 个学生。

学生可能的作业是以下排列(包括一个主题有三个学生但忽略他们的情况),其中每个是

(学生 1 主题、学生 2 主题、学生 3 主题)

请注意,这三个学生不需要被分配到不同的主题。

n_topics = 3
n_students = 3


per = [el for el in itertools.product(range(n_topics), repeat=n_students)]

我们也有学生排名

rankings = [0:1, 1:3, 2:2, #student 1
        0:3, 1:1, 2:2, #student 2
        0:2, 1:1, 2:3] # ...

因此,将排名作为成本是很自然的。因此,如果学生将某个主题排在第一位并被分配到该主题,他们支付的最低成本为 1。如果他们将某个主题排在第三位并被分配,他们支付的成本为 3。

找到最好的 3 个排列

def get_cost(perm, rankings):
        cost = 0
        for (el, c) in zip(perm, rankings):
                cost += c[el]
        return cost

def get_best_perms(per, rankings):
        perm_cost = 
        for perm in per:
                perm_cost[perm] = get_cost(perm, rankings)
        return sorted(perm_cost.items(), key=operator.itemgetter(1))[0:3]

最好给第一个学生第零个主题,第二个学生第二个主题,以最小化成本。

print(get_best_perms(per, rankings))
#[((0, 1, 1), 3), ((0, 2, 1), 4), ((0, 1, 0), 4)]

但是,实际上,有 13 个学生和 7 个主题,所以 7**13 = 96889010407 个排列(在这种情况下,没有一个主题可以有超过 4 个学生,并且某些主题可能不会被选择)

是否有人对如何并行化此代码有任何建议(要使用的库等)(因为每个成本都可以独立于其他成本计算)?或者一般如何加快速度?

我认为这是一个旅行推销员类型的问题,但是学生和主题太少了,我认为可以尝试尝试所有选项,但我的直觉是这样做可能需要时间事情不是很好。

感谢您的宝贵时间

***如果有更好的地方转发,请告诉我!

【问题讨论】:

乍一看,我认为您的问题可能不像旅行推销员那样是 NP 难的。我建议您首先确定您的问题。如果您需要这方面的帮助,我们需要更准确地描述最佳解决方案的构成要素。 这看起来像是assignment problem 的变体。 添加了更好的问题描述,感谢指点指派问题。 我猜这个问题还有另一个限制。因为如果没有限制为学生分配主题,您可以在线性时间内将每个学生分配到成本最低的主题。一个约束可以是“所有主题都需要分配给一些学生”。在这种情况下,您可以使用Hungarian algorithm 将所有主题匹配到一个学生,然后使用贪心算法。 没有一个主题可以有超过 n 个学生怎么办? 【参考方案1】:

这是一个约束满足问题,与n-queens问题非常相似。我们可以通过迭代算法贪婪地解决这个问题。

将所有学生放在总成本最小的最佳位置(即位置 0)。 当存在冲突时(一个主题被分配给超过 4 名学生),选择其中一名有冲突的学生并将他移动到次优位置。 当没有冲突时,你会得到你的结果。

这种算法可能会给出次优的解决方案,但比回溯要快。

如果您想了解有关算法的更多信息,这里是一个很棒的link

【讨论】:

以上是关于根据排名为学生分配主题的主要内容,如果未能解决你的问题,请参考以下文章

在sql中根据成绩显示学生排名

根据计数对记录集进行分类

等值并列排名(学生成绩排名)

Python操作rabbitmq系列:根据主题分配消息

Mysql分组排名

喜报:悉尼大学项目管理硕士成功案例分享