<p>这是一个使用简单算法的非Pandas解决方案。它从按薪水排序的玩家列表递归地生成组合。这使得它可以跳过生成超过薪资上限的组合。在</p>
<p>正如piRSquared提到的,没有6人的团队在问题中提到的薪水限制之内,所以我选择了限制来产生一小部分团队。在</p>
<pre><code>#!/usr/bin/env python3
''' Limited combinations
Generate combinations of players whose combined salaries fall within given limits
See http://stackoverflow.com/q/38636460/4014959
Written by PM 2Ring 2016.07.28
'''
data = '''\
0 Jason Day 11700
1 Dustin Johnson 11600
2 Rory McIlroy 11400
3 Jordan Spieth 11100
4 Henrik Stenson 10500
5 Phil Mickelson 10200
6 Justin Rose 9800
7 Adam Scott 9600
8 Sergio Garcia 9400
9 Rickie Fowler 9200
'''
data = [s.split() for s in data.splitlines()]
all_players = [(' '.join(u[1:-1]), int(u[-1])) for u in data]
all_players.sort(key=lambda t: t[1])
for i, row in enumerate(all_players):
print(i, row)
print('- '*40)
def choose_teams(free, num, team=(), value=0):
num -= 1
for i, p in enumerate(free):
salary = all_players[p][1]
newvalue = value + salary
if newvalue <= hi:
newteam = team + (p,)
if num == 0:
if newvalue >= lo:
yield newteam, newvalue
else:
yield from choose_teams(free[i+1:], num, newteam, newvalue)
else:
break
#Salary limits
lo, hi = 55000, 60500
#Indices of players that can be chosen for a team
free = tuple(range(len(all_players)))
for i, (t, s) in enumerate(choose_teams(free, 6), 1):
team = [all_players[p] for p in t]
names, sals = zip(*team)
assert sum(sals) == s
print(i, t, names, s)
</code></pre>
<p><strong>输出</strong></p>
^{pr2}$
<hr/>
<p>如果使用的Python旧版本不支持<code>yield from</code>语法,则可以替换它</p>
<pre><code>yield from choose_teams(free[i+1:], num, newteam, newvalue)
</code></pre>
<p>与</p>
<pre><code>for t, v in choose_teams(free[i+1:], num, newteam, newvalue):
yield t, v
</code></pre>