只知道提议的数字是低还是高,猜测一个数字?

时间:2012-03-07 16:13:40

标签: algorithm math

我需要猜一个数字。我只能看看我提议的数字是低还是高。性能很重要,所以我想到了以下算法:

假设我猜的数字是600。

  • 我从数字1000开始(或者更高的性能,以前数字的平均结果)。

  • 然后检查1000是高于还是低于600.它更高。

  • 然后我将数字除以2(现在为500),并检查它是否低于或高于600.它更低。

  • 然后我找到差异并按以下方式将其除以2以检索新数字:((1000 - 500)/ 2)。结果是750.然后检查那个号码。

等等。

这是最好的方法吗?有更聪明的方法吗?对于我的情况,每次猜测大约需要500毫秒,我需要在尽可能短的时间内猜测很多数字。

我可以粗略地假设先前猜测的平均结果也接近即将到来的数字,所以我可以使用一种模式来为自己的利益。

7 个答案:

答案 0 :(得分:7)

binary search是最有效的方法。 Binary Search就是您所描述的。对于在Binary Search时间内运行1到N O(log(n))之间的数字。

所以这是找到1-N

之间的数字的算法
int a = 1, b = n, guess = average of previous answers;

while(guess is wrong) {

    if(guess lower than answer) {a = guess;}
    else if(guess higher than answer) {b = guess;}

    guess = (a+b)/2;

} //Go back to while

答案 1 :(得分:3)

嗯,你在没有额外信息的情况下采取了最好的方法 - 基本上是二进制搜索

如何使用“以前猜测的平均结果”取决于你;它会建议将结果偏向该平均值,但您需要对先前结果的指示进行分析,以便找出最佳方法。不要只使用平均值:使用完整的分布。

例如,如果所有结果都在600-700范围内(即使假设范围达到1000),平均值为670,那么您可能以<6>开始但是如果它说“猜得更高”然后你可能想要选择670到700之间的值作为你的下一个猜测,而不是835(很可能高于实际结果)。

我建议您记录之前查询的所有结果,这样您就可以将其用作替代方法的测试数据。

答案 2 :(得分:1)

通常,从范围的中间点开始的二分搜索是最佳策略。但是,您有其他特定信息可能会使其成为次优策略。这主要取决于“接近先前结果的平均值”的含义。

如果数字接近先前的平均值,则在第二步中除以2不是最佳的。

示例:之前的数字630,650,620,660。您从640开始。

你的号码实际上更接近了。想象一下它是634。

数字较低。如果在第二步中除以2,则得到320,从而失去对先前平均数的任何优势。

您应该进一步分析行为。在您的特定情况下,从N个先前数字的平均值开始,然后添加或减去与先前数字的标准差相关的一些数量可能是最佳的

答案 3 :(得分:1)

是的,二进制搜索(您的算法)在这里是正确的。但是,标准二进制搜索中缺少一件事:

对于二进制搜索,您通常需要知道要搜索的最大值和最小值。如果您不知道这一点,您必须在开头迭代地找到最大值,如下所示:

  • 从零开始
  • 如果它高于搜索的数字,则零是您的最大值,您必须找到最小值
  • 如果它低于搜索的数字,则零是您的最小值,您必须找到最大值
  • 您可以从1或-1开始搜索最大值/最小值,并始终乘以2,直到找到更大/更小的数字

当你总是乘以2时,你会比线性搜索时快得多。

答案 4 :(得分:0)

您知道可能值的范围吗?如果是,请始终从中间开始,完全按照您的描述进行操作。

答案 5 :(得分:0)

0到N之间的标准二进制搜索(N是给定数字)将在logN时间内给出答案。

答案 6 :(得分:0)

int a = 1, b = n+1, guess = average of previous answers;

while(guess is wrong) {

    if(guess lower than answer) {a = guess;}
    else if(guess higher than answer) {b = guess;}

    guess = (a+b)/2;

} //Go back to while

You got to add +1 to n else you can never get n since it's an int.