小编典典

根据投票将人分类

algorithm

我在寻找一种对人员数据集进行排序的算法时遇到了问题。我尝试解释的尽可能详细:

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

这些项目的参与者人数有限。每个项目可以加入约30人(基于人数和项目数)。

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

问题是您不能只将所有拥有1个愿望X的人放在某个项目中,而将所有其他拥有1个愿望X的人都放在那个项目2个愿望中,因为那不是最“最快乐”的情况为所有人。

您可能会想到我的意思,当您想象每个获得1号愿望的人得到100点,获得2号愿望的人得到60点,3号愿望得到30点而没有得到其中一个愿望的每个人0分
而您想获得尽可能多的积分。

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

亲切的问候


阅读 284

收藏
2020-07-28

共1个答案

小编典典

您可以通过将其公式化为最低成本的网络流量问题来最佳地解决此问题。

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

根据人员和项目的偏好设置成本。

(由于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。

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

2020-07-28