假设我想将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个学生,并且某些主题可能不会被选择)
是否有人对如何并行化此代码有任何建议(要使用的库等)(因为每种成本可以独立于其他成本进行计算)?还是一般如何加快速度?
我认为这是一个旅行推销员式的问题,但是我认为可能有机会尝试所有选项的学生和主题很少,但我的直觉认为这样做可能会花费一些时间事情不是很好。
谢谢您的时间
***如果有更好的转发位置,请告诉我!
答案 0 :(得分:0)
这是一个约束满足问题,与n皇后问题非常相似。我们可以通过应用迭代算法来贪婪地解决这个问题。
该算法可能给出次优的解决方案,但比回溯要快。
如果您想了解有关算法的更多信息,那么link真好