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}
对不起,文字太长了;我的问题是
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元素使用相同的随机过程,而不使用上面的蛮力
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