笛卡尔积 算法
是否曾经尝试过生成42个大集合/序列的笛卡尔乘积,只是为了获得乘积的236指数?
技巧问题:您没有足够的存储空间! (大概)
值得庆幸的是,有一种算法可以快速获取您想要的任何索引!
有时,您只需要计算非常大的笛卡尔乘积即可使用结果中的少数索引。 问题在于,生成整个事物的过程很慢,而且常常是很多次,以至于您的内存甚至无法处理。
这就是促使我想出这个算法,显然这是真的很难找到在互联网(至少我无法找到它)上。 因此,我继续询问其他人,他们也证实,尽管许多人都知道该算法,但在互联网上找不到它。 所以我在这里发布帖子,希望人们以后可以找到:)
它有什么作用?
假设我们有3个序列-
- 答:
{1, 2, 3}
- B:
{2, 6, 7, 9}
- C:
{1, 7}
只需调用get_tuple_by_index
并传递序列的列表/数组(即[A, B, C]
或{A, B, C}
)和所需结果的索引。
对于C
(编程语言),您还需要传递序列数 (在这种情况下为3
)和包含每个序列的长度的数组 (在这种情况下为 {3, 4, 2}
)。
例如,如果我们用笛卡尔积A x B x C
的第六个索引 (从0开始)调用get_tuple_by_index
,我们将得到(1, 9, 1)
get_tuple_by_index
(1, 9, 1)
它是如何工作的?
对于此演示,我们将使用上面提到的序列作为示例
- 我们希望笛卡尔积在这种情况下为
[A, B, C]
或{A, B, C}
的序列list
/array
被反向迭代。 - 在每次迭代中,
result tuple
都从向后填充。 - 在每次迭代中,
result tuple
的current element
将是当前集合的index % length_of_current_set
th。 - 此外,在每次迭代中,
index
都设置为index // length_of_current_set
其中//
表示整数除法。因此,在这种情况下,在第一次迭代中,对于index = 6
,current element
将为C[6 % 2]
或C[0]
或1
。 现在将其添加为result tuple
的最后一个元素 。 现在看起来像->(1)
index
现在设置为6 // 2
或3
在第二次迭代中, current element
将为B[3 % 4]
或B[3]
或9
。
现在将其添加为result tuple
倒数第二个元素 。 现在看起来像-> (9, 1)
index
现在设置为3 // 4
或0
在第三次迭代中, current element
将为A[0 % 3]
或A[0]
或1
。
现在将其添加为result tuple
倒数第三个元素 (在本例中为第一个元素)。 现在看起来像-> (1, 9, 1)
代码
太酷了! 这是一些伪代码来演示算法-
getNthTuple(sets, pos):
tuple = ()
for i in [(|sets|-1)..0]:
set = sets[i]
elem = set[pos mod |set|]
tuple = (elem, tuple)
pos = pos // |set|
return tuple
如果您想以真实的编程语言查看示例,可以在这里找到java
, python
和C
版本!
翻译自: https://dev.to/totally_chase/cool-algorithm-calculating-any-index-of-a-cartesian-product-1g8i
笛卡尔积 算法