4

非常に広く深い木の幅優先探索に対応するシーケンスを生成しようとしています...シーケンスに沿って進みすぎると、メモリの問題が発生します。IRCチャネルで質問し、ここを見たところ、このような問題の最大の原因は、うっかり頭を抱えていることです。しかし、私はこれをどこで行っているのかわかりません。

コードは非常に単純です。問題を表示するバージョンは次のとおりです。

(def atoms '(a b c))

(defn get-ch [n] (map #(str n %) atoms)) 

(defn add-ch 
  ([] (apply concat (iterate add-ch atoms))) 
  ([n] (mapcat get-ch n)))

(dorun (take 20000000 (add-ch)))

そして、これは別のバージョン(#clojureから助けを得る前に私が始めたバージョンです)で、同じ問題が表示されます:

(def atoms '(a b c))

(defn get-children [n] (map #(str n %) atoms))

(defn add-layer 
  ([] (add-layer atoms)) 
  ([n] (let [child-nodes (mapcat get-children n) ] 
      (lazy-seq (concat n (add-layer child-nodes))))))

(dorun (take 20000000 (add-layer)))

どちらも「OutOfMemoryErrorJavaヒープスペース」を提供してくれます。MacbookAirのEclipse/CounterClockwiseのREPLから実行しています。

私はClojureにかなり慣れていないので、これに対して1日頭を打ち負かした後、これが私が見落としている些細なことであることを望んでいます。ヒープサイズを大きくして問題が発生しにくくすることはできますが、最終的に処理したいシーケンスは非常に膨大であるため、これが役に立たないと思います。

頭をつかまないようにするために、「テイク」(上記の例)を「ドロップ」に置き換えてみましたが、違いはありません。

4

1 に答える 1

2

ドルンを逃した。問題は StringBuilder str にあるようです。

これは、get-children を以下のように置き換えると機能します。

 (defn get-children [n] (map #(if (seq? n) (conj n %) (conj (list n) %)) atoms))
于 2012-06-08T16:23:43.593 に答える