最小位串集合与移位算法

时间:2016-04-14 15:13:48

标签: algorithm set bit-manipulation sequence-alignment

我正在寻找一种算法来解决,或者至少是一个适当的名称来解决以下问题:

我有一组 B 的位串。该算法应找到最小值(定义为"设置最少位和#34;)bitstring S ,以便:

  

对于 B 中的所有 b ,存在转移 N (在中),(S << N) & b == b

如果有帮助,每个 b 适合机器字,| B |大约是几百个。

我认为我们可以假设(不失一般性) S 的LSB和每个 b 为1。

这让我觉得某种multiple sequence-alignment问题。

如果我们可以为 B 中的每个 b i 找到每个 N i >( i = 1 .. | B |),它看起来像 S 只是按位或所有( b) i &gt;&gt; N i )。

我的直觉是,第一步是从 B 中删除每个 b ,其中 B中存在另一个bitstring c 和一些转移 M ,使b & (c << M) == b。下一步是什么?

1 个答案:

答案 0 :(得分:0)

我的 B 的具体实例足够小,可以通过一些技巧来修剪搜索。

已定义以下功能

  • snoob,返回设置相同位数的次高编号(如Hacker's Delight图2-1(或最初为HAKMEM项目175)中所定义)
  • popcount,返回其参数中的1位数
  • clz,返回其参数最重要结尾的连续零数

我的解决方案的伪代码如下:

min_ones = max popcount(b) for b in B
max_ones = popcount(~0)

for i = 0 .. |B|-1:
    while !(B[i] & 1): B[i] >>= 1

found_ones = false
for ones = min_ones .. max_ones:
    if found_ones: break
    for S = (1 << ones)-1; clz(S) > 0; S = snoob(S):
        if !(S & 1): continue
        for b in B:
            found = false
            for N = 0 .. clz(b) - clz(S):
                if (S >> N) & b == b:
                    found = true
                    break
            if !found: break
         if found:
             print(S)
             found_ones = true

第一个循环向右移动 b ,因此其LSB为1;这允许我们以后只使用N的右移。

S 上的循环以设置了ones位的最小数字开始;循环停止条件不太正确,但它适用于我的目的。

N 上的循环以 S b 的LSB对齐开始,然后转到最重要的一位 S b 对齐。

现在,我将问题留下未解决的问题,看看是否有适当的非暴力解决方案,或者直到有人说问题是NP难的。