给出一组字符串(第一列)和计数(第二列),例如:
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
)。
即使只有蛮力解决方案,我也想知道它是否曾经实施过以及如何使用(理想情况下无需我自己实施)。
答案 0 :(得分:2)
我想到了以下内容:
这将报告得分最高的项目,并将其得分与附近邻居的得分相加。一旦使用邻居,就不会单独报告。
我建议使用Vantage-point树作为度量指标。
算法如下:
也许可以通过使用已用表而不是删除任何内容来简化此操作。度量空间索引不需要有效删除,最大堆也不需要支持按值删除。但是,如果社区很大且经常重叠,则速度会较慢。因此有效的删除可能是一个必要的困难。
我无法提供复杂性分析。
我正在考虑第二种算法。我认为比较慢的部分是针对使用过的桌子检查邻居。不需要这样做,因为可以在线性时间内从Vantage点树中删除。在搜索邻居时,请记住在哪里找到他们,然后稍后使用这些位置将其删除。如果将邻居用作优势点,请将其标记为已删除,以便搜索不会返回它,否则将其保留。我认为这可以将其恢复到二次方以下。否则,它将类似于项目数量乘以邻域大小。
回应评论。问题是“计数较低的字符串折叠为计数较高的字符串”。因此,这确实可以进行计算。这不是贪婪的近似,因为没有任何要最大化或最小化的结果,因此可能导致非最佳结果。这是一个精确的算法。它返回得分最高的项目以及其邻域的得分。
这可以看作是为每个邻域分配一个领导者,以使每个项目最多具有一个领导者,并且该领导者迄今为止拥有最高的总分。可以将其视为有向图。
该规范不适用于动态编程或优化问题。为此,您需要在总得分最高的社区中获得得分最高的项目。也可以通过将排名函数字符串从其得分更改为得分及其邻域和得分之和的对来解决此问题。
这确实意味着它不能用最大的堆来解决,因为删除项目会影响邻居的邻居,因此必须重新计算其邻居得分,然后才能再次找到总得分最高的项目。