将特定规模的志愿者群体与要求特定数量的志愿者的志愿者站点进行最佳匹配的算法?

时间:2019-01-25 19:08:36

标签: python algorithm optimization

我有不同规模的志愿者团体(从5人到250人),需要与志愿者站点配对,以请求各种数量的志愿者(从3人到400人)。我需要将志愿者组与志愿者站点配对,在需要时将志愿者组拆分,并在必要时将多个志愿者组与单个志愿者站点配对。但是,我想最大程度地减少分裂。是否有一种算法可以最佳地配对这些?这是否属于已知的具有Wikipedia页面的计算机科学问题类型?任何建议表示赞赏!

2 个答案:

答案 0 :(得分:1)

此问题可以解释为运输问题的变体。考虑具有源节点(志愿者组,用i表示)和目标节点(志愿者站点,用j表示)的二部图。让我们假设志愿者总数等于或大于站点的总需求。然后的目标是使来自i → j的已使用链接的数量最少。

此问题可以公式化为混合整数规划模型,并可以使用现成的MIP求解器解决。该模型如下所示:

enter image description here

项目 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)

关于您要优化的内容,我将需要更多详细信息,但是这里有一个解决方案可以帮助您完成。

您可能需要考虑的事情:

  1. 您要分配最大人数还是最大组数?我的算法旨在最大化匹配组的数量。
  2. 您仍然要匹配不完整的组吗?我的算法可能会创建1个不完整的志愿者比赛,但我认为还是值得的,然后您可以稍后进行填写。

首先,创建两个字典,志愿者组(使用组号或名称的键,并以所需的数字作为值)和志愿者需要(使用组号或名称的键,并以所需的数字作为值) 。使用集合对字典进行排序。

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])