我有不同规模的志愿者团体(从5人到250人),需要与志愿者站点配对,以请求各种数量的志愿者(从3人到400人)。我需要将志愿者组与志愿者站点配对,在需要时将志愿者组拆分,并在必要时将多个志愿者组与单个志愿者站点配对。但是,我想最大程度地减少分裂。是否有一种算法可以最佳地配对这些?这是否属于已知的具有Wikipedia页面的计算机科学问题类型?任何建议表示赞赏!
答案 0 :(得分:1)
此问题可以解释为运输问题的变体。考虑具有源节点(志愿者组,用i
表示)和目标节点(志愿者站点,用j
表示)的二部图。让我们假设志愿者总数等于或大于站点的总需求。然后的目标是使来自i → j
的已使用链接的数量最少。
此问题可以公式化为混合整数规划模型,并可以使用现成的MIP求解器解决。该模型如下所示:
项目 x up i,j 表示 x i,j < / em>。
让我们生成一些随机数据:
---- 18 PARAMETER size volunteers in group
group1 47, group2 212, group3 140, group4 79, group5 76, group6 60, group7 91
group8 215, group9 21, group10 128, group11 250, group12 147
---- 18 PARAMETER request needed by site
site1 397, site2 306, site3 55, site4 257, site5 66
---- 18 PARAMETER numvolunteer = 1466 total volunteers
PARAMETER numrequest = 1081 total requests
将这些数据输入我们的模型时,我们得到以下结果:
---- 44 VARIABLE y.L link used
site1 site2 site3 site4 site5
group2 1
group3 1
group4 1
group5 1
group8 1
group10 1
group11 1
group12 1
---- 44 VARIABLE x.L flow
site1 site2 site3 site4 site5
group2 91
group3 140
group4 66
group5 55
group8 215
group10 117
group11 250
group12 147
答案 1 :(得分:0)
关于您要优化的内容,我将需要更多详细信息,但是这里有一个解决方案可以帮助您完成。
您可能需要考虑的事情:
首先,创建两个字典,志愿者组(使用组号或名称的键,并以所需的数字作为值)和志愿者需要(使用组号或名称的键,并以所需的数字作为值) 。使用集合对字典进行排序。
import collections
volunteerGroups = collections.OrderedDict(sorted(volunteerGroups.items()))
volunteersNeeded = collections.OrderedDict(sorted(volunteersNeeded.items()))
为匹配项创建字典:
volunteerMatches = {}
接下来,首先要找到适合需要的最少数量的志愿者。
for v in volunteersNeeded.keys():
matches = False
for v2 in volunteerGroup.keys():
if volunteerGroup[v2]>=volunteersNeeded[v]:
volunteerMatches[v] = v2 #dictionary entry matching group to assignment
#remove matched groups
del volunteerGroup[v2]
del volunteerGroup[v]
#Now match any groups that couldn't fit 1 to 1
for v in volunteersNeeded.keys():
matched = false
vg = volunteerGroups.keys()
volunteerMatches[v] = []
while matched == false and len(vg)>0:
for v2 in volunteerGroups.keys():
if volunteersNeeded[v]>0:
volunteersNeeded[v] = volunteersNeeded[v]-volunteerGroups[v2]
volunteerMatches[v].append(volunteerGroups[v2])
del volunteerGroups[v2] #delete the group that was added to this project
#once you finish a group, you can move on
if volunteersNeeded[v]<=0:
matched = true
break
#print out all the matches
for match in volunteerMatches.keys():
print(volunteerMatches[match])