我们将收到180篇关于不同主题的文章。每篇文章都有一个或多个标签,表明它的主题是什么:历史,诗歌,艺术,哲学等 这些论文将由15位评论家进行评审。所有评论者都喜欢阅读某些主题,因此他们也有一个或多个标签。
然而,所有这些人都愿意阅读和评论标有主题的论文,这些主题不在他们喜欢的主题列表中。 每篇文章都将由两位评论家阅读。每位评论者将阅读24篇论文。我如何确保论文的分发方式使得每位评论者都有关他/她最喜欢的主题的最大论文数量?
我想我知道算法的第一步,但我如何确保每个评论者的分布最大化关于他们最喜欢的主题的论文数量?
答案 0 :(得分:2)
您可以使用最小成本流量公式解决此问题。
我们的想法是设置一个图表,其中沿着边缘的流表示将文章分配给特定评论者。
边缘具有容量,这意味着沿边缘的最大流量。在这种情况下,容量可用于控制每篇文章需要多少评论,以及每位评论者可以处理的论文数量。
边缘也有重量,允许您为特定组合分配成本。在这种情况下,如果有人正在阅读他们不喜欢的主题,我们可能会花费1。权重可以任意调整,例如如果有人真的不想阅读关于算法的论文。
一旦表示为图表,就会有标准算法来查找最低成本流量。我最喜欢的库是Networkx for Python。
import networkx as nx
reviewers = "An:poetry/art;Bob:poetry;Cindy:art/philosophy".split(';')
essays = "E0:poetry;E1:art;E2:poetry;E3:art/philosophy".split(';')
max_reviews_per_reviewer = 24
max_reviews_per_essay = 2
G = nx.DiGraph()
D = {} # Stores the subjects for each essay
for E in essays:
essay, subjects = E.split(':')
G.add_edge('source',essay,capacity=max_reviews_per_essay,weight=0)
D[essay] = set(subjects.split('/'))
for R in reviewers:
reviewer,subjects = R.split(':')
G.add_edge(reviewer,'sink',capacity=max_reviews_per_reviewer,weight=0)
reviewer_subjects = set(subjects.split('/'))
for essay,essay_subjects in D.items():
if essay_subjects & reviewer_subjects:
G.add_edge(essay,reviewer,capacity=1,weight=0) # Preferred topic
else:
G.add_edge(essay,reviewer,capacity=1,weight=1) # Not on preferred topic
mincostFlow = nx.max_flow_min_cost(G, 'source', 'sink')
for R in reviewers:
reviewer,subjects = R.split(':')
for essay in D:
if mincostFlow[essay][reviewer]>0.5:
print reviewer,essay
此代码打印出作业:
An E1
An E0
An E3
An E2
Bob E0
Bob E2
Cindy E1
Cindy E3