我正在寻找一种算法来解决,或者至少是一个适当的名称来解决以下问题:
我有一组 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
。下一步是什么?
答案 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难的。