いくつかのコードで少し問題が発生しています。私はひどいプログラマーなので、私の解決策はおそらくあまり雄弁ではないことを覚えておいてください(そしておそらく私がメモリを使い果たしている理由-私は4ギガバイトを持っていて、スクリプトはゆっくりとそれを満たします)。
ここに問題があります。ディレクトリに約3,500個のファイルがあります。各ファイルは、スペースのない比較的少数または多数の文字を含む可能性のある1行で構成されます(最小のファイルは200バイトであるのに対し、最大のファイルは1.3メガバイトです)。私がやろうとしているのは、これらのファイル間で設定された長さの2つの共通の部分文字列を見つけることです(以下のコードでは13文字です)。それらすべてに共通のサブストリングを探しているのではなく、すべてのファイルが比較されるまで2つの組み合わせを探しているので、一度に2つ実行します。つまり、ファイル間で設定された長さの共通のサブストリングであり、すべてのファイルに共通のサブストリングではありません。
C実装をラップするサフィックスツリーモジュールを使用します(ここ)。最初にディレクトリ内のすべてのファイルのリストを作成し、次にすべての組み合わせがカバーされるように2つの組み合わせを探し、一度に2つのファイルをサフィックスツリーに渡し、次に一般的なサブストリングであるシーケンスを探します。
しかし、なぜそれがゆっくりとメモリを使い果たしているのか、私にはよくわかりません。未使用のもののメモリをなんとかしてクリアするように、コードに修正を加えることができるといいのですが。もちろん、3,500ファイルの処理には長い時間がかかりますが、4ギガバイトのメモリを段階的にいっぱいにすることなく処理できることを願っています。どんな助けでも大歓迎です!これが私がこれまでに持っているコードです:
from suffix_tree import GeneralisedSuffixTree
from itertools import combinations
import glob, hashlib, os
alist = open('tmp.adjlist', 'w')
def read_f(f):
f = open(f, "r")
s = str(f.readlines())
f.close()
return s
def read_gs(a,b):
s1 = read_f(a)
s2 = read_f(b)
print str(a) + ":" + str(hashlib.md5(s1).hexdigest()) + " --- " + str(b) + ":" + str(hashlib.md5(s2).hexdigest())
return [s1,s2]
def build_tree(s):
hlist = []
stree = GeneralisedSuffixTree(s)
for shared in stree.sharedSubstrings(13):
for seq,start,stop in shared:
hlist.append(hashlib.md5(stree.sequences[seq]).hexdigest())
hlist = list(set(hlist))
for h in hlist:
alist.write(str(h) + " ")
alist.write('\n')
glist = []
for g in glob.glob("*.g"):
glist.append(g)
for a,b in list(combinations(glist, 2)):
s = read_gs(a,b)
build_tree(s)
alist.close()
os.system("uniq tmp.adjlist network.adjlist && rm tmp.adjlist")
更新#1
更新されたコードは次のとおりです。Pyrceの提案を追加しました。しかし、jogojapanがCコードのメモリリークを特定し、それが私の専門知識をはるかに超えていることを考えると、私ははるかに遅いアプローチをとることになりました。この分野に精通している人がいれば、Cコードを変更してメモリリークや割り当て解除機能を修正する方法を知りたいと思います。PythonのCサフィックスツリーバインディングは非常に価値があると思います。接尾辞木なしでこのスクリプトを介してデータを実行するにはおそらく数日かかるので、誰かが創造的な修正を持っているかどうかを確認することは間違いなくオープンです!
from itertools import combinations
import glob, hashlib, os
def read_f(f):
with open(f, "r") as openf:
s = str(openf.readlines())
return s
def read_gs(a,b):
s1 = read_f(a)
s2 = read_f(b)
print str(a) + ":" + str(hashlib.md5(s1).hexdigest()) + " --- " + str(b) + ":" + str(hashlib.md5(s2).hexdigest())
return [s1,s2]
def lcs(S1, S2):
M = [[0]*(1+len(S2)) for i in xrange(1+len(S1))]
longest, x_longest = 0, 0
for x in xrange(1,1+len(S1)):
for y in xrange(1,1+len(S2)):
if S1[x-1] == S2[y-1]:
M[x][y] = M[x-1][y-1] + 1
if M[x][y]>longest:
longest = M[x][y]
x_longest = x
else:
M[x][y] = 0
return S1[x_longest-longest: x_longest]
glist = glob.glob("*.g")
for a,b in combinations(glist, 2):
s = read_gs(a,b)
p = lcs(s[0],s[1])
if p != "" and len(p) >= 13:
with open("tmp.adjlist", "a") as openf:
openf.write(hashlib.md5(s[1]).hexdigest() + " " + hashlib.md5(s[0]).hexdigest() + "\n")
os.system("uniq tmp.adjlist network.adjlist && rm tmp.adjlist")