在不使用反馈的情况下查找数组中的偶数

时间:2011-12-30 06:41:55

标签: algorithm binary-search

我看到这篇文章:Finding even numbers in an array我正在思考如何在没有反馈的情况下做到这一点。这就是我的意思。

  

给定一个长度为n的数组,其中包含最多e偶数和a   函数isEven如果输入是偶数和假,则返回true   否则,写一个打印所有偶数的函数   使用isEven调用次数最少的数组。

这篇文章的答案是使用二进制搜索,这很整洁,因为它并不意味着数组必须按顺序排列。如果数字为偶数,则必须e log n代替n因为您进行二分搜索(log n)以便每次都找到一个偶数({{1}时间)。

但是这个想法意味着你将数组分成两半,测试均匀度,然后根据结果决定保留哪一半。

我的问题是你是否可以在一个固定的测试计划上打e个电话,你可以在不知道结果的情况下检查你想要的所有数字,然后找出偶数后的数字。我们根据结果完成了所有测试。所以我想这不是反馈或盲目或类似的术语。

我有一段时间没想过这件事,也无法想出任何东西。二元搜索的想法在这个约束下根本不起作用,但也许其他的东西呢?即使是n来电而不是n/2(是的,我知道他们是同一个大O)也不错。

6 个答案:

答案 0 :(得分:7)

“无反馈或盲目”的技术术语是“非适应性”。 O(e log n)调用仍然足够,但算法更加复杂。

我们不是测试产品的均匀度,而是测试总和的均匀度。设E≠F是{1,...,n}的不同子集。如果我们有一个数组x 1 ,...,x n 在位置E处有偶数,而另一个数组y 1 ,...,y n 在位置F处具有偶数,{1,...,n}的子集J满足

(J x i 中的Σ i)mod 2≠(J y i 中的Σ i) mod 2?

答案是2 n-1 。设i是一个索引,使得x i mod 2≠y i mod 2.设S是{1,...,i - 1,i + 1的子集, ...... n。 J = S是解决方案或J = S union {i}是解决方案,但不是两者。

对于每个可能的结果E,我们需要进行消除所有其他可能结果的调用F.假设我们随机进行2e log n个调用。对于每对E≠F,我们仍然不能将E与F区分开的概率是(2 n-1 / 2 n 2e log n = n -2e ,因为有2个 n 可能的调用,只有2个 n-1 无法区分。 E最多有n e + 1个选择,因此最多(n e + 1)n e / 2对。通过联合约束,存在一些不可区分对的概率最多为n -2e (n e + 1)n e / 2 < 1(假设我们正在研究e≥1且n≥2的有趣情况),因此存在一系列2e log n次调用来完成工作。

请注意,虽然我使用随机性来表明存在一个良好的调用序列,但结果算法是 deterministic (当然,也是非自适应的,因为我们选择了没有结果的知识)。

答案 1 :(得分:4)

您可以使用Chinese Remainder Theorem执行此操作。我要稍微改变你的记谱法。

假设您有N个,其中E个偶数。选择一系列不同的素数q1,q2,...,qk,使其产品至少为N^E,即

 qi = pi^ei

其中pi为素数,ei > 0为整数且

 q1 * q2 * ... * qk >= N^E

现在制作一堆0-1矩阵。让Mi成为qi x N矩阵,其中r行和c行中的条目1 c = r mod qi0 } 除此以外。例如,如果qi = 3^2,则行2在其他地方的列2, 11, 20, ... 2 + 9j0中都有。

现在垂直堆叠这些矩阵以获得Q x N矩阵M,其中Q = q1 + q2 + ... + qkM行告诉您哪些数字相乘(非零位置)。这样可以提供总共需要测试均匀度的Q个产品。将每一行称为“试用”,如果该行的j列非空,则说“试验涉及j”。你需要的定理如下:

THEOREM:位置j中的数字即使且仅当涉及j的所有试验都是偶数时才是。

因此,您总共进行Q次试验,然后查看结果。如果您智能地选择素数,则Q应显着小于N。渐近结果表明您总是可以按照

的顺序获得Q
(2E log N)^2 / 2log(2E log N)

这个定理实际上是中国剩余定理的必然结果。我见过这个地方的唯一地方是Combinatorial Group Testing。显然,这个问题最初是在测试士兵从二战中回来治疗梅毒时出现的。

答案 2 :(得分:2)

您遇到的问题是一种group testing形式的问题类型,目的是降低识别某组元素的成本(最高 d 一组 N 元素的元素。

正如您已经说过的,可以通过两个基本原则进行测试:

  • 非自适应组测试,其中所有要执行的测试都是先验决定的。

  • 自适应组测试,我们执行多项测试,将每项测试基于之前测试的结果。显然,与非自适应测试相比,自适应测试有可能降低成本。

已对两项原则的理论界限进行了研究,并提供in this Wiki articlethis paper

  • 对于自适应测试,上限为 O(d*log(N)) (如this answer中所述)。

    < / LI>
  • 对于非自适应测试,可以显示上限是 O(d*d/log(d)*log(N)) ,这明显大于上限自适应测试的因子为d/log(d)

非自适应测试的上限来自使用disjunct matrices的算法:维度T x N的矩阵(“测试次数”x“元素数”),其中每个项目都可以要么为true(如果元素包含在测试中),要么为false(如果不包含),其属性为d列的任何子集必须与所有其他列至少有一行不同(test包含)。这允许线性解码时间(还有“d-separable”矩阵,其中需要较少的测试,但是它们解码的时间复杂度是指数级的,而不是计算可行的。)

<强>结论:

  

我的问题是你是否可以在固定测试计划上打n次电话[...]

对于这样的方案和足够大的N值,可以构造一个小于K * [d*d/log(d)*log(N)]行的析取矩阵。所以,对于N的大值,是的,你可以击败它。

答案 3 :(得分:0)

潜在的问题(挑战)有点愚蠢。如果二进制搜索答案是可接受的(它将子数组相加并将它们发送到IsEven)那么我可以想办法用E或更少的IsEven调用(假设数字当然是整数)。

JavaScript演示

// sort the array by only the first bit of the number
A.sort(function(x,y) { return (x & 1) - (y & 1); });
// all of the evens will be at the beginning
for(var i=0; i < E && i < A.length; i++) {
    if(IsEven(A[i]))
        Print(A[i]);
    else
        break;
}

答案 4 :(得分:0)

不完全是一个解决方案,但只是一些想法。

  1. 很容易看出,如果阵列长度为n的解决方案需要少于n次测试,则对于任何数组长度m> 1。很容易看出,总有一种解决方案的测试时间少于m次。所以,如果你有n = 2或3或4的解决方案,那么问题就解决了。

  2. 你可以将数组拆分成数字对和每对:如果总和是奇数,那么其中只有一个是偶数,否则如果其中一个是偶数,那么它们都是偶数。对于每对,这种方式需要一次或两次测试。最佳案例:n / 2次测试,更糟糕的情况:n次测试,如果选择偶数和奇数,则:3n / 4次测试。

  3. 我的预感是没有少于n次测试的解决方案。不知道如何证明它。

    更新:第二种解决方案可以通过以下方式进行扩展。

    检查两个数字的总和是否为偶数。如果奇怪,那么其中只有一个是偶数。否则将该组标记为“大小为2的同类组”。取两个相同大小的“同质集”n。从每组中选择一个数字并检查它们的总和是否均匀。如果是偶数,则将这两组合并为“均匀的2n大小”。否则,它意味着其中一个集合纯粹由偶数组成,另一个纯粹由奇数组成。

    最佳案例:n / 2次测试。平均情况:3 * n / 2。最坏的情况仍然是n。只有当所有数字都是偶数或所有数字都是奇数时,才会出现最坏情况。

答案 5 :(得分:0)

如果我们可以添加乘法数组元素,那么我们可以在低位上计算每个布尔函数(直到补码)。模拟一个编码偶数位置的电路​​,编号为0到nC0 + nC1 + ... + nCe - 1用二进制表示,并使用isEven调用来读取这些位。

使用的呼叫数量:信息理论最优中的1个。

另见fully homomorphic encryption