基于规则的最佳组合

时间:2018-07-25 16:03:38

标签: ruby algorithm

在符合条件的情况下,五个条目的哪个组合组合得分最高?

2 个答案:

答案 0 :(得分:3)

如果数据集不是很大,那么您就可以去做(可能效率很低):

<video>

答案 1 :(得分:1)

代码

def best_five(players, max_elo)
  players.combination(5).with_object({ names:[], tot_scores: -1 }) do |arr, best|
    names, elos, scores = arr.map(&:values).transpose
    best.replace({ names: names, tot_scores: scores.sum }) unless
      elos.sum > max_elo || scores.sum <= best[:tot_scores]
  end
end

这里players是一个哈希数组,每个哈希都有键:name:eloscore,其中:name的值是一个字符串和值另外两个键是整数。

示例

players =<<_
Derek Aufderhar, 2134, 1
Hadley Kuhn, 2044, 0
Myrtie Lueilwitz, 2207, 2
Mitchell Schiller, 2036, 2
Javier Walter MD, 2485, 4
Waino Leuschke, 2486, 2
Ariel Jacobson, 2015, 3
Melvin Bailey, 2485, 0
Dovie Emmerich, 2383, 4
Adrian Stroman Jr., 2180, 1
Helen Douglas, 2352, 4
Yessenia O’Reilly, 2247, 2
_

将这个字符串转换为哈希很方便,既可以解决当前问题,又可以对数据执行其他操作。

players_by_name = players.each_line.with_object({}) do |line, h|
  name, elo, score = line.split(',')
  h[name] = { name: name, elo: elo.to_i, score: score.to_i }
end
  #=> {"Derek Aufderhar"  =>{:name=>"Derek Aufderhar",   :elo=>2134, :score=>1},
  #    "Hadley Kuhn"      =>{:name=>"Hadley Kuhn",       :elo=>2044, :score=>0},
  #    ...
  #    "Yessenia O’Reilly"=>{:name=>"Yessenia O’Reilly", :elo=>2247, :score=>2}}

我们现在可以计算max_elo = 11000的前五名:

best = best_five(players_by_name.values, 11000)
  #=> {:names=>["Myrtie Lueilwitz", "Mitchell Schiller", "Ariel Jacobson",
  #             "Dovie Emmerich", "Helen Douglas"],
  #    :tot_scores=>15}

要检索这五个玩家的信息,我们需要计算以下内容:

a = players_by_name.values_at(*best[:names])
  #=> [{:name=>"Myrtie Lueilwitz" , :elo=>2207, :score=>2},
  #    {:name=>"Mitchell Schiller", :elo=>2036, :score=>2},
  #    {:name=>"Ariel Jacobson"   , :elo=>2015, :score=>3},
  #    {:name=>"Dovie Emmerich"   , :elo=>2383, :score=>4},
  #    {:name=>"Helen Douglas"    , :elo=>2352, :score=>4}]

我们已经知道分数总和为15。

a.map { |h| h[:elo] }.sum
  #=> 10993

我们看到未超过合并的ELO限制。

Array#sum在Ruby v2.4中首次亮相。