【问题标题】:Generating unambiguous fixed-length circular bit sequence生成明确的固定长度循环比特序列
【发布时间】:2020-07-03 06:44:57
【问题描述】:

我正在做一项研究,其中使用了一种明确的固定长度单位比特序列生成算法。假设我们使用k位,为简单起见,假设k=3,我们可以将整数0 ~ 7转换为000~111,命名为code units。 现在我想得到一个序列s,其中:

(i)。 s是一个循环比特序列,即s_1, s_2 ... s_n =(functions as) s_2, s_3 ... s_n, s_1

(ii)。 s 是通过将所有 code units 与固定长度重叠连接一次而构造的。 s 中的每一位都对 k 原始代码单元有贡献。所以s的长度是2^k

(iii)。在已知s 的情况下,给定任何连续的k 0-1 位(1 个代码单元),我们可以在s 中唯一地定位该代码单元。

我写了一个程序在k=3下找到s

# -*- coding: utf-8 -*-

import math
from itertools import permutations
import numpy


def is_legal_seq(seq, k):
    seen_set = set()
    len_seq = len(seq)
    seq = seq + seq[:k]
    for i in range(len_seq):
        cu = seq[i:i+k]
        if cu in seen_set:
            return False
        else:
            seen_set.add(cu)
    if len(seen_set) != int(math.pow(2, k)):
         return False
    return True


k = 3
n_cu = int(math.pow(2, k))

root_str = (n_cu//2 - k) * '0' + n_cu // 2 * '1'
per_strs = list(set("".join(p) for p in permutations(root_str)))
per_strs = ["0" * k + i for i in per_strs]

# should equal to scipy.comb(n-k, n/2-k)
print(f"count permutations: {len(per_strs)}")

for i in range(len(per_strs)):
    if is_legal_seq(per_strs[i], k):
        print(f"satisfying: {per_strs[i]}")

输出:

count permutations: 5
satisfying: 00011101
satisfying: 00010111

00011101为例,它可以按顺序明确解释为代码单元: 000, 001, 011, 111, 110, 101, 010, 100。 更重要的是,没有重复。每个可能的代码单元只出现一次。

这里我使用了固定的k 前缀“0”来避免删除循环重复。而且我发现我需要测试Combination(2^k-k, 2^k/2-k) 可能的序列以确定哪个是合法的。

但是当更改为k=6 时,程序似乎需要更多时间来输出(2.2e16 次测试)。 如何通过其他方式找到s

【问题讨论】:

    标签: python string algorithm math permutation


    【解决方案1】:

    您似乎想在 0/1 字母表上构建 de Brujin sequence

    来自上述链接的 Python 代码,其 2/3 输出类似于您的 00010111:

    def de_bruijn(k, n: int) -> str:
        """
        de Bruijn sequence for alphabet k
        and subsequences of length n.
        """
        try:
            # let's see if k can be cast to an integer;
            # if so, make our alphabet a list
            _ = int(k)
            alphabet = list(map(str, range(k)))
    
        except (ValueError, TypeError):
            alphabet = k
            k = len(k)
    
        a = [0] * k * n
        sequence = []
    
        def db(t, p):
            if t > n:
                if n % p == 0:
                    sequence.extend(a[1:p + 1])
            else:
                a[t] = a[t - p]
                db(t + 1, p)
                for j in range(a[t - p] + 1, k):
                    a[t] = j
                    db(t + 1, t)
        db(1, 1)
        return "".join(alphabet[i] for i in sequence)
    
    print(de_bruijn(2, 3))
    print(de_bruijn("abcd", 2))
    which prints
    
    00010111
    aabacadbbcbdccdd
    

    【讨论】:

    • 是的。我确实认为可能有人在这方面工作过。
    猜你喜欢
    • 2016-10-16
    • 2019-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多