From 2a03fd9a56c82a711854ae82a7e596482ee8f67b Mon Sep 17 00:00:00 2001 From: sanine Date: Wed, 1 Jan 2025 10:11:34 -0600 Subject: initial commit --- example.lua | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 example.lua (limited to 'example.lua') diff --git a/example.lua b/example.lua new file mode 100644 index 0000000..fd61f06 --- /dev/null +++ b/example.lua @@ -0,0 +1,80 @@ +local Grammar = require 'grammar' +local GA = require 'ga' + + +local production = {} +production[""]={{''}} +production[""]={ {''}, {'(', '', '', '', ')'} } +production[""]={ {'+'}, {'-'}, {'*'}, {'/'} } +production[""]={ {'x'} } + + +local grammar = Grammar.createGrammar(production) + + +math.randomseed(0) + + +function randomGenome() + local len = math.ceil(math.random() * 256) + local genome = {} + for i=1,len do + table.insert(genome, math.floor(256 * math.random())) + end + return genome +end + + +function randomPop() + local pop = {} + for n=1,1000 do + table.insert(pop, randomGenome()) + end + return pop +end + +function evaluate(genome) + local s = 'return function(x) return ' .. grammar:expand(genome) .. ' end' + local f = assert(loadstring(s))() + local target = function(x) return (x*x*x*x) + (x*x*x) + (x*x) + (x) end + local cost = 0 + for n=0,100 do + x = (n-50)/50 + ok, y = pcall(f, x) + if (not ok) or (y ~= y) then + cost = cost + 100 + else + cost = cost + math.abs(y - target(x)) + end + end + return -((0.0001*#s) + cost) +end + +local ga = GA.createGA(randomPop(), { + evaluate=evaluate, + crossover=function(a, b) + local crossoverPoint = math.ceil(#a * math.random()) + local new = {} + for i=1,#b do + table.insert(new, (i>=crossoverPoint and b[i]) or a[i]) + end + return new + end, + mutate=function(a) + local new = {} + for i,v in ipairs(a) do new[i] = v end + local mutationPoint = math.ceil(#a * math.random()) + new[mutationPoint] = math.floor(256 * math.random()) + return new + end, +}) + + +for n=1,100 do + print(ga:step()) + print(grammar:expand(ga.population[ga.bestMember])) +end + +-- for k,v in ipairs(ga.population) do +-- print(k, '(', v[1], v[2], v[3], ')', evaluate(v)) +-- end -- cgit v1.2.1