2016-10-28 8 views
1

私は遺伝的アルゴリズムを書いています。実行時に設定を再生するのを助けるために、私は設定を保存しようとしています(突然変異率、クロスチャンス、フィットネス機能...)ディスクに。そうすれば、ファイルを変更し、時々ファイルを読み込んで実行時に設定を更新することができます。コンソールからの入力を簡単にすることはできますが、Intellijの入力機能は使いこなせず、使いにくいことがわかりました。これは私が試しているルートです。匿名関数をシリアライズ

私の問題はこれです:設定はレコードで表されます。個々の設定の多くは数字なので、ディスクに簡単に保存できます。これは、適応度関数が表現されている方法を除き、罰金ですほとんどの部分について

"#ai.genetic_algorithm.genetic_algorithm2_2.Settings{:gene-set #{1 3 2}, :sequence-length 10, :fitness-f #object[ai.genetic_algorithm.genetic_algorithm2_2$eval776$fn__777$fn__778 0x1b30c92 \"ai[email protected]1b30c92\"]}" 

(defrecord Settings [ 
       gene-set 
       sequence-length 
       fitness-f]) 

(with-out-str (pr 
       (->Settings #{1 2 3} 
          10 
          #(count %))))) 

収量:一部の設定は、しかし、きれいに保存しない機能です。私は後ろにファイルを読み込むしようとした場合:

(read-string 
    (with-out-str (pr 
        (->Settings #{1 2 3} 
           10 
           #(count %))))) 

私が取得:

ai.genetic-algorithm.genetic-algorithm2-2=> RuntimeException No reader function for tag object clojure.lang.LispReader$CtorReader.readTagged (LispReader.java:1245) 

と機能を読む/保存しようとするとき、私はこのエラーを取得します。私はそれが私がそれをbarfsのように関数を読み取るように求めていることを知る方法がないと推測しています。

匿名関数をファイルに確実に保存する方法はありますか?

はい、私はread-stringが潜在的に危険であることを知っています。私はそれを個人的なプロジェクトのためだけに使っているので、私はこの脆弱性について心配していません。

+0

[実行時にClojureで関数をシリアル化するにはどうすればよいですか?](http://stackoverflow.com/questions/38753960/how-can-i-serialize-functions-at-runtime-in-clojure) – OlegTheCat

+0

@OlegTheCatおっと。どのように私はそれを見つけられなかったのか分からない。ありがとう。それは私が必要とするもののために非常に複雑に思えます。関数を保存する必要はないかもしれませんが、 – Carcigenicate

答えて

0

関数を生成する代わりにコードを変更し、後でその関数を名前空間から抽出してファイルに保存する場合は、設定の式を生成し、その式をファイルに保存します。次に、そのファイルを新しい状態としてロードした結果を使用します。

user> (let [new-config '{:gene-set #{1 2 3} 
         :sequence-length 10 
         :fitness-f (fn [x] (count x))}] 
      (with-open [w (clojure.java.io/writer "/tmp/config.edn")] 
      (binding [*out* w] 
       (pr new-config)))  
      (load-file "/tmp/config.edn")) 

{:gene-set #{1 3 2}, 
:sequence-length 10, 
:fitness-f #function[user/eval111126/fn--111127]} 

保存する新しい適合度関数を定義するときに、それをシンボルのシーケンスとして生成し、そのシーケンスを関数クラスにコンパイルする前に保存します。ロードされたときだけコンパイルされるようにして、常にロード可能なものであることを知ってください。これはバグを捕まえるでしょう。

機械的にこれらのコンポジションを生成したい場合は、そのコンポジション内のコンポジションの順序を保存するだけの名前を付けてください。