选择具有最大点但具有给定成本的玩家的算法

时间:2012-10-31 09:39:17

标签: algorithm data-structures

我需要一个执行以下操作的算法:

在NBA幻想联盟中,给出了:

  1. 每位玩家的平均积分
  2. 每位玩家的价格
  3. 工资帽
  4. 选择最佳的9人阵容。

    使用一个简单的例子,假设联盟中只有四名球员,你有一个$ 10,000的工资帽,你想要最佳(意味着最高分)3人阵容。这里有平均点总数和价格:

    勒布朗詹姆斯:30分/场比赛; $ 5,000个
    科比布莱恩特:25分/场; $ 3,500名
    德隆威廉姆斯:20分/场; $ 2,500个
    谢尔文麦克:得到15分; $ 2,000

    最佳阵容将是科比,威廉姆斯和麦克,这将花费8,000美元并得到60分。

    还有一个限制:程序必须为每个位置选择一定数量的球员(例如,两个控球后卫,两个得分后卫,两个小前锋,两个大前锋和一个中锋)。这使得设计程序变得困难。

2 个答案:

答案 0 :(得分:5)

首先,很容易看出问题的推广是NP-Hard,并且可以立即从Knapsack Problem缩小:

考虑到背包问题:weight=W, costs_of_items=C, weight_of_items=X,将问题减少到这个问题而不限制玩家数量(概括最多只有k个玩家,其中k被选中由你)。

因此,我们可以得出结论,没有已知的多项式时间解决方案。

但是,我们可以基于knapsack pseudo-polynomial solution开发解决方案。
为简单起见,假设我们只限制小前锋的数量(答案的原则可用于增加更多限制)。

然后,可以使用以下递归方法解决问题:

if i is not a forward, same as the original knapsack, while maintaining the #forwards
    f(i,points,forwards) = max {
                f(i-1,points-C[i],forwards)
                f(i-1,points,forwards)
                           }
if i is a forward:
    f(i,points,forwards) = max {
                //We used one of the forwards if we add this forward to the team
                f(i-1,points-C[i],forwards-1) 
                f(i-1,points,forwards)
                           }

基数将全部为零,其中一个维度为零:f(0,_,_)=f(_,0,_)=0(与常规背包相同)和f(_,_,-1)=-infnity(无效解决方案)

答案为f(2,W,n)(前锋数量为2,如果不同,也应该更改)。 W是工资上限,n是玩家数量。

DP解决方案将填充表示递归自下而上的矩阵以获得伪多项式时间解(仅当限制是常数时才是伪多项式)。

通过重复此过程,为每个条件添加维度,DP解决方案将最佳地解决此问题。

您将获得的复杂性为O(B^p * W * n) - 其中:
B是“分支因素” - 您的案例B=3中每个职位的玩家数量+ 1(零)。
W =工资帽
n =可供选择的球员数量


如果您发现最佳解决方案过于耗时,我建议您使用启发式解决方案,例如hill climbingGenetic Algorithms,这会尝试优化结果尽可能多,但不能保证找到全局最大值。

答案 1 :(得分:1)

使用动态编程可以轻松解决这个问题。参考this

f[i][j]成为我们使用j美元与第一个i玩家获得的最高分数,所以

f [i] [j] = max {

  1. f [i - 1] [j] //我们不选择第i个玩家
  2. f [i - 1] [j - cost [i]] + point [i] //我们选择他
  3. }

    最后f[TOTALPLAYER][MONEYCAP]就是答案。

    主要想法是确定是否为每个玩家选择他。

    数组f[][]仅用于加速搜索过程。

    btw,Chowlett是对的。