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

标签 algorithm data-structures

<分区>

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

在 NBA 梦幻联盟中,给定:

  1. 每位选手的平均总分
  2. 每个玩家的价格
  3. 工资帽

选择最佳的 9 人阵容。

举个简单的例子,假设联盟中只有四名球员,你的工资帽是 10,000 美元,你想要最佳(即最高分)的 3 人阵容。以下是平均总分和价格:

勒布朗·詹姆斯:30 分/场; 5,000 美元
科比-布莱恩特:25分/场; 3,500 美元
德隆威廉姆斯:20分/场; 2,500 美元
谢尔文麦克:15分/场; 2,000 美元

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

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

最佳答案

首先很容易看出问题的泛化是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 是“分支因子”- 在您的情况下,每个位置的玩家数量 +1(对于零)B=3
W = 工资帽
n = 可供选择的玩家数量


如果您发现最佳解决方案太耗时,我建议您选择启发式解决方案,例如hill climbingGenetic Algorithms ,它将尽可能地优化结果,但不能保证找到全局最大值。

关于选择具有最高点数但具有给定成本的玩家的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13154995/

相关文章:

java - 如何在Java中动态地将信息存储到包含字符串和整数的数据结构中

database - 一种在内存中保存经常变化的值的方法

c++ - 当我们已经拥有更强大的 vector 时,为什么还需要堆栈?

C++ 在无序树中查找具有最高值的节点

c# - 在 C# 中打印 LevenshteinDistance 矩阵

arrays - 获取表条目的算法?

c++ - 购买元素后最小化硬币数量

java - 关于如何从 char 字符串中获取所有子集而不覆盖所有不同字母的算法是什么?

c# - 为什么我们需要二叉搜索树中的父节点 - C#

java - 我不明白 Node.next 是如何工作的