基于投票将人们分组

时间:2014-01-23 19:08:14

标签: algorithm sorting design-patterns

我在查找用于对人员数据集进行排序的算法时遇到问题。我试着尽可能详细地解释:

故事始于一项调查。一堆人,可以说600可以选择20-25个项目。他们提出了#1愿望,#2愿望和#3愿望,其中#1是他们想要参与的最想要的项目,并希望3“不完美但最可接受的选择”。

这些项目的参与人数有限。每个项目可以加入约30人(根据人数和项目数量)。

该算法将人们置于不同的项目中,并应找到最佳组合。

问题在于,你不能只把所有人在第一个项目中放入他们的号码1愿望X,并且在第2号愿望中将所有其他人的号码1愿望X放在一起,因为那不是最“最幸福的“每个人的情况。

你可以想到我的意思当你想象每个得到1号希望的人都会得到100分,因为每个得到他的2号希望得到60分,3号希望得到30分而没有得到1分的人他的愿望0分。并且你想获得尽可能多的积分。

我希望你能解决我的问题。这是一个学校项目日。 有什么东西可以帮助我吗?你有什么主意吗?我会感激每一个tipp !!

亲切的问候

2 个答案:

答案 0 :(得分:4)

您可以通过将其制定为最低成本网络流量问题来优化解决此问题。

为每个人添加一个节点,为每个项目添加一个节点。

根据个人喜好设置个人与项目之间的流量成本。

(由于Networkx提供最低成本流量,但不是最大成本流量,我设定了成本 负。)

例如,使用Networkx和Python:

import networkx as nx

G=nx.DiGraph()

prefs={'Tom':['Project1','Project2','Project3'],
       'Dick':['Project2','Project1','Project3'],
       'Harry':['Project1','Project3','Project1']}

capacities={'Project1':2,'Project2':10,'Project3':4}

num_persons=len(prefs)
G.add_node('dest',demand=num_persons)
A=[]
for person,projectlist in prefs.items():
    G.add_node(person,demand=-1)
    for i,project in enumerate(projectlist):
        if i==0:
            cost=-100 # happy to assign first choices
        elif i==1:
            cost=-60 # slightly unhappy to assign second choices
        else:
            cost=-30 # very unhappy to assign third choices
        G.add_edge(person,project,capacity=1,weight=cost) # Edge taken if person does this project

for project,c in capacities.items():
        G.add_edge(project,'dest',capacity=c,weight=0)

flowdict = nx.min_cost_flow(G)
for person in prefs:
    for project,flow in flowdict[person].items():
        if flow:
            print person,'joins',project

在这段代码中,Tom的第一个选择是Project1,然后是Project2,然后是Project3。

容量字典指定了每个项目可以加入的人数的上限。

答案 1 :(得分:0)

我的算法是这样的:

mainloop
 wishlevel = 1
  loop
   Distribute people into all projects according to wishlevel wish
   loop through projects, counting population
    If population exceeds maximum
     Distribute excess non-redistributed people into their wishlevel+1 projects that are under-populated
     tag distributed people as 'redistributed' to avoid moving again
    endif
   endloop
  wishlevel = wishlevel + 1
 loop until wishlevel == 3    
mainloop until no project exceeds max population

这应该在数据集中进行多次传递,直到所有内容均匀。如果在一个项目填满算法进展的人员的情况下限制已经重新分配的人的重新分配,则该算法可能导致无限循环,因此您可以在没有该限制的情况下尝试它。