Algorithm 是否可以从表中索引唯一排列? 索引编号显示特定和唯一排列的算法?

Algorithm 是否可以从表中索引唯一排列? 索引编号显示特定和唯一排列的算法?,algorithm,math,Algorithm,Math,想象一个有4列的表 每列有1000个元素 从每列中随机选择一个元素会导致1万亿次排列。(1000^4) 如果不对这些万亿排列中的每一个进行索引,那么就有可能分配一个索引编号,从1万亿到1万亿,代表一个特定排列。理想的, 提供索引号将产生唯一的排列 这里是棘手的部分:当查看两个紧密相连的索引号(例如:12345和12346)时,这两个排列不应该看起来几乎是随机的——它们不应该看起来像是紧密相关的 示例:如果每个元素都是一个单词 以下是可以接受的,因为每个索引编号代表一组明显不同的单词: 12345

想象一个有4列的表

每列有1000个元素

从每列中随机选择一个元素会导致1万亿次排列。(1000^4)

如果不对这些万亿排列中的每一个进行索引,那么就有可能分配一个索引编号,从1万亿到1万亿,代表一个特定排列。理想的, 提供索引号将产生唯一的排列

这里是棘手的部分:当查看两个紧密相连的索引号(例如:12345和12346)时,这两个排列不应该看起来几乎是随机的——它们不应该看起来像是紧密相关的

示例:如果每个元素都是一个单词

以下是可以接受的,因为每个索引编号代表一组明显不同的单词:

123456 = apple, banana, cow, dog
123457 = elephant, fox, goat, hippo
123458 = iguana, jackal, kangaroo, lion
123459 = mouse, newt, octopus, pig
123460 = apple, fox, newt, lion
(注意:重复几次当然没问题——只是不要太频繁)

以下情况是不可接受的,因为附近的索引编号会导致非常相似的结果:

123456 = apple, banana, cow, dog
123457 = apple, banana, cow, elephant
123458 = apple, banana, cow, fox
123459 = apple, banana, cow, goat
这个解决方案应该是可伸缩的——我应该能够改变,一列中有10000个元素而不是1000个,我应该能够有10列而不是4列

有什么想法吗


附加细节:由于空间要求,我不想存储实际索引,但我希望索引编号能够被分解,以指向它引用的确切排列。

我建议分两步解决这个问题

  • 创建一个不满足本地约束的简单索引。例如,按字典顺序排列集合。例如,假设您有4列,每列中有1000个元素,则每列的数量从0到1000不等。集合
    [2100,4927]
    具有索引
    002 100 004 927
    。请注意,此顺序中的to连续元素仅在最后一列中有所不同,这是不需要的

  • 对索引应用一些散列函数。例如,假设您有一个哈希函数
    f
    ,它具有
    f(5)=394 033 748 123
    f(6)=921 038 839 104
    。您使用散列的结果作为步骤1的索引。输入中的两个连续索引现在具有非常不同的输出(前提是哈希函数工作正常)

  • 想到的最“方便”的解决方案是使用一个简单的“元索引”,它组合了每列的索引,然后对生成的索引使用某种加密来生成“官方”索引

    给定一个任意数字,然后解密它并分离出组件索引

    我最初的直觉是建议使用散列函数而不是加密,但散列函数不容易反转(这意味着您无法为给定的索引生成元组),而且很难创建具有最小空槽或重叠的函数

    您可以通过加密算法中位的转置程度来控制索引组件的可预测程度。如果用一个键对每个字节进行异或运算,列索引将不会连续,但关系将存在。但是,如果将位与相邻(或非相邻)字节交换,则会使每个索引的表示形式非定域化。(我不一定推荐,但值得一看,以了解哪些内容容易隐藏。)


    一个警告:如果希望每个索引都与有效的元组匹配,则需要确保以某种方式获取每个组件索引的每个值。这完全是另一种讨论。

    似乎最简单的解决方案是将以10为基数的数字转换为以1000为基数的数字。但是,它只在列限制为每个元素不超过1000个时才起作用

    下面是Python中的代码

    def convertToBase(number,base,min_digits):
        n = number
        value = []
        while n > 0:
            value.append(n % base)
            n = int(n/base)
        while len(value) < min_digits:
            value.append(0)
        return value
    
    def转换器底座(数字、基数、最小位数):
    n=数量
    值=[]
    当n>0时:
    附加值(n%base)
    n=int(n/base)
    而len(value)

    其中,基数为1000,最小位数为4(确保四列)。结果值就是你的排列。

    索引紧密的意义是结果非常相似还是其他什么?你到底想实现什么?是否有实际问题需要解决,或者此代码是否为高尔夫?