假设我想给三个学生分配三个主题学生们可以对每个题目从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个学生,有些主题可能无法选择)
有人对如何并行化这段代码有什么建议(要使用的库等)(因为每个成本都可以独立于其他成本计算)?或者一般来说如何加速?
我认为这是一个旅行推销员类型的问题,但学生和主题太少了,我认为可能尝试所有的选择,但我的直觉可能需要时间来做这种事情不是很好。
谢谢你抽出时间
如果有更好的地方可以转载,请告诉我!
最佳答案
这是一个约束满足问题,与n皇后问题非常相似,我们可以通过迭代算法来贪婪地求解。
把所有的学生放在最佳的位置,这样可以最大限度地降低总成本(即在0位置)。
当有冲突时(一个主题被分配给4个以上的学生),从冲突的学生中挑选一个并将其移动到次优位置。
当没有冲突时,你就会得到你的结果。
该算法可以给出次优解,但速度比回溯算法快。
如果你想了解更多关于算法的知识,这里有一个很棒的link
关于python - 根据排名为学生分配主题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54281776/