您可以通过将其表述为最小成本网络流问题来优化解决此问题。
为每个人添加一个节点,为每个项目添加一个。
根据个人和项目的偏好设置流程成本。
(由于 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。
容量字典指定了每个项目可以加入的人数上限。