Algorithm 根据选票将人分为若干组
我有一个问题,就是找不到一个算法来对人的数据集进行排序。我试图尽可能详细地解释: 故事以调查开始。一群人,比如说600人可以在20-25个项目中选择。他们许下一个愿望、两个愿望和三个愿望,其中1是他们最想参加的项目,3是“不完美但最可接受的选择” 这些项目的参与者数量有限。每个项目可以加入大约30人(根据人数和项目数量) 该算法将人员放在不同的项目中,并应找到可能的最佳组合 问题是,你不能把所有的人和他们的1号愿望都放在某个项目中,而把其他人也放在2号愿望中,因为这不是每个人最“幸福”的情况 当你想象得到1号愿望的人得到100分,得到2号愿望的人得到60分,得到3号愿望的人得到30分,而没有得到1号愿望的人得到0分时,你可能会想到我的意思。你想得到尽可能多的分数 我希望你明白我的问题。这是一个学校项目日。 有什么可以帮我的吗?你知道吗?我会感谢每一个tippAlgorithm 根据选票将人分为若干组,algorithm,sorting,design-patterns,Algorithm,Sorting,Design Patterns,我有一个问题,就是找不到一个算法来对人的数据集进行排序。我试图尽可能详细地解释: 故事以调查开始。一群人,比如说600人可以在20-25个项目中选择。他们许下一个愿望、两个愿望和三个愿望,其中1是他们最想参加的项目,3是“不完美但最可接受的选择” 这些项目的参与者数量有限。每个项目可以加入大约30人(根据人数和项目数量) 该算法将人员放在不同的项目中,并应找到可能的最佳组合 问题是,你不能把所有的人和他们的1号愿望都放在某个项目中,而把其他人也放在2号愿望中,因为这不是每个人最“幸福”的情况 当
我的算法是这样的:
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
这应该通过数据集进行多次传递,直到所有内容都平衡。如果在一个项目中,随着算法的进展,已经重新分配的人员被一个项目填满,而您又限制了这些人员的重新分配,则此算法可能会导致无休止的循环,因此您可以在没有此限制的情况下尝试此算法。您可以通过将其表述为最小成本网络流问题来优化解决此问题 为每个人添加一个节点,为每个项目添加一个节点 根据个人和项目的偏好设置流程的成本 (由于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
容量字典指定了每个项目可以加入的人数上限。WOW!这太完美了!我对Python或networkx一无所知,但我希望我能处理好这件事,应该不会那么难。还有一个问题。我还可以为一个项目设置最小人数吗?当然,您只需为一个项目设置需求,例如,为Project1设置至少10个add g.add_节点(“Project1”,demand=10),并将dest的需求减少10以匹配。