【发布时间】:2021-09-03 10:56:48
【问题描述】:
给定一个包含 20 个浮点数的列表,我想找到一个最大的子集,其中任意两个候选者彼此不同,大于 mindiff = 1.。现在我正在使用蛮力方法使用itertools.combinations 从最大到最小的子集进行搜索。如下所示,代码在 4 秒后为 20 个数字的列表找到一个子集。
from itertools import combinations
import random
from time import time
mindiff = 1.
length = 20
random.seed(99)
lst = [random.uniform(1., 10.) for _ in range(length)]
t0 = time()
n = len(lst)
sample = []
found = False
while not found:
# get all subsets with size n
subsets = list(combinations(lst, n))
# shuffle to ensure randomness
random.shuffle(subsets)
for subset in subsets:
# sort the subset numbers
ss = sorted(subset)
# calculate the differences between every two adjacent numbers
diffs = [j-i for i, j in zip(ss[:-1], ss[1:])]
if min(diffs) > mindiff:
sample = set(subset)
found = True
break
# check subsets with size -1
n -= 1
print(sample)
print(time()-t0)
输出:
{2.3704888087015568, 4.365818049020534, 5.403474619948962, 6.518944556233767, 7.8388969285727015, 9.117993839791751}
4.182451486587524
但是,实际上我有一个包含 200 个数字的列表,这对于暴力枚举是不可行的。我想要一种快速算法来仅采样一个 random 最大 子集,其最小差异大于 1。请注意,我希望每个样本都具有随机性和最大大小。有什么建议吗?
【问题讨论】:
-
对列表进行抽样并选择相差超过 1.0 的元素来构建集合?
-
@rdas 是的。子集编号必须彼此不同,因此它必须是一个集合。但这并不重要。
-
看来已经发布的答案就足够了。它考虑到集合中的最小值将始终存在于最大子集中。因此,之后取每个大于 1 的值
-
@Onyambu 是的,现在我明白这已经足够了,但我完全忘记了我的目的是随机抽样!我只是在我的问题中强调了这一点。我的错。
标签: python python-3.x list algorithm random