在长度为a
的排序数组n
上考虑以下随机搜索算法(按递增顺序)。 x
可以是数组的任何元素。
size_t randomized_search(value_t a[], size_t n, value_t x)
size_t l = 0;
size_t r = n - 1;
while (true) {
size_t j = rand_between(l, r);
if (a[j] == x) return j;
if (a[j] < x) l = j + 1;
if (a[j] > x) r = j - 1;
}
}
从x
中随机选择a
时,此功能的Big Theta complexity(下限和上限)的期望值是多少?
虽然这似乎是log(n)
,但我进行了一项指令计数实验,发现结果的增长速度比log(n)
快一点(根据我的数据,甚至是(log(n))^1.1
更好地适应结果)。
有人告诉我,这个算法有一个精确大的theta复杂度(显然log(n)^1.1
不是答案)。那么,您能否将时间复杂性与您的方法一起证明呢?感谢。
更新:我的实验数据
log(n)
符合mathematica的结果:
log(n)^1.1
符合结果:
答案 0 :(得分:5)
如果您愿意切换到计算三向比较,我可以告诉您确切的复杂性。
假设密钥位于位置i,我想知道与位置j的预期比较数。我声称,当且仅当它是i和j之间的第一个位置进行检查时,才检查位置j。由于每次都是随机均匀地选择枢轴元素,因此概率为1 /(| i - j | + 1)。
总复杂度是对sum_ {j = 1} ^ n 1 /(| i - j | + 1)的i&lt; - {1,...,n}的期望,这是
sum_{i=1}^n 1/n sum_{j=1}^n 1/(|i - j| + 1)
= 1/n sum_{i=1}^n (sum_{j=1}^i 1/(i - j + 1) + sum_{j=i+1}^n 1/(j - i + 1))
= 1/n sum_{i=1}^n (H(i) + H(n + 1 - i) - 1)
= 1/n sum_{i=1}^n H(i) + 1/n sum_{i=1}^n H(n + 1 - i) - 1
= 1/n sum_{i=1}^n H(i) + 1/n sum_{k=1}^n H(k) - 1 (k = n + 1 - i)
= 2 H(n + 1) - 3 + 2 H(n + 1)/n - 2/n
= 2 H(n + 1) - 3 + O(log n / n)
= 2 log n + O(1)
= Theta(log n).
(log表示自然日志。)请注意低位项中的-3。这使得看起来比较的数量在开始时比对数增长得快,但是渐近行为表明它会趋于平稳。尝试排除小n并重新设置曲线。
答案 1 :(得分:2)
假设rand_between
在恒定时间内从均匀概率分布实现采样,该算法的预期运行时间为Θ(lg n )。证明的非正式草图:rand_between(l, r)
的预期值为(l+r)/2
,即它们之间的中点。所以每次迭代都要跳过一半的数组(假设大小是2的幂),就像二次搜索的单次迭代一样。
更正式地说,借鉴quickselect的分析,观察当你选择一个随机中点时,它将在¼ n 和¾ n之间的一半时间< / em>的。左或右子阵列都不具有多于3/4 n 元素。另一半的时间,都没有超过 n 元素(显然)。这导致了重现关系
T(n) = ½T(¾n) + ½T(n) + f(n)
其中f( n )是每次迭代中的工作量。从两侧减去½T(n),然后将两边加倍,我们有
½T(n) = ½T(¾n) + f(n)
T(n) = T(¾n) + 2f(n)
现在,因为2f( n )=Θ(1)=Θ( n ᶜlog⁰ n )其中 c < / em> = log(1)= 0,它遵循主定理T(n)=Θ( n ⁰lg n )=Θ(lg 名词的)。