【问题标题】:Minimal bitstring set union with shifts algorithm带移位算法的最小位串集联合
【发布时间】:2016-08-06 06:05:21
【问题描述】:

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


我有一组 B 位串。该算法应该找到一个最小(定义为“设置最少的位”)位串 S,这样:

对于B中的所有b,存在移位N em>(在)这样(S << N) & b == b


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


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

这在我看来像是某种multiple sequence-alignment 问题。

如果我们可以为 B中的每个 bi 找到每个 Ni > (i = 1 .. |B|),看起来 S 只是所有 (b i >> Ni).

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

【问题讨论】:

  • ℤ 中的移位量很有趣,这是否意味着负的左移位相当于右移位?
  • 我认为对于一组字符串来说这等于"Shortest common supersequence problem"。一般来说,它是 NP-Hard,但对于您的特定情况,解决它应该不会太难。
  • @harold 是的,负左移相当于右移。
  • @EvgenyKluev 谢谢,这看起来确实与那个问题有关。主要区别在于超序列中的 1 可以匹配要匹配的序列集中的 0。我想超序列可以由 X 和 0 组成,其中 X 表示“不关心”,0 表示“必须有 0”。
  • 与试图最小化长度的“最短公共超序列问题”的另一个重要区别是 AlliedEnvy 试图最小化设置为 1 的位数。

标签: algorithm set bit-manipulation sequence-alignment


【解决方案1】:

我的特定 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 上的循环以 Sb 的 LSB 对齐开始,然后转到最重要的一位Sb 对齐。


目前,我将问题保留为未解决,看看是否有合适的非暴力解决方案出现,或者直到有人说问题是 NP 难题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-26
    • 2014-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多