Algorithm 高效的文本平移不变特征变换
编辑 有3个连续的比特流。有一段时间,人们开始阅读它们。一段时间后,一个停止,现在有3个非常长的字符串相同的长度 这3个字符串应包含介于两者之间的已发送消息。除消息外,发送随机位 现在的目标是,找出如何覆盖3个字符串以进一步执行任何错误更正Algorithm 高效的文本平移不变特征变换,algorithm,text,transformation,sift,Algorithm,Text,Transformation,Sift,编辑 有3个连续的比特流。有一段时间,人们开始阅读它们。一段时间后,一个停止,现在有3个非常长的字符串相同的长度 这3个字符串应包含介于两者之间的已发送消息。除消息外,发送随机位 现在的目标是,找出如何覆盖3个字符串以进一步执行任何错误更正 hfkasjkfhjs<<this is a string><hjaksdf jkdf::this is b strimg>>iowefjlasfjoie jfaskflsjdflf<<this is a t
hfkasjkfhjs<<this is a string><hjaksdf
jkdf::this is b strimg>>iowefjlasfjoie
jfaskflsjdflf<<this is a tring>>oweio
hfkasjkfhjsiowefjlasfjoie
jfaskflsjdflfoweio
下面是一个简单的例子。现在我想要的是这个
<<this is a string><
::this is b string>>
<<this is a tring>>
>
现在我可以用多数票投票,得到正确的顺序
<<this is a string>>
如何有效地实现这一点?在Lisp中进行探索性编程:
fuzz extract.tl的内容:
(defun fuzz (str)
(window-map 1 " "
(do if (memql #\X @rest)
#\X #\space)
str))
(defun correlate (str1 str2 thresh)
(let ((len (length str1))
(pat (mkstring thresh #\X)))
(each ((offs (range* 0 len)))
(let* ((str2-shf `@[str2 offs..:]@[str2 0..offs]`)
(str2-dshf `@{str2-shf}@{str2-shf}`)
(raw-diff (mapcar [iff eql (ret #\X) (ret #\space)]
str1 str2-dshf))
(diff (fuzz raw-diff))
(pos (search-str diff pat)))
(if pos
(let ((rng (+ (r^ #/X+/ pos diff) #R(-2 2))))
(if (< (from rng) 0)
(set rng 0..(to rng)))
(return-from correlate [str1 rng])))))))
(defun count-same (big-s lit-s offs)
(countq t [mapcar eql [big-s offs..:] lit-s]))
(defun find-off (big-s lit-s)
(let ((idx-count-pairs (collect-each ((i (range 0 (- (length big-s)
(length lit-s)))))
(list i (count-same big-s lit-s i)))))
(first [find-max idx-count-pairs : second])))
(defun extract-from-three (str1 str2 str3 : (thresh 10))
(let* ((ss1 (correlate str1 str2 thresh))
(ss2 (correlate str2 str3 thresh))
(ss3 (correlate str3 str1 thresh))
(maxlen [[mapf max length length length] ss1 ss2 ss3])
(pad (mkstring (trunc maxlen 2) #\space))
(buf1 `@pad@ss1@pad`)
(off1 (find-off buf1 ss2))
(buf2 `@{"" off1}@ss2`)
(off2 (find-off buf1 ss3))
(buf3 `@{"" off2}@ss3`))
(mapcar (do cond
((eql @1 @2) @1)
((eql @2 @3) @2)
((eql @3 @1) @3)
(t #\space))
buf1 buf2 buf3)))
(定义模糊(str)
(窗口映射1“”
(如果执行(memql#\X@rest)
#\X#\space)
str)
(解除关联(str1 str2阈值)
(let((len(长度str1))
(pat(mkstring thresh#\X)))
(每个((关闭(范围*0 len)))
(让*((str2 shf`@[str2 offs..::@[str2 0..offs]`)
(str2-dshf`{str2-shf}{str2-shf}`)
(原始差异(映射车[iff eql(ret#\X)(ret#\space)]
str1 str2 dshf)
(差异(毛绒原始差异))
(pos(搜索str diff pat)))
(如果是pos
(let((rng(+(r^#/X+/pos diff)#r(-2)))
(如果(<(从rng)0)
(将rng 0..(设置为rng)))
(从关联[str1 rng]()()()))返回)
(除雾计数相同(大s亮s灭)
(countq t[mapcar eql[big-s offs..:]lit-s]))
(卸载查找(大s亮s)
让((idx)计数对(收集每个((i)范围0(-(长度大-s)
(长度lit-s()()))
(列表i(计算相同的大s lit-s i()())))
(第一个[查找最大idx计数对:第二个])
(从三个(str1、str2、str3:(脱粒10))中提取)
(let*((ss1(关联str1和str2阈值))
(ss2(关联str2和str3阈值))
(ss3(关联str3和str1阈值))
(最大长度[[mapf最大长度]ss1 ss2 ss3])
(pad(mkstring(trunc maxlen 2)#\space))
(buf1`@pad@ss1@垫`)
(off1(查找buf1 ss2))
(buf2`@{“off1}@ss2`)
(off2(查找buf1 ss3))
(buf3`@{“off2}@ss3`)
(mapcar(do cond
((eql@1@2)@1)
((eql@2@3)@2)
((eql@3@1)@3)
(t#\空格)
buf1 buf2 buf3)))
交互式会议:
$ txr -i fuzz-extract.tl
1> (extract-from-three
"hfkasjkfhjs<<this is a string><hjaksdf"
"jkdf::this is b strimg>>iowefjlasfjoie"
"jfaskflsjdflf<<this is a tring>>oweio")
" f<<this is a string>> "
2> (trim-str *1)
"f<<this is a string>>"
$txr-i fuzz-extract.tl
1> (摘自三篇文章)
“hfkasjkfhjsiowefjlasfjoie”
“jfaskflsjdflfoweio”)
“f”
2> (修剪str*1)
“f”
闻起来(或者你的意思是输入可以包含indel)可能会计算不同轮班候选者的汉明距离?你对你的问题不是很具体。特别是,不清楚同步丢失是否是分歧的可能原因。另一种可能性是在流中插入/删除随机(扩展)位/字符。对于DNA比对/组装,有一整套算法来处理这类问题。(google for BLAST)注意:查找开始/同步看起来像是使用维特比算法的特殊编码流,该算法试图找到一个比比特流复杂得多的马尔可夫模型
马尔可夫模型用于预测下一个(或当前)比特,给定先前的比特。在我看来,预测一个比特或预测一个2比特的核苷酸在理论上没有区别,除了状态空间的大小等。这些“特殊编码”的比特流是为了帮助预测而发明的。你有问题了!在之前,您的两条消息共享一个前导的f
,我实际处理了代码并用另一种语言编写了它。它现在工作得很好。