読者です 読者をやめる 読者になる 読者になる

Just $ A sandbox

プログラミングと計算機科学とかわいさ

1.Haskellで遺伝的プログラミング[ファイル入出力]

Haskellで遺伝的プログラムとか大仰なことを言いましたが私自身まだHaskellを使い始めたばかりで、初歩的な型エラーに何時間も悩むレベルです。
なので、まぁゆっくり少しずつ、悩みながら作っていきたいと思います(つまり遅いということです)。

ファイル入出力

まず、ファイル入出力ができないと話になりません。とりあえずはファイルの1行が一つの論理式(生命モデル*1 )になります。

さて、現実的な問題として、半角英数では∃∀を入力できません。些細なことですが、まぁプログラムはUnicodeにすれば問題はありませんが入力が面倒なので私はEAで代用したいと思います。なので限定論理式のサンプルとしては、
Ex<10 Ay<10 x+1=y
のようになります*2

仮想的な実行時間の算出

さて、式Ex<m Ay<n [PA算術で定義される式]を満たすものが存在するかどうかを調べたいとします。この時、実行時間はどのくらいでしょうか?どのように調べるかにもよりますが、もしも解が存在しない場合はmn回式を評価するのにかかる時間が実行時間です。

というわけで簡単のために、今はこのmnを実行時間として考えたいと思います。

プログラム

結局プログラムは、

  1. 論理式が書かれた何行かのデータファイルからデータを読む(ここではdata.txt)
  2. 実行時間を算出
  3. [実行時間]:[論理式]の形にしてファイルに出力

だけしてくれればよいので、簡単に組めますね*3

以下がそのプログラムです。

-- main.hs
import qualified Data.Char

main = readFile "data.txt" >>= writeFile "out0.txt" . unlines . analy

analy :: String->[String]
analy ss = zipWith (\x y->y++" : "++x)  (lines ss) . map show . map calTime . lines $ ss

calTime :: String->Int
calTime = product . map read . filter (/="") . map pickTime . words
    where
        pickTime :: String->String
        pickTime cs | cs==""         = []
                    | (head cs=='<') = tail cs
                    | otherwise      = pickTime . tail $ cs

入力(データファイル)

-- data.txt
Ex<100 Ay<20  x=y
Ex<10  Ay<50  x=y+1
Ex<100 Ay<100 x+1=y
Ex<200 Ay<200 x+2=y

出力

-- out0.txt
2000 : Ex<100 Ay<20  x=y
500 : Ex<10  Ay<50  x=y+1
10000 : Ex<100 Ay<100 x+1=y
40000 : Ex<200 Ay<200 x+2=y

次回は「交叉」「突然変異」を行って式を繁殖(?)させたいと思います。

*1:この系を現実のモデルと対応させるならファイル1行分が一つの生命で、1つのファイルが1つの世界に対応します。

*2:気持ち悪い?なら適当に変更すればいいんじゃないですか?

*3:いやまぁ読者さんは簡単に組めるでしょうけど私は色々悩んだんですよ! 主に型エラーやらなんやらに!!