我的任务是:
生成唯一组合列表,其中每个组合都有一定的长度(var com_len)并包含给定列表(var values)中的值(ints),
每个组合都是通过从给定列表中获取随机值创建的(随机性非常重要!),
每个组合内部必须有唯一的值,组合内部不能重复任何值,
必须对组合中的值进行排序,
计算整个组合集中每个值的出现(var counter),
每个值在整个数据集中出现的次数必须尽可能接近给定的次数(var counter_expected)。“尽可能接近”的意思是,在脚本运行时计算每个出现的值,如果没有更多组合要创建,只需结束脚本。
例如,我需要生成一个组合列表,其中每个组合的长度为 3,内部具有唯一的排序值,每个值都来自范围(256),并且每个值出现在所有生成的组合中,直到接近尽可能100次。
我的问题是,如何有效地检测到没有更多独特的值组合可以创建来停止循环。
当脚本即将结束并且仍然存在可用值并且 len(available_values) > com_len 时会出现问题,但是无法创建尚未出现的任何新的唯一组合。
到目前为止创建的代码:
import numpy as np
import random
com_len = 3
length = 256
counter = np.zeros(length)
values = range(length)
exclude_values = []
counter_expected = 100
done = []
mask = np.ones(len(np.array(values)), np.bool)
mask[exclude_values] = False
available_values = set(values) - set(exclude_values)
available_values = list(available_values)
ii = 0
while True:
"""print progress"""
ii = ii + 1
if not ii % 1000: print('.', end='')
#POSSIBLE CONDITION HERE
ex = random.sample(available_values, k=com_len)
ex.sort()
if ex in done: continue
done.append(ex)
counter[ex] = counter[ex] + 1
for l_ in ex:
if counter[l_] == counter_expected:
del available_values[available_values.index(l_)]
if len(available_values) < com_len:break
if all(counter[mask] == counter_expected): break
#OR HERE
注意:脚本通常会成功结束,因为 len(available_values) < com_len 或 all(counter[mask] == counter_expected) 条件会破坏 While 循环。尝试多次运行脚本,在某些时候,您会观察到脚本进入无限循环,因为 len(available_values) >= com_len 但没有更多新的唯一条件可供创建,因此计数器不会增加。
我需要一个有效的条件来停止脚本。在这里使用 itertools.combinations 不是一个选项,因为 available_values 列表在开始时可能很长,即 10k 个元素。
当 len(available_values) 达到一定水平时,蛮力将使用 itertools.combinations 并检查是否有任何尚未创建的组合,但这是一个丑陋的解决方案。
可能有更好的方法不是我想出来的,而是你可能想出来的。我会很感激你的帮助。
慕婉清6462132
拉风的咖菲猫
忽然笑
相关分类