我看到这篇文章:Finding even numbers in an array我正在思考如何在没有反馈的情况下做到这一点。这就是我的意思。
给定一个长度为n的数组,其中包含最多
e
偶数和a 函数isEven
如果输入是偶数和假,则返回true 否则,写一个打印所有偶数的函数 使用isEven
调用次数最少的数组。
这篇文章的答案是使用二进制搜索,这很整洁,因为它并不意味着数组必须按顺序排列。如果数字为偶数,则必须e log n
代替n
因为您进行二分搜索(log n
)以便每次都找到一个偶数({{1}时间)。
但是这个想法意味着你将数组分成两半,测试均匀度,然后根据结果决定保留哪一半。
我的问题是你是否可以在一个固定的测试计划上打e
个电话,你可以在不知道结果的情况下检查你想要的所有数字,然后找出偶数后的数字。我们根据结果完成了所有测试。所以我想这不是反馈或盲目或类似的术语。
我有一段时间没想过这件事,也无法想出任何东西。二元搜索的想法在这个约束下根本不起作用,但也许其他的东西呢?即使是n
来电而不是n/2
(是的,我知道他们是同一个大O)也不错。
答案 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 qi
和0
} 除此以外。例如,如果qi = 3^2
,则行2
在其他地方的列2, 11, 20, ... 2 + 9j
和0
中都有。
现在垂直堆叠这些矩阵以获得Q x N
矩阵M
,其中Q = q1 + q2 + ... + qk
。 M
行告诉您哪些数字相乘(非零位置)。这样可以提供总共需要测试均匀度的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 article或this paper。
对于自适应测试,上限为 O(d*log(N))
(如this answer中所述)。
对于非自适应测试,可以显示上限是 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)
不完全是一个解决方案,但只是一些想法。
很容易看出,如果阵列长度为n的解决方案需要少于n次测试,则对于任何数组长度m> 1。很容易看出,总有一种解决方案的测试时间少于m次。所以,如果你有n = 2或3或4的解决方案,那么问题就解决了。
你可以将数组拆分成数字对和每对:如果总和是奇数,那么其中只有一个是偶数,否则如果其中一个是偶数,那么它们都是偶数。对于每对,这种方式需要一次或两次测试。最佳案例:n / 2次测试,更糟糕的情况:n次测试,如果选择偶数和奇数,则:3n / 4次测试。
我的预感是没有少于n次测试的解决方案。不知道如何证明它。
更新:第二种解决方案可以通过以下方式进行扩展。
检查两个数字的总和是否为偶数。如果奇怪,那么其中只有一个是偶数。否则将该组标记为“大小为2的同类组”。取两个相同大小的“同质集”n。从每组中选择一个数字并检查它们的总和是否均匀。如果是偶数,则将这两组合并为“均匀的2n大小”。否则,它意味着其中一个集合纯粹由偶数组成,另一个纯粹由奇数组成。
最佳案例:n / 2次测试。平均情况:3 * n / 2。最坏的情况仍然是n。只有当所有数字都是偶数或所有数字都是奇数时,才会出现最坏情况。
答案 5 :(得分:0)
如果我们可以添加和乘法数组元素,那么我们可以在低位上计算每个布尔函数(直到补码)。模拟一个编码偶数位置的电路,编号为0到nC0 + nC1 + ... + nCe - 1用二进制表示,并使用isEven
调用来读取这些位。
使用的呼叫数量:信息理论最优中的1个。