[英]Get subscripts from linear index into product of infinite generators
我有N
无限生成器。 我已经知道如何取这些无限生成器的笛卡尔积,因为这里列出了几种方法(“之字形”,“扩展平方”等)。 我真的不在乎哪种方法用作我真正想要的基础: 我想将“索引到笛卡尔乘积中”转换成“索引到原始生成器中的元组”,而无需实际迭代笛卡尔积点。 我很清楚,我实际上无法索引生成器。 很好,因为我需要的只是索引本身。 基本上,我想要这里描述的相同内容,但适用于无限生成器。
如果我们考虑一个具体的例子,这将是最容易理解的。 让我们考虑两个生成器( N=2
),并将它们都设为itertools.count()
以便生成器的索引和生成器的值都相同。
from itertools import count
a = count() # 0, 1, 2, ...
b = count() # 0, 1, 2, ...
假设我使用之字形算法是因为作者非常乐意将其提供给PyPI使用。
from infinite import product
p = product(a, b) # (0,0), (0,1), (1,0), (0,2), (1,1), (2,0), ...
我想要一个函数,给定p
的索引,将索引的元组返回a
和b
,如下所示:
f(2) # (1,0)
f(4) # (1,1)
同样,它不必是Zig-zag算法的线性索引。 可以在无限生成器上生成笛卡尔积的任何算法都可以用作基础。
您正在尝试反转配对功能 。 作为示例,您给出的“ zig-zag”算法是Cantor配对函数 (最多可更改参数顺序),由f(x, y) = (x+y)(x+y+1)/2 + y
,并且具有反函数如下。
如果f^-1(z) = (x, y)
,则
w = floor((sqrt(8z+1)-1)/2)
t = w(w+1)/2
y = z-t
x = w-y
您可以查看Wikipedia链接以获取完整的派生信息。
生成笛卡尔乘积的各种方法都是同一过程的所有变体:
将产品元组划分为无数个有限大小的块;
依次在每个块中生成元组。
“ zigzag”方法和Cantor函数,例如,按索引总和进行分块:
For integer i = 0 to infinity
generate all tuples with sum(component_indexes) == i
“扩展平方法”为:
For integer i = 0 to infinity
generate all tuples with max(component_indexes) == i
等等...
要直接为任何这些方法找到第k个元组,您可以:
对于N维中的“扩展平方”方法,例如, SMALLER(i)= i ^ N-所有分量都小于i的元组数,因此i = floor(Nth_root(k)) 。 令r = k-i ^ N ,然后找到最大成分等于k的第r个元组(例如,按词法顺序)。
但是,直接索引最简单的一种产品是比特交错 。 在该方案中,以循环方式将乘积索引的二进制扩展中的连续位分配给组件索引。 在python中,它看起来像这样:
def getProductTerm(dimensions, index):
ret=[0]*dimensions
bit=0
while index>0:
ret[dimensions-1-(bit%dimensions)]+=(index&1)<<(bit/dimensions)
index >>= 1
bit+=1
return ret
您可以在这里尝试: https : //ideone.com/0dTMU3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.