繁体   English   中英

预期的最大数量

[英]Expected number of maxima

我有算法,它以数组作为参数,并返回其最大值。

find_max(as) :=
    max = as[0]
    for i = 1 ... len(as) {
        if max < as[i] then max = as[i]
   }
    return max

我的问题是:假设数组最初处于(统一)随机排列并且其所有元素都是不同的,那么max变量的预期次数是多少(忽略初始赋值)。

例如,如果as = [1, 3, 2] ,那么max的更新次数将为1(当读取值3时)。

假设原始数组包含值1,2,...,N。

设X_i,i = 1..N是随机变量,如果i在算法期间的某个点处为最大值,则取值1。

然后算法采用的最大值数是随机变量:M = X_1 + X_2 + ... + X_N。

平均值(根据定义)E(M)= E(X_1 + X_2 + ... + X_N)。 使用期望的线性,这是E(X_1)+ E(X_2)+ .. + E(X_N),这是概率(1表示为最大值)+概率(2表示为最大值)+ ... +概率(N显示为最大值)(因为每个X_i取值0或1)。

我什么时候出现最大值? 它出现在i,i + 1,i + 2,...,N之间的数组中。它的概率是1 /(N-i + 1)(因为这些数字中的每一个都同样可能是第一)。

所以...... prob(我出现最大值)= 1 /(N-i + 1),总体期望值是1 / N + 1 /(N-1)+ .. + 1/3 + 1/2 + 1/1

这是谐波(N),其近似于ln(N)+ emc,其中emc~ = 0.5772156649,Euler-Mascheroni常数。

由于在该问题中您没有将最大值的初始设置计数为第一个值作为一个步骤,因此实际答案是Harmonic(N)-1或大约ln(N) - 0.4227843351。

快速检查一些简单的情况:

  • N = 1,只有一个排列,没有最大更新。 谐波(1) - 1 = 0。
  • N = 2,排列为[1,2]和[2,1]。 第一次更新最大值,第二次更新零次,因此平均值为1/2。 谐波(2) - 1 = 1/2。
  • N = 3,排列为[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2] ,1]。 最大更新分别为2,1,1,1,0,0。 平均值为(2 + 1 + 1 + 1)/ 6 = 5/6。 谐波(3) - 1 = 1/2 + 1/3 = 5/6。

所以理论上的答案看起来不错!

实证解

可以执行和分析许多不同阵列大小的模拟,每个阵列具有多个试验:

#include <iostream>
#include <fstream>
#include <cstdlib>
#define UPTO 10000
#define TRIALS 100

using namespace std;

int arr[UPTO];

int main(void){
  ofstream outfile ("tabsep.txt");
  for(int i = 1; i < UPTO; i++){
    int sum = 0;
    for(int iter = 0; iter < TRIALS; iter++){
      for(int j = 0; j < i; j++){
        arr[j] = rand();
      }
      int max = arr[0];
      int times_changed = 0;
      for(int j = 0; j < i; j++){
        if (arr[j] > max){
          max = arr[j];
          times_changed++;
        }
      }
      sum += times_changed;
    }
    int avg = sum/TRIALS;
    outfile << i << "\t" << avg << "\n";
    cout << "\r" << i;
  }
  outfile.close();
  cout << endl;
  return 0;
}

当我绘制这些结果时,复杂性似乎是对数的:

数组大小与最大值更改的平均次数


我认为可以安全地得出时间复杂度为O(log n)的结论。


理论解决方案

  • 假设数字在0 ... n范围内
  • 你有一个暂定的最大值m
  • 下一个最大值将是m + 1 ... n范围内的随机数,平均值为(m + n)/ 2
  • 这意味着每次找到新的最大值时,您将可能的最大值范围除以2
  • 重复除法相当于对数
  • 因此,找到新的最大值的次数是O(log n)

最坏的情况(通常是所寻求的)是O(n)。 如果列表按相反顺序排序,则每个列表都将导致分配。

但是,如果您的作业是最昂贵的操作,为什么不存储它的索引并且只复制一次,如果有的话? 在这种情况下,您将完成1次分配和n-1次比较。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM