Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.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
Python 样本在线数据算法分析_Python_Arrays_Algorithm_Random_Data Structures - Fatal编程技术网

Python 样本在线数据算法分析

Python 样本在线数据算法分析,python,arrays,algorithm,random,data-structures,Python,Arrays,Algorithm,Random,Data Structures,我正在阅读一本名为《编程面试要点》的书,但我遇到了以下问题: 实现一个算法,该算法以一个不同的数组作为输入 元素和大小,并返回给定大小的 数组元素。所有子集的可能性应相同。归还 结果是输入数组本身 他们提供的解决方案如下: import random def random_sampling(k, A): for i in range(k): # Generate a random index in [i, len(A) - 1]. r = random.r

我正在阅读一本名为《编程面试要点》的书,但我遇到了以下问题:

实现一个算法,该算法以一个不同的数组作为输入 元素和大小,并返回给定大小的 数组元素。所有子集的可能性应相同。归还 结果是输入数组本身

他们提供的解决方案如下:

import random
def random_sampling(k, A):
    for i in range(k):
        # Generate a random index in [i, len(A) - 1].
        r = random.randint(i, len(A) - 1)
        A[i], A[r] = A[r], A[i]


A = [3, 7, 5, 11]
k = 3

print(random_sampling(k, A))
我不明白作者凭直觉想做什么。他们的解释如下

另一种方法是枚举大小为k的所有子集,然后选择 从这些中随机抽取一个。由于存在大小为k的(n到k)子集, 时间和空间的复杂性是巨大的。提高效率的关键 构建一个大小正好为k的随机子集首先要构建一个 大小为k-1,然后再添加一个元素,从中随机选择 其余的。当k=1时,问题很简单。我们打一个电话给 随机数生成器,取返回值mod n(称为r), 并将[0]与[r]交换。条目A[0]现在保存结果

对于k>1,我们从如上所述随机选择一个元素开始,然后 现在对n-1元素子数组A[1,n-1]重复相同的过程。 最终,随机子集占据插槽A[0,k-1]和 其余元素位于最后的n-k插槽中

直观地说,如果大小为k的所有子集的可能性相等,则 构造过程确保大小为k+1的子集也 同样可能。对此的正式证明使用数学归纳法- 归纳假设是每一个大小为k的排列 A的子集同样可能位于A[0,k-1]中

作为一个具体的例子,让输入为a=和大小 3岁。在第一次迭代中,我们使用随机数生成器 在区间[0,3]中选取一个随机整数。让返回的结果随机 数字是2。我们将[0]与[2]交换-现在数组是。 现在我们在区间[1,3]中选取一个随机整数。让他回来 随机数应该是3。我们将[1]与[3]交换,现在是结果数组 是现在我们在区间[2,3]中选取一个随机整数。 让返回的随机数为2。当我们将[2]与自身交换时 结果数组不变。随机子集首先由he组成 三个条目,即{5,11,3}

对不起,文字太长了;我的问题是

  • 他们所指的效率的关键是什么?它没有在我的头脑中点击
  • 他们所说的“最终,随机子集占据插槽A[0,k-1],其余元素位于最后的n-k插槽”是什么意思
  • “a的每个大小为k的子集的每个置换都同样可能位于a[0,k-1]中”有明确的原因吗
  • 你能更清楚地解释算法背后的理论吗
  • 算法的返回应该是什么
  • 谢谢

  • 直观的解决方案可能是
  • 但不清楚每个k子集的概率是否相等(因为对于同一个k,在不同的范围内可能使用不同数量的随机数)

    因此,符合概率条件的解将

    import itertools as it
    def random_sampling(k, A):
        index_posibilities = [i for i in it.combinations(A,k)] #very expansive action
        index = random.randint(0, len(index_posibilities) - 1)
        selected = []
        for i in index:
            selected.append(A[i])
        return selected
    
    因此,他们给出的解决方案确保对每一组k元素使用相同的随机过程,而不使用上面的蛮力

  • 现在列表的顺序是,前k个元素是我们选择的,其余的是剩余的项目

  • 这是归纳假设,我假设长度为k-1的每个集合都有相同的概率,并证明了长度为k的集合

  • 确保每个k大小子集的概率相同的一种有效方法是执行完全相同的步骤来生成它

  • 没有返回值,因为函数中的列表正在更改,而main中的列表也在更改,子集是调用函数后列表的前k个元素

  • (这里的问题太多了……)你明白那行
    A[i],A[r]=A[r],A[i]
    在做什么吗?对我来说,这似乎是这个算法的关键。第5条:“返回
    return
    语句从函数返回一个值。
    return
    不带表达式参数返回
    None
    。从函数末尾脱落也返回
    None
    ”()。因此,它返回并打印
    None
    (顺便说一句,如果您运行它,您也可以看到)。
    import itertools as it
    def random_sampling(k, A):
        index_posibilities = [i for i in it.combinations(A,k)] #very expansive action
        index = random.randint(0, len(index_posibilities) - 1)
        selected = []
        for i in index:
            selected.append(A[i])
        return selected