Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 解决是非测试_Algorithm - Fatal编程技术网

Algorithm 解决是非测试

Algorithm 解决是非测试,algorithm,Algorithm,有一个测试有NYES或NO问题。你可以写测试,教授会告诉你有多少答案是正确的。通过考试最快的方法是什么?即,以最少的试验次数正确回答所有问题 UPD使用N+1试验的解决方案是显而易见的。在每次试验中,我们都会对一个问题给出正确答案。这是一个信息位。但教授每次给我们一个从0到N的数字,它是log2(N+1)位的信息。这就是为什么最好的解决方案具有O(N/log(N))复杂性我正在寻找任何具有次线性最差时间复杂度的解决方案。免责声明:我不知道这是否是最快的方法。我确信在特定的场景中,你可以通过较少的

有一个测试有
N
YES或NO问题。你可以写测试,教授会告诉你有多少答案是正确的。通过考试最快的方法是什么?即,以最少的试验次数正确回答所有问题

UPD使用
N+1
试验的解决方案是显而易见的。在每次试验中,我们都会对一个问题给出正确答案。这是一个信息位。但教授每次给我们一个从0到N的数字,它是log2(N+1)位的信息。这就是为什么最好的解决方案具有
O(N/log(N))
复杂性我正在寻找任何具有次线性最差时间复杂度的解决方案。

免责声明:我不知道这是否是最快的方法。我确信在特定的场景中,你可以通过较少的试验获得成功,但这可能是一个严格的上限(最坏的情况)

无论你喜欢什么,都可以参加第一轮的试用,记住你的选择。如果您愿意,您可以为所有选项选择“否”

在下一次试验中,仅更改第一个答案(按照示例:选择是)。根据答案的变化,您将知道第一个问题的正确答案(如果结果增加,您给出了正确答案,如果没有,则是错误答案)

现在只更改第二个,依此类推


你需要N+1条线索。

简单的解决方案需要O(N)次尝试:从所有答案开始是,然后在每个
i
th尝试翻转
i
th答案。如果你的分数增加了,保持它;如果没有,请将其翻转回去。增量
i
,重复


更有效的解决方案可能涉及一个非常简单的遗传算法,其中启发式是教授的答案,而变异可能相当于简单地翻转所有答案。这可能会接近O(logn)次尝试,但乘法常数当然会更大(如果我不得不猜测的话,至少会大一个数量级),因此它只适用于大N。

一些Python代码适用于一个简单的O(N)算法:

import random

def ask_prof(A, M): return sum(x == y for x, y in zip(M, A)) 

N = 10
A = [ random.randint(0, 1) for x in range(N) ]
K, s = [], 0
for trial in range(N):
    M = K + [ 0 for x in range(N - len(K)) ]
    s1 = ask_prof(A, M)
    M[len(K)] = 1 
    s2 = ask_prof(A, M)
    if s1 < s2: K.append(1)
    else: K.append(0)
print 'answers are', K
随机导入
def ask_prof(A,M):返回和(x==y表示x,y表示zip(M,A))
N=10
A=[random.randint(0,1)表示范围(N)内的x]
K、 s=[],0
在范围(N)内进行试验:
M=K+[0表示范围内的x(N-len(K))]
s1=询问教授(A,M)
M[len(K)]=1
s2=询问教授(A,M)
如果s1
与N+1解决方案相比有明显的改进:

从所有令人困惑的答案开始

那么我们就知道有多少是/否了

p
为在任何给定位置上出现yes的概率<代码>p>=1/2,不失一般性

然后,我将以
2-p^2
次尝试的平均值展示两个最初的答案

我更改了前两个问题的答案。 至少有一段时间我会知道他们俩的确切答案。如果不是,那么我至少知道其中一个是Y,另一个是N,我需要再问一个问题

因此,在最坏的情况下,p=1/2,我需要另一种方法(分而治之)。为了简单起见,我将引用
N
的一个特定值,但概括起来很简单

假设在第一轮(
trial=1
)中,我们正确回答了
5
问题。这是最有可能的结果,也是人们注意到的信息量较少的结果

然后,以下逻辑允许我们不检查每个数字:

  • 将答案列表分为两组,
    1…5
    6…10
    。假设我们有5个正确答案,每组可能的正确答案如下

    (0,5)
    (1,4)
    (2,3)
    (3,2)
    (4,1)
    (5,0)
    
现在,在下一次试验中,翻转答案
1…5
。然后,上述状态变化如下:

    (0,5)--> (5,5)   -- 10 correct
    (1,4)--> (4,4)   -- 8 correct
    (2,3)--> (3,3)   -- 6 correct
    (3,2)--> (2,2)   -- 4 correct
    (4,1)--> (1,1)   -- 2 correct
    (5,0)--> (0,0)   -- 0 correct
如果老师说
10
0
我们就完成了,或者我们需要分别进行一次试验。在任何情况下,根据老师说的数字,我们可以知道每个时间间隔有多少正确答案。然后我们可以决定

  • 2正确:我们回溯(回溯)前5个答案,我们知道我们的答案分别是(4,1)正确的
    1…5
    6…10
    。因此,我们也翻转
    6…10
    ,得到正确的8,见下文
  • 4正确:与2正确一样,我们将前5个答案翻过来,再翻过来
    6…10
    ,得到6正确答案,见下文
  • 6正确:我们需要进一步分割和迭代。对于
    1…5
    6…10
    中的每一个,我们最多还需要3个步骤,因此总共需要8个步骤,包括前两个步骤
  • 8正确:我们再次应用二进制搜索。我们将两个初始集合(例如,
    1…5
    被划分为
    1…3
    4…5
    )中的每一个,并寻找错误的答案。如果在
    4…5中,我们需要两个步骤,否则我们需要三个步骤。因此,再次总共有8个步骤
在Carsten的评论中,Erdös和Rényi举例说明了如何将问题表述为找到最小数量的测试序列,这些测试序列一起可以为未知序列生成唯一的哈希。因为他们的例子显示了一个用四个测试求解的五位数序列,所以我试图为长度为6和7的序列提出一个次线性的测试数

看看Erdös和Rényi的例子,受Ioannis提到的“分而治之”的启发,我认为测试序列可能是一种划分,然后再细分序列。为了得到序列长度为7的工作测试,进行了几次尝试

考虑您所要求的算法的一种方法可能是概括/自动生成这些测试序列

下面是JavaScript程序
// http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html
function setBits(i)
{
     i = i - ((i >> 1) & 0x55555555);
     i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
     return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}

// http://stackoverflow.com/questions/10073699/pad-a-number-with-leading-zeros-in-javascript
function pad(n, width, z) {
  z = z || '0';
  n = n + '';
  return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}

function numCoincidences(a,b){
    var n = 0
    for (var i=0; i<a.length; i++){
        if (a.charAt(i) == b.charAt(i)){
            n ++
        }
    }
    return n
}

var sequenceLength = 6

var tests = [
        "111111",
        "111000",
        "010010",
        "011001",
        "000100"
    ]

/***
var sequenceLength = 7

var tests = [
    "1111111",
    "1111000",
    "0100100",
    "0110010",
    "0110001",
    "0001000"
]
***/

var hash = {}

console.log("       " + tests.join(" "))

for (var i=0; i<1<<sequenceLength; i++){
    if (setBits(i) < Math.floor(sequenceLength / 2)){
      var tmp = pad(i.toString(2),sequenceLength)
      var h = ""
      for (var j in tests){
        h += numCoincidences(tests[j],tmp)
      }
      console.log(tmp + "   " + h.split("").join("      "))
      if (hash[h]){
          console.log("found match")
      } else {
          hash[h] = true
      }

    }
}

console.log("done")
"       111111 111000 010010 011001 000100" <-- test sequences
"000000   0      3      4      3      5"
"000001   1      2      3      4      4"    <-- sequences to match, followed by
"000010   1      2      5      2      4"             the number of coincidences 
"000011   2      1      4      3      3" 
"000100   1      2      3      2      6" 
"000101   2      1      2      3      5" 
"000110   2      1      4      1      5" 
"000111   3      0      3      2      4" 
"001000   1      4      3      4      4" 
"001001   2      3      2      5      3" 
"001010   2      3      4      3      3" 
"001011   3      2      3      4      2" 
"001100   2      3      2      3      5" 
"001101   3      2      1      4      4" 
"001110   3      2      3      2      4" 
"010000   1      4      5      4      4" 
"010001   2      3      4      5      3" 
"010010   2      3      6      3      3" 
"010011   3      2      5      4      2" 
"010100   2      3      4      3      5" 
"010101   3      2      3      4      4" 
"010110   3      2      5      2      4" 
"011000   2      5      4      5      3" 
"011001   3      4      3      6      2" 
"011010   3      4      5      4      2" 
"011100   3      4      3      4      4" 
"100000   1      4      3      2      4" 
"100001   2      3      2      3      3" 
"100010   2      3      4      1      3" 
"100011   3      2      3      2      2" 
"100100   2      3      2      1      5" 
"100101   3      2      1      2      4" 
"100110   3      2      3      0      4" 
"101000   2      5      2      3      3" 
"101001   3      4      1      4      2" 
"101010   3      4      3      2      2" 
"101100   3      4      1      2      4" 
"110000   2      5      4      3      3" 
"110001   3      4      3      4      2" 
"110010   3      4      5      2      2" 
"110100   3      4      3      2      4" 
"111000   3      6      3      4      2" 
"done"