You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何生成符合位置与预算要求的15人足球球员组合?

Fantasy Premier League 15人合规组合生成方案

问题1:价格与球员关联错误的解决

你之前把球员的各个字段拆成独立数组(id、first_name等),导致后续无法将价格和对应球员正确绑定。正确做法是保留每个球员的完整数据对象,不要拆分字段:

  • 直接从API返回的elements中提取每个球员的所需字段,计算好转换后的价格,将每个球员封装为一个哈希,让所有属性绑定在一起。
  • 避免单独处理price数组,而是在球员对象里直接存储转换后的价格值。

问题2:多位置组合合并的解决

Ruby的Array#product方法支持任意数量的数组参数,完全可以用来合并四个位置的组合数组。通过forward_combo.product(midfielder_combo, defender_combo, goalkeeper_combo)就能生成所有位置组合的笛卡尔积,之后再筛选总价格符合预算的组合。

修正后的完整代码

def index
  require 'net/http'
  require 'json'
  url = 'https://fantasy.premierleague.com/api/bootstrap-static/'
  uri = URI(url)
  response = Net::HTTP.get(uri)
  data = JSON.parse(response)
  elements = data["elements"]

  # 预算上限
  budget = 100.0

  # 1. 处理球员数据:封装为包含所需字段的哈希,直接计算转换后的价格
  players = elements.map do |elem|
    {
      id: elem["id"],
      first_name: elem["first_name"],
      second_name: elem["second_name"],
      position: elem["element_type"],
      price: elem["now_cost"] / 10.to_f,
      total_points: elem["total_points"]
    }
  end

  # 2. 按位置分组
  goalkeepers = players.select { |p| p[:position] == 1 }
  defenders = players.select { |p| p[:position] == 2 }
  midfielders = players.select { |p| p[:position] == 3 }
  forwards = players.select { |p| p[:position] == 4 }

  # 3. 生成各位置符合人数要求的组合
  gk_combos = goalkeepers.combination(2).to_a
  def_combos = defenders.combination(5).to_a
  mid_combos = midfielders.combination(5).to_a
  fw_combos = forwards.combination(3).to_a

  # 4. 合并所有位置组合,并筛选符合预算的组合
  valid_teams = fw_combos.product(mid_combos, def_combos, gk_combos).select do |fw_group, mid_group, def_group, gk_group|
    # 计算当前组合的总价格
    total_price = fw_group.sum { |p| p[:price] } + 
                  mid_group.sum { |p| p[:price] } + 
                  def_group.sum { |p| p[:price] } + 
                  gk_group.sum { |p| p[:price] }
    total_price <= budget
  end

  # 可选:输出结果示例,比如第一个合规组合的球员信息和总价格
  if valid_teams.any?
    sample_team = valid_teams.first
    total_price = sample_team.flatten.sum { |p| p[:price] }
    puts "示例合规组合(总价格:#{total_price.round(1)}):"
    sample_team.each_with_index do |group, idx|
      position_names = ["门将", "后卫", "中场", "前锋"]
      puts "#{position_names[idx]}:"
      group.each { |p| puts "  #{p[:first_name]} #{p[:second_name]} - #{p[:price]} 分 - #{p[:total_points]} 点" }
    end
  else
    puts "没有找到符合预算的15人组合"
  end

  valid_teams
end

关键代码说明

  • 球员数据封装:通过map将每个API返回的球员对象转换为精简哈希,包含所有需要的字段,价格直接转换为小数存储,彻底避免关联错误。
  • 组合合并:使用product方法一次性合并四个位置的组合数组,得到所有可能的15人组合。
  • 预算筛选:对每个组合计算总价格,只保留总价格≤100的组合。
  • 性能提示:由于组合数量可能非常庞大(比如前锋组合可能有成千上万种),实际运行时可以提前过滤掉价格过高的球员,或者使用更高效的算法减少计算量。

内容的提问来源于stack exchange,提问作者ldthompson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 06:05:55