最佳匹配

时间:2015-04-13 16:59:12

标签: algorithm optimization

让我们假设你是一名棒球经理。并且你的牛棚中有N个投手(N <= 14)并且他们必须面对M个击球手(M <= 100)。另外要提到的是你知道每个投手和每个击球手的实力。对于那些对棒球不熟悉的人,一旦你带来了一个救援投手,他可以投球到连续的击球手,但是一旦他被淘汰出局,他就无法回来。

对于每个投手,他将失去对位的概率由(他将面对的所有击球手的总和)/(他的力量)给出。尽量减少这些概率,即尽量提高你赢得比赛的机会。

例如,我们有3个投手,他们必须面对3个击球手。击球手的强势是:

10 40 30

虽然你的投手的力量是:

40 30 3

最佳解决方案是让最强的投手面对前2个击球手,第二个面对第三击球手。那么每个投手失去比赛的概率将是:

50/40 = 1.25和30/30 = 1

因此失去游戏的概率为1.25(此数字可能大于100)。

如何找到最佳数字?我想采取一种贪婪的方法,但我怀疑它是否会永远持有。此外,投手可以面对无限数量的击球手(我的意思是它只受M限制)对我来说是一个主要问题。

2 个答案:

答案 0 :(得分:0)

概率必须在[0.0,1.0]范围内,因此您所谓的概率不能是概率。我只是称它为分数并将其最小化。

我现在要假设你以某种方式知道投手应该打的顺序。

鉴于顺序,剩下要决定的是每个投手的上场时间。我想你可以用动态编程找到它。考虑按顺序面对的击球手。建立一个NxM表最好[投手,击球员]哪里最好[i,j]是你可以考虑使用第一个投手的第一个j击球手的最佳得分,或者如果它没有意义则是巨大的。

最佳[1,1]只是对阵第一个击球手的最佳投手的得分,而对于j的任何其他值,最好的[1,j]没有意义。

对于较大的i值,考虑到所有可能性(因此1,2,3 ... i),考虑到投手的最后一次变化,你可以得到最好的[i,j]。如果投手的最后一次更改是在时间t,那么查找最佳[t,j-1]以使分数达到该变化之前的时间,然后计算a / b值以考虑总和时间t + 1和时间i之间的击球强度。当您考虑所有可能的时间后,取最佳分数并将其用作最佳[i,j]的值。记下足够的信息(例如最后一次投手变化最好),这样一旦你计算出最佳[N,M],你就可以追溯到找到最佳时间表。

您实际上并不知道订单,并且因为最终得分是每个投手的a / b值的最大值,所以订单确实很重要。但是,如果将球员分成小组,将投手分配给小组的最佳方法是将最佳投手分配给总分最高的组,下一个最佳投手组中的最佳投手,等等。因此,如上所述,你可以在将击球手分成小组之间交替,然后将投手分配到小组以计算投手真正应该处于的顺序 - 继续这样做直到答案停止变化并希望结果是全局最优。不幸的是,我们无法保证这一点。

我不相信你的得分对于棒球来说是一个很好的模特,特别是因为它最初是以概率开始但不是。也许你应该弄清楚一些例子(甚至可能通过蛮力解决小例子),看看结果是否合理。

答案 1 :(得分:0)

解决此问题的另一种方法是通过http://en.wikipedia.org/wiki/Branch_and_bound

使用分支和绑定,您需要一些方法来描述部分答案,并且您需要某种方法来计算给定部分答案的值V,这样无法扩展该部分答案可能产生比V更好的答案然后你运行树搜索,以各种可能的方式扩展部分答案,但丢弃部分答案,这些答案可能比目前为止找到的最佳答案更好。如果你能从最好的答案开始猜测就好了,因为那时你可以从一开始就丢弃不好的部分答案。我的另一个答案可能会提供一种解决方法。

这里的部分答案是选择投手,按他们应该打的顺序,以及他们应该投球的击球手的数量。第一个部分答案将有0个投手,你可以通过选择每个可能的投手来扩展它,投射到每个可能数量的击球手,给出一个部分答案列表,每个提到一个投手,其中大部分你可能希望丢弃。

鉴于部分答案,您可以计算每个投手选择的(总击球手强度)/(投手力量)。这里找到的最大值是一种可行的方法。你可以做另一种计算。总结剩下的所有击球手的总强度,并除以剩下的所有投手的总强度。这将是投手留下的最佳结果,因为如果你以某种方式设法尽可能均匀地将投手分配给击球手,那么这就是你得到的结果。如果此值大于您目前已计算的V值,请使用此值而不是V来获得一个不太乐观(但更准确)的度量,以衡量该部分答案的后代可能有多好。