【问题标题】:Algorithm to auto-pick 11 players in a fantasy football lineup where the total price is near N在总价接近 N 的梦幻足球阵容中自动选择 11 名球员的算法
【发布时间】:2013-10-18 10:30:37
【问题描述】:

我有一个包含 500 个浮点数的列表。

我想从列表中挑选出 11 个数字,它们加起来总和为 N,并且 N 在 X 范围内

这基本上是一个梦幻足球游戏,我们在人物阵容中自动选择 11 名球员。

总成本应该在一个范围内,而不是随机的。

一种解决方案可能是连续随机选择 11 名玩家,直到我得到一个适合该范围的总数,但我想知道是否有更优雅的方法?

【问题讨论】:

  • 动态规划 :) 它是背​​包问题的修改版本。
  • 也是子集和问题的修改版本。这并不奇怪,因为两者都是 NP 完全的。
  • 您只需要一个选择吗?它必须给所有玩家一个公平的机会?
  • 感谢 thefourtheye,甚至不知道该用谷歌搜索什么!
  • 你不必随机挑选球员。选择随机玩家会导致碰撞,从而减慢寻找解决方案的速度。取而代之的是,您可以系统地循环遍历不同的组合,希望尽快找到解决方案。

标签: python algorithm


【解决方案1】:

就像评论者指出的那样,这是一个 NP 难题。但是,如果您的数据还不错,那么以下内容应该可以正常工作:

picks[] := K numbers chosen at random from the population
While sum(picks) is not in the allowable range
  if sum(picks) < MinRange
    select an element p from picks at random
    let subpop := elements in population which are larger than p
    replace p with a random element from subpop
  if sum(picks) > MaxRange
    select an element p from picks at random
    let subpop := elements in population which are smaller than p
    replace p with a random element from subpop

这很容易编写代码,它将返回一个满足约束的相对随机的选择,并且它不应该花费太长时间,除非你真的有一个问题的困难实例,在这种情况下它会非常使用任何算法都很难找到解决方案。

如果你想加速算法,那么你可以选择元素p作为每次通过picks中的最小/最大元素。这应该会使算法运行得更快,但也会减少“随机”选择。

【讨论】:

    【解决方案2】:

    我认为这不是最好的方法,但它可能会奏效:

    import random
    
    data  # list of 500 floats
    n = 11 # numbers to pick
    bottom_limit = X
    top_limit = Y
    max_tries = 100
    
    data_min = min(data)
    data_max = max(data)
    
    i = 0
    while i < max_tries:
        i += 1
        picked = []
    
        for j in xrange(n-1):  # pick random except the last one
            picked.append(random.choice(data))
        s = sum(picked)
    
        if s + data_min < top_limit and s + data_max > bottom_limit:
            # Ok, we know we can find proper values, let's do it
            filtered = []
            for value in data:
                if value + s > bottom_limit and value + s < top_limit:
                    filtered.append()
    
            picked.append(random.choice(filtered))
            break  # Success
    else:
        print 'Unable to pick, sorry'
    

    成功率与数据和限值高度相关。

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      什么是 X 和 Y?你能用整数近似它们和玩家的分数吗? 如果是这样,那么您可以使用动态编程,例如 for knapsack problem.

      但是有几个问题。

      1. 此算法需要 O(Y) 内存和 O(M + Y) 时间,其中 M 是玩家总数。
      2. 如果您想找到所有允许的团队,然后随机选择一个,那么您将遇到一个问题,即此类团队的数量可能呈指数级增长。

      因此,对于实用的方法,我投票赞成 mrip 的建议。

      【讨论】:

        猜你喜欢
        • 2011-11-27
        • 2023-02-22
        • 1970-01-01
        • 2017-08-16
        • 1970-01-01
        • 1970-01-01
        • 2020-02-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多