繁体   English   中英

从线性索引中获取下标到无限生成器的乘积中

[英]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的索引,将索引的元组返回ab ,如下所示:

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链接以获取完整的派生信息。

生成笛卡尔乘积的各种方法都是同一过程的所有变体:

  1. 将产品元组划分为无数个有限大小的块;

  2. 依次在每个块中生成元组。

“ 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个元组,您可以:

  1. SMALLER(i)为小于i的块中的元组数。 找到最大值i ,使SMALLER(i)<= k 这是包含第k个元组的块的编号。
  2. 获取块编号为i的 第(k-SMALLER(i))个元组(从零开始)。

对于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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM