根据给定的汉明距离折叠字符串集

时间:2019-11-06 12:44:07

标签: python unix hamming-distance

给出一组字符串(第一列)和计数(第二列),例如:

aaaa 10
aaab 5
abbb 3
cbbb 2
dbbb 1
cccc 8

是否存在任何算法或什至实现(理想情况下是Unix执行程序,R或python),可以根据给定的汉明距离将此集合折叠为新集合。

  • 折叠意味着增加计数
  • 计数较低的字符串将折叠为计数较高的字符串。

例如,对于汉明距离1,上述集合会将第二个字符串aaab折叠成aaaa,因为它们相距1个汉明距离,并且aaaa的计数更高。 折叠后的条目将具有组合计数,此处为aaaa 15

因此,对于此集合,我们将获得以下折叠的集合:

aaaa 15
abbb 6
cccc 8

理想情况下,实现应该是有效的,因此即使不能保证最佳解决方案的启发式方法也会受到赞赏。

其他背景和动机

大多数编程语言都实现了计算2个字符串(一对)之间的汉明距离。蛮力解决方案将计算所有对之间的距离。也许没有办法解决。但是例如我以为有效的解决方案可以避免计算所有对的距离等。也许有一些聪明的方法可以基于度量理论来保存一些计算(因为汉明距离是度量)。如果x和z之间的汉明距离为3,x和y为3,则可以避免在y和z之间进行计算。也许有一个聪明的k-mer方法,或者某个恒定距离的有效解决方案(例如d=1)。

即使只有蛮力解决方案,我也想知道它是否曾经实施过以及如何使用(理想情况下无需我自己实施)。

1 个答案:

答案 0 :(得分:2)

我想到了以下内容:

这将报告得分最高的项目,并将其得分与附近邻居的得分相加。一旦使用邻居,就不会单独报告。

我建议使用Vantage-point树作为度量指标。

算法如下:

  1. 根据字符串及其得分构建指标索引
  2. 根据字符串及其分数构建最大堆
  3. 对于最大堆中得分最高的字符串:
  4. 使用指标索引来查找字符串附近的
  5. 打印字符串,并按字符串显示其分数与附近的总和
  6. 从指标索引中删除字符串和字符串附近的每个字符串
  7. 从最大堆中删除字符串和每个字符串附近的字符串
  8. 重复3-7,直到最大堆为空

也许可以通过使用已用表而不是删除任何内容来简化此操作。度量空间索引不需要有效删除,最大堆也不需要支持按值删除。但是,如果社区很大且经常重叠,则速度会较慢。因此有效的删除可能是一个必要的困难。

  1. 根据字符串及其得分构建指标索引
  2. 根据字符串及其分数构建最大堆
  3. 从一个空集中构造使用过的表
  4. 对于最大堆中得分最高的字符串:
  5. 如果此字符串在使用的表中:从下一个字符串重新开始
  6. 使用指标索引来查找字符串附近的
  7. 通过使用表中的字符串删除所有附近
  8. 打印字符串,并按字符串显示其分数与附近的总和
  9. 将字符串附近的字符串添加到使用的表中
  10. 重复4-9,直到最大堆为空

我无法提供复杂性分析。

我正在考虑第二种算法。我认为比较慢的部分是针对使用过的桌子检查邻居。不需要这样做,因为可以在线性时间内从Vantage点树中删除。在搜索邻居时,请记住在哪里找到他们,然后稍后使用这些位置将其删除。如果将邻居用作优势点,请将其标记为已删除,以便搜索不会返回它,否则将其保留。我认为这可以将其恢复到二次方以下。否则,它将类似于项目数量乘以邻域大小。


回应评论。问题是“计数较低的字符串折叠为计数较高的字符串”。因此,这确实可以进行计算。这不是贪婪的近似,因为没有任何要最大化或最小化的结果,因此可能导致非最佳结果。这是一个精确的算法。它返回得分最高的项目以及其邻域的得分。

这可以看作是为每个邻域分配一个领导者,以使每个项目最多具有一个领导者,并且该领导者迄今为止拥有最高的总分。可以将其视为有向图。

该规范不适用于动态编程或优化问题。为此,您需要在总得分最高的社区中获得得分最高的项目。也可以通过将排名函数字符串从其得分更改为得分及其邻域和得分之和的对来解决此问题。

这确实意味着它不能用最大的堆来解决,因为删除项目会影响邻居的邻居,因此必须重新计算其邻居得分,然后才能再次找到总得分最高的项目。