根据排名为学生分配主题

时间:2019-01-20 22:59:44

标签: python algorithm traveling-salesman

假设我想将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个学生,并且某些主题可能不会被选择)

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

我认为这是一个旅行推销员式的问题,但是我认为可能有机会尝试所有选项的学生和主题很少,但我的直觉认为这样做可能会花费一些时间事情不是很好。

谢谢您的时间

***如果有更好的转发位置,请告诉我!

1 个答案:

答案 0 :(得分:0)

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

  • 将所有学生置于最佳位置,以使总体成本(位于位置0)降到最低。
  • 当有冲突时(一个主题分配给4个以上的学生),请选择一个有冲突的学生,然后将他移动到次优的位置。
  • 没有冲突时,您会得到结果。

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

如果您想了解有关算法的更多信息,那么link真好