これがやや打ちのめされたトピックであることはわかっていますが、すでに回答されているものから得ることができる助けの限界に達しました.
これは、Rosalind プロジェクトの問題 LREP 用です。文字列内で最長の k ピート部分文字列を見つけようとしていますが、サフィックス ツリーが提供されています。各ノードからの子孫の葉の数で接尾辞テーブルに注釈を付け、子孫を持つノードを>=k
見つけ、最後にそれらのノードの最も深いところを見つける必要があることはわかっています。理論的には、私は設定されています。
私は次のリソースから多くの助けを得ました (おっと、投稿できるのは 2 つだけです)。
ルートから各リーフへのパスを取得できますが、各ノードから子孫の数を取得できるようにツリーを前処理する方法がわかりません。小さなシーケンスで機能する別のアルゴリズムがありますが、指数関数的に複雑であるため、大きなものでは時間がかかりすぎます。DFS を使用すれば、線形の複雑さでタスク全体を実行できるはずです。このアルゴリズムが機能するには、長さ 40,000 までの文字列の最長の k-peat を 5 分以内に取得できる必要があります。
サンプル データを次に示します (1 行目: sequence
、2 行目: k
、サフィックス テーブル形式: parent child location length
):
CATACATAC$
2
1 2 1 1
1 7 2 1
1 14 3 3
1 17 10 1
2 3 2 4
2 6 10 1
3 4 6 5
3 5 10 1
7 8 3 3
7 11 5 1
8 9 6 5
8 10 10 1
11 12 6 5
11 13 10 1
14 15 6 5
14 16 10 1
これからの出力はCATAC
.
次のコード ( LiterateProgramsから変更) を使用すると、パスを取得できましたが、長いシーケンスでは各ノードのパスを解析するのにまだ長い時間がかかります。
#authors listed at
#http://en.literateprograms.org/Depth-first_search_(Python)?action=history&offset=20081013235803
class Vertex:
def __init__(self, data):
self.data = data
self.successors = []
def depthFirstSearch(start, isGoal, result):
if start in result:
return False
result.append(start)
if isGoal(start):
return True
for v in start.successors:
if depthFirstSearch(v, isGoal, result):
return True
# No path was found
result.pop()
return False
def lrep(seq,reps,tree):
n = 2 * len(seq) - 1
v = [Vertex(i) for i in xrange(n)]
edges = [(int(x[0]),int(x[1])) for x in tree]
for a, b in edges:
v[a].successors.append(v[b])
paths = {}
for x in v:
result = []
paths[x.data] = []
if depthFirstSearch(v[1], (lambda v: v.data == x.data), result):
path = [u.data for u in result]
paths[x.data] = path
私がやりたいことは、ツリーを前処理してdescendants >= k
、深さを見つける前に要件を満たすノードを見つけることです。深さを計算する方法にもまだ到達していません。パス内の各ノードの深さを追跡し、合計するための辞書があると思いますが。
したがって、私の最初の最も重要な質問は、「ツリーを子孫の葉で前処理するにはどうすればよいですか?」ということです。
2 番目に重要でない質問は、「その後、深度をすばやく計算するにはどうすればよいか」です。
PS これは宿題などではありません。私は、計算上の課題で視野を広げようとしている生化学者です。