如何在Python中动态生成符合薪资限制的6人高尔夫球手阵容
动态高尔夫球手阵容选择最优实现方案
需求概述
将原有固定选取2名Tier1 + 4名Tier2的逻辑,扩展为两种合法组合模式:
- 模式1:2名Tier1 + 4名Tier2
- 模式2:3名Tier1 + 3名Tier2
总人数始终为6人,同时需满足总薪资在49700-50000区间内。
原有代码参考
import itertools import csv def load_golfers(csv_path): tier1 = [] tier2 = [] with open(csv_path, 'r') as f: reader = csv.DictReader(f) for row in reader: golfer = { 'name': row['Name'], 'salary': int(row['Salary']), 'tier': row['Tier'] } if golfer['tier'] == '1': tier1.append(golfer) elif golfer['tier'] == '2': tier2.append(golfer) return tier1, tier2 def find_valid_lineups(tier1, tier2): valid_lineups = [] # 原有固定逻辑:2名tier1,4名tier2 for t1_comb in itertools.combinations(tier1, 2): t1_salary = sum(g['salary'] for g in t1_comb) if t1_salary > 50000: continue # 提前过滤,减少后续计算 for t2_comb in itertools.combinations(tier2, 4): total_salary = t1_salary + sum(g['salary'] for g in t2_comb) if 49700 <= total_salary <= 50000: valid_lineups.append({ 'tier1': [g['name'] for g in t1_comb], 'tier2': [g['name'] for g in t2_comb], 'total_salary': total_salary }) return valid_lineups if __name__ == '__main__': tier1, tier2 = load_golfers('golfers.csv') lineups = find_valid_lineups(tier1, tier2) for idx, lineup in enumerate(lineups, 1): print(f"阵容 {idx}:") print(f"Tier1球手: {', '.join(lineup['tier1'])}") print(f"Tier2球手: {', '.join(lineup['tier2'])}") print(f"总薪资: {lineup['total_salary']}\n")
优化后的实现方案
核心思路
覆盖两种合法组合模式,同时通过提前过滤和精准范围匹配提升运行效率,避免不必要的组合遍历:
import itertools import csv def load_golfers(csv_path): tier1 = [] tier2 = [] with open(csv_path, 'r') as f: reader = csv.DictReader(f) for row in reader: golfer = { 'name': row['Name'], 'salary': int(row['Salary']), 'tier': row['Tier'] } if golfer['tier'] == '1': tier1.append(golfer) elif golfer['tier'] == '2': tier2.append(golfer) return tier1, tier2 def find_valid_lineups(tier1, tier2): valid_lineups = [] # 模式1:2名Tier1 + 4名Tier2 for t1_comb in itertools.combinations(tier1, 2): t1_salary = sum(g['salary'] for g in t1_comb) if t1_salary > 50000: continue # 提前过滤超薪资上限的组合 # 计算Tier2所需的薪资区间 t2_min = max(49700 - t1_salary, 0) t2_max = 50000 - t1_salary for t2_comb in itertools.combinations(tier2, 4): t2_salary = sum(g['salary'] for g in t2_comb) if t2_min <= t2_salary <= t2_max: valid_lineups.append({ 'tier1_count': 2, 'tier2_count': 4, 'tier1': [g['name'] for g in t1_comb], 'tier2': [g['name'] for g in t2_comb], 'total_salary': t1_salary + t2_salary }) # 模式2:3名Tier1 + 3名Tier2 for t1_comb in itertools.combinations(tier1, 3): t1_salary = sum(g['salary'] for g in t1_comb) if t1_salary > 50000: continue t2_min = max(49700 - t1_salary, 0) t2_max = 50000 - t1_salary for t2_comb in itertools.combinations(tier2, 3): t2_salary = sum(g['salary'] for g in t2_comb) if t2_min <= t2_salary <= t2_max: valid_lineups.append({ 'tier1_count': 3, 'tier2_count': 3, 'tier1': [g['name'] for g in t1_comb], 'tier2': [g['name'] for g in t2_comb], 'total_salary': t1_salary + t2_salary }) # 可选:按总薪资降序排序,优先展示接近50000的阵容 valid_lineups.sort(key=lambda x: x['total_salary'], reverse=True) return valid_lineups if __name__ == '__main__': tier1, tier2 = load_golfers('golfers.csv') lineups = find_valid_lineups(tier1, tier2) if not lineups: print("未找到符合条件的阵容") else: for idx, lineup in enumerate(lineups, 1): print(f"阵容 {idx} (Tier1:{lineup['tier1_count']}人 | Tier2:{lineup['tier2_count']}人):") print(f"Tier1球手: {', '.join(lineup['tier1'])}") print(f"Tier2球手: {', '.join(lineup['tier2'])}") print(f"总薪资: {lineup['total_salary']}\n")
性能优化点
- 提前过滤:计算完Tier1组合薪资后,若已超过50000,直接跳过后续Tier2组合遍历
- 精准范围匹配:计算Tier2所需的薪资区间,避免无意义的全量判断
- 结果排序:可选按总薪资降序,优先展示更接近薪资上限的最优阵容
CSV数据示例 (golfers.csv)
Name,Salary,Tier Player A,10500,1 Player B,10200,1 Player C,9800,1 Player D,9500,1 Player E,7200,2 Player F,7000,2 Player G,6800,2 Player H,6700,2 Player I,6600,2 Player J,6500,2
内容的提问来源于stack exchange,提问作者BruceyBandit
相关产品推荐
相关产品推荐

