首先,很容易看出问题的泛化是NP-Hard,并且可以立即从背包问题中约简:
给定一个背包问题:weight=W, costs_of_items=C, weight_of_items=X
,将问题简化为这个问题,不限制玩家的数量(一般化最多是k
玩家,k
由你选择)。
因此,我们可以得出结论,该问题没有已知的多项式时间解。
但是,我们可以开发一个基于背包伪多项式解的解。
为简单起见,假设我们仅对小前锋的数量进行了限制(可以应用答案的原则来添加更多限制)。
然后,可以使用以下递归方法解决问题:
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
= 可供选择的球员人数
如果您发现最佳解决方案过于耗时,我建议您使用启发式解决方案,例如爬山或遗传算法,它们会尝试尽可能优化结果,但不能保证找到全局最大值。