给定一个包含来自集合S中的元素的元组集合t,最有效的方法是构建成员不包含在t中的另一个集合?

问题描述

例如,假设我有一个(n,2)维度张量t,其元素全部来自包含随机整数的集合S。我想构建另一个张量d,其大小为(m,2),其中每个元组中的各个元素都来自S,但整个元组不会出现在t中。

例如

S = [0,1,2,3,7]
t = [[0,1],[7,3],[3,1]]

d = some_algorithm(S,t)

/* 
d =[[2,2],4]]
*/

在python中最有效的方法是什么?最好使用pytorch或numpy,但我可以解决一般的解决方案。

在我幼稚的尝试中,我只是使用

d = np.random.choice(S,(m,2))
non_dupes = [i not in t for i in d]
d = d[non_dupes]

但是t和S都非常大,并且要花费大量时间(更不用说,很少会生成(m,2)数组)。我觉得我必须要做一些花哨的张量操作才能实现这一目标,或者对t中的值进行大型哈希映射,因此检查t中的成员身份为O(1) ,但这只会在内存上产生相同的问题。有没有更有效的方法?

大概的解决方案也是可以的。

解决方法

我幼稚的尝试是将问题简化为整数集问题的基本转换功能:

定义和假设:

  • 让S成为集合(唯一元素)
  • 让L为S中的元素数
  • 让它成为带有S元素的M元组的集合
  • t中元素的原始顺序不相关
  • 让I(x)成为S中元素x的索引函数
  • 让x [n]成为t元素的第n个元组成员
  • 让f(x)是我们的基本变换函数(f ^ -1是其逆函数)

由于S是一个集合,我们可以使用S中的元素作为数字将t中的每个元素作为M位数字写入基数L。

对于M = 2,转换看起来像 f(x)= I(x [1])* L ^ 1 + I(x [0])* L ^ 0

f ^ -1(x)也是不重要的... x mod L以获取最低有效数字的索引。 floor(x / L)并重复直到提取所有索引。在S中查找值并构造元组。

因为现在您可以将t重新设置为一个整数集(读取hastable),计算逆集合d变得微不足道

从L ^(M-1)循环到(L ^(M + 1)-1),并询问您的哈希表元素是否在t或d中

如果S的大小太大,您也可以针对哈希表的t倒数的子集绘制随机数

这对您有帮助吗?

,

如果|t| + |d| << |S|^2,则在一次迭代中再次选择某个随机元组的概率相对较小。

更确切地说,如果(|t|+|d|) / |S|^2 = C代表某个常数C<1,则如果您重绘一个元素直到它成为“新”元素,则所需的重绘次数为1/(1-C)

这意味着,通过执行此操作并重新绘制元素直到这是一个新元素,您获得O((1/(1-C)) * |d|)次来处理一个新元素(平均),如果{{1 }}确实是恒定的。

可以通过以下几种方式来检查元素是否已经“可见”:

  • 保留O(|d|)C的哈希集。这需要额外的空间,但是每次查找都是t时间不变。您也可以使用bloom filter而不是存储已经看到的实际元素,这会产生一些错误,表示虽然已经“看到”了一个元素,但实际上却不是,但是别无选择-所以您仍然将d中的所有元素都设为唯一。
  • 就地排序O(1),并使用二进制搜索。这样会添加d预处理,并为每次查找添加t,但不需要额外的空间(除了存储O(|t|log|t|)的空间)。

如果实际上O(log|t|)非常接近d,那么|d| + |t|的时间解决方案可能是在可用选项上使用Fisher Yates shuffle ,然后选择第一个{未出现在|S|^2中的{1}}个元素。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...