Skip to content

Instantly share code, notes, and snippets.

@Vaguery
Created November 13, 2010 00:30
Show Gist options
  • Select an option

  • Save Vaguery/674958 to your computer and use it in GitHub Desktop.

Select an option

Save Vaguery/674958 to your computer and use it in GitHub Desktop.
The BrickpigScript class for creating and evaluating random arithmetic expressions in a simple Cartesian GP language, and some accompanying files from the book I'm working on.
class Float
alias :add :+
alias :subtract :-
alias :multiply :*
alias :negate :-@
def divide(arg2)
arg2==0 ? 0.0 : self / arg2
end
end
module Brickpig
class BrickpigCell
attr_accessor :current_value, :script, :inputs
def initialize(script)
@script = script
@inputs = script.scan(/cells\[([0-9]+)\]/).flatten.collect {|link| link.to_i}
@current_value = 0.0
end
end
class BrickpigScript
attr_accessor :script
FUNCTION_SET = [
"constant",
"cells[#].negate",
"cells[#].add( cells[#] )", "cells[#].subtract( cells[#] )",
"cells[#].multiply( cells[#] )", "cells[#].divide( cells[#] )"]
def initialize(number_of_cells=20)
script = "x\n"
number_of_cells.times do
cell_function = FUNCTION_SET.sample
cell_function = cell_function.gsub("#") {|v| Random.rand(number_of_cells).to_s}
cell_function = cell_function.gsub("constant") {(Random.rand()*20-10).round(3)}
script += "#{cell_function}\n"
end
@script = script
end
def evaluate(x, iterations = 1)
x = x.to_f
graph = script.split("\n").collect {|line| BrickpigCell.new(line)}
cells = graph.collect {|node| node.current_value}
iterations.times do
graph.each_with_index do |node,idx|
old_value = cells[idx]
result = self.instance_eval(node.script)
cells[idx] = result
end
end
return cells[-1]
end
end
# brick = BrickpigScript.new(20)
# (-5..5).each do |x|
# puts (1..30).inject("#{x}") {|line,iters| line + "\t#{brick.evaluate(x, iters).round(5)}"}
# end
end
require "./brickpig"
include Brickpig
module Brickpig
class BrickpigScript
def as_dotfile
line_count = script.lines.to_a.length-1
dotfile = "digraph Brickpig {"
@script.split("\n").each_with_index do |cell,idx|
links = cell.scan(/cells\[([0-9]+)\]/).flatten
unless links == []
dotfile += " node_#{idx} [label=\"#{idx}\\n #{cell}\", rank=#{idx}, shape=box]; "
links.each {|link| dotfile += " node_#{link} -> node_#{idx};"}
else
dotfile +=" node_#{idx} [rank=min, shape=invhouse, label=\"#{idx}\\n #{cell}\", style=filled, color=\"palegreen\"];"
end
end
dotfile += " node_#{line_count}->output; output [rank=max,shape=house,label=\"RESULT\",style=filled, color=\"coral2\"]; }"
end
end
end
# brick = BrickpigScript.new(30)
# puts brick.as_dotfile
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment