to top page
2013-02-17
マルコフチェーンのセーブとロード
LyliPond + Ruby プロジェクトの MarkovChain クラスに、チェーン本体を保存する save と load メソッドを追加した。

class MarkovChain
  def initialize(n)
    @order = n
    @nodes = { Array.new(@order) => [] }
    @history = Array.new(@order)
  end

  def reset
    @history.fill(nil)
  end

  def add(leaf)
    if @nodes.has_key?(@history)
      @nodes[@history].push leaf
    else
      @nodes[@history.dup] = [leaf]
    end
    @history.shift
    @history.push leaf
  end

  def get()
    reset unless @nodes.has_key?(@history)
    leaves = @nodes[@history]
    leaf = leaves[rand(leaves.size)]
    @history.shift
    @history.push leaf
    return leaf
  end

  def save(path)
    File.open(path, "w") do |f|
      Marshal.dump(@nodes, f)
    end
  end

  def load(path)
    File.open(path) do |f|
      @nodes = Marshal.load(f)
    end
  end
end

[課題]
バイナリで保存したくない。JSON など、テキストで保存するように変える。
read、write など、外からチェーンをエディットする機能も付ける。

[追記]
Ruby 1.9系に標準添付されている JSON ライブラリを利用した save と load。
def save(path)
  File.open(path, "w") do |f|
    JSON.dump(@nodes, f)
  end
end

def load(path)
  File.open(path) do |f|
    JSON.load(f).each do |key, val|
      @nodes[eval(key.sub(/^"/,'').sub(/"$/,''))] = val
    end
  end
end