解决一个简单的最大化游戏

时间:2011-10-10 17:01:19

标签: java algorithm language-agnostic maximize

我有一个关于我创建的游戏的一个非常简单的问题(这不是作业):以下方法应包含哪些内容以最大化收益:

private static boolean goForBiggerResource() {
    return ... // I must fill this
};

我再次强调这不是作业:我正在努力了解这里的工作原理。

“策略”是微不足道的:只能有两种选择:真或假。

“游戏”本身非常简单:

P1  R1        R2 P2


          R5


P3  R3        R4 P4
  • 有四个玩家(P1,P2,P3和P4)和五个资源(R1,R2,R3,R4全部值1和R5,价值2)

  • 每个玩家都有两个选项:要么选择接近其起始位置的资源,该资源给出1并且玩家肯定会得到(没有其他玩家可以首先获得该资源) OR < / em>玩家可以尝试寻找价值2的资源......但其他玩家也可以选择它。

  • 如果两个或更多玩家选择更大的资源(价值2的那个),那么他们将同时到达更大的资源,并且只有一个玩家随机获得它而另一个玩家获得它进入该资源的玩家将获得0(他们无法返回值为1的资源)。

  • 每位玩家都采用相同的策略(方法中定义的策略 goForBiggerResource ())

  • 玩家不能互相“交谈”以达成战略协议

  • 游戏运行100万次

所以基本上我想填充方法 goForBiggerResource(),它返回true或false,以最大化收益。

以下是允许测试解决方案的代码:

private static final int NB_PLAYERS = 4;
private static final int NB_ITERATIONS = 1000000;

public static void main(String[] args) {
    double totalProfit = 0.0d;
    for (int i = 0; i < NB_ITERATIONS; i++) {
        int nbGoingForExpensive = 0;
        for (int j = 0; j < NB_PLAYERS; j++) {
            if ( goForBiggerResource() ) {
                nbGoingForExpensive++;
            } else {
                totalProfit++;
            }
        }
        totalProfit += nbGoingForExpensive > 0 ? 2 : 0;
    }
    double payoff = totalProfit / (NB_ITERATIONS * NB_PLAYERS);
    System.out.println( "Payoff per player: " + payoff );
}

例如,如果我建议以下解决方案:

private static boolean goForBiggerResource() {
    return true;
};

然后所有四名球员都会争取更大的资源。其中只有一个会随机获得它。超过一百万次迭代,每位玩家的平均收益为2/4,得到0.5,程序将输出:

每位玩家的回报:0.5

我的问题非常简单:应该进入方法 goForBiggerResource()(返回true或false)以最大化平均收益以及为什么?

4 个答案:

答案 0 :(得分:5)

由于每个玩家使用的是goForBiggerResource方法中描述的相同策略,并且您尝试最大化整体回报,最好的策略是三个玩家坚持使用本地资源,一个玩家参加大型游戏。不幸的是,因为他们不能就战略达成一致,而且我认为没有一个球员不能被分类为大型猎人,所以事情变得棘手。

我们需要随机化玩家是否参加大型比赛。假设p是他为之而去的概率。然后根据有多少大型游戏猎人将案件分开,我们可以计算案件的数量,概率,收益,并根据这个预期的收益来计算。

  • 0 BGH:(4选0)个案,(1-p)^ 4概率,4支付,预期4(p ^ 4-4p ^ 3 + 6p ^ 2-4p + 1)
  • 1 BGH:(4选1)个案,(1-p)^ 3 * p概率,5个支付,预期20(-p ^ 4 + 3p ^ 3-3p ^ 2 + p)
  • 2 BGH:(4选2)个案,(1-p)^ 2 * p ^ 2概率,4个支付,预期24个(p ^ 4-2p ^ 3 + p ^ 2)
  • 3 BGH:(4选3)个案,(1-p)* p ^ 3概率,3个支付,预期12个(-p ^ 4 + p ^ 3)
  • 4 BGH:(4选4)个案,p ^ 4概率,2个支付,预期2个(p ^ 4)

然后我们需要最大化预期收益的总和。如果我正确计算,则为-2p ^ 4 + 8p ^ 3-12p ^ 2 + 4p + 4。由于第一项是-2&lt; 0,它是一个凹函数,希望它的导数之一,-8p ^ 3 + 24p ^ 2-24p + 4,将最大化预期的收益。将其插入在线多项式求解器中,它返回三个根,其中两个复数,第三个是p~0.2062994740159。第二衍生物是-24p ^ 2 + 48p-24 = 24(-p ^ 2 + 2p-1)= -24(p-1)^ 2,其<1。 0表示所有p!= 1,所以我们确实找到了最大值。 (总体)预期收益是在此最大值下评估的多项式,约为4.3811015779523,即每位玩家的1.095275394488075支付。

因此,获胜方法就像这样

private static boolean goForBiggerResource ()
{
    return Math.random() < 0.2062994740159;
}

当然,如果玩家可以使用不同的策略和/或互相对抗,那就完全不同了。

编辑:此外,你可以作弊;)

private static int cheat = 0;

private static boolean goForBiggerResource ()
{
    cheat = (cheat + 1) % 4;
    return cheat == 0;
}

答案 1 :(得分:3)

我认为你试过以下内容:

private static boolean goForBiggerResource() {
    return false;
};

其中没有一个玩家试图获得价值为2的资源。因此,每个人都可以保证每次获得一个价值为1的资源:

每位玩家的回报:1.0

我想如果你问这个好问题是因为你猜这是一个更好的答案。

诀窍在于你需要所谓的“混合策略”。

编辑:好的,我带来了一个混合策略...我不知道帕特里克如何快速找到20%(当他评论时,你发布问题后几分钟)但是,是的,我发现了基本相同的价值:

private static final Random r = new Random( System.nanoTime() );

private static boolean goForBiggerResource() {
    return r.nextInt(100) < 21;
}

例如:

每位玩家的回报:1.0951035

基本上如果我没弄错,你想阅读关于“纳什均衡”的维基百科页面,尤其是:

“纳什均衡是根据混合策略定义的,其中玩家选择可能行为的概率分布”

你的问题/简单的例子,如果我没有弄错也可以用来表明为什么勾结球员可以做更好的平均回报:如果球员可以练习,他们平均得到1.25,这比我得到的1.095还要好。 / p>

另请注意,我的答案包含近似误差(我只检查0到99之间的随机数),并且取决于随机PRNG,但你应该明白这一点。

答案 2 :(得分:2)

如果玩家不能合作并且没有记忆,那么只有一种可能的方式来实现goForBiggerResource:随机选择一个值。现在的问题是什么是最好的使用率。

现在简单数学(与编程无关):

  • 假设费率x表示保留小资源的概率;
  • 因此,没有球员选择大球的机会是x^4;
  • 所以至少有一名球员进入大球的机会是1-x^4;
  • 总利润为x + ( 1 - x^4 ) / 2
  • 找出该公式的最大值为0%&lt; = x&lt; = 100%

结果大约是79.4%(对于返回false)

答案 3 :(得分:-1)

嗯,我认为你的基本问题是所描述的游戏是微不足道的。在所有情况下,最佳策略是坚持使用本地资源,因为前往R5的预期收益仅为0.5(1/4 * 2)。将R5的奖励提高到4,变得均匀;没有更好的策略。 奖励(R5)&gt; 4并且总是支付R5。