您可以通过将其作为最小成本网络流量问题进行优化来解决此问题。
为每个人添加一个节点,并为每个项目添加一个节点。
根据自己的喜好设置人与项目之间的流量成本。
(作为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。
容量字典指定有多少人可以加入每个项目的上限。
哇!太棒了! 我不知道Python或networkx,但我希望我能处理这个,应该不那么难。还有一个问题。我是否也可以为项目设置最少人数? – Jannik
当然,您只需设置项目的需求,例如对于Project1至少有10个添加G.add_node('Project1',需求= 10),并减少dest的需求10匹配。 –