Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
I guess I'll use global scope
  • Loading branch information
Stephen committed Mar 12, 2018
1 parent 6b1d7a4 commit 30143f5
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 26 deletions.
118 changes: 92 additions & 26 deletions gp.jl
@@ -1,23 +1,8 @@
#=
Objective: Find minimum time vehicle control program
Terminal Set: x (position)
v (velocity)
-1
Function Set: +, -, *, DIV, GT, ABS
Cost: Time to bring behicle to phase plane origin
averaged over 20 random initial conditions
Gen. Limit: 50
Pop. Size: 500
Max Initial Tree Depth: 6
Init. Method: Ramped half-and-half
Max. Tree depth: 17
X-Over Prob.: 0.9
Mutation prob.: 0
Number of elites: 2
Selection: Tournament
=#

function GT(a,b)
"""
GT function to be used in AST
"""
if a > b
return 1
else
Expand All @@ -26,25 +11,106 @@ function GT(a,b)
end

function DIV(a,b)
"""
Protected division used in AST
"""
if abs(b) < 10.0^-10
return 1
else
return a/b
end
end
#=
macro create_function(defs)
for name in eval(defs)
ex = quote
function $(Symbol(name))(x,v)
fs = [:+, :-, :DIV, :GT]
ts = [:x,:v,-1]
return create_single_full_tree(4, fs, ts)
end
end
eval(ex)
end
end
=#

function create_full_tree(depth, fs, ts)
"""
Creates a single AST with full depth
Inputs
depth Current depth of tree. Initially called from main() with max depth
fs Function Set - Array of allowed functions
ts Terminal Set - Array of allowed terminal values
Output
Full AST of typeof()==Expr
"""

function create_single_full_tree(depth, fs, ts)
# If we are not at the bottom
# If we are at the bottom
if depth == 1
# End of tree, return function with two terminal nodes
return Expr(:call, fs[rand(1:length(fs))], ts[rand(1:length(ts))], ts[rand(1:length(ts))])
else
return Expr(:call, fs[rand(1:length(fs))], create_single_full_tree(depth-1, fs, ts), create_single_full_tree(depth-1, fs, ts))
# Not end of expression, recurively go back through and create functions for each new node
return Expr(:call, fs[rand(1:length(fs))], create_full_tree(depth-1, fs, ts), create_full_tree(depth-1, fs, ts))
end
end

function main()
fs = [:+, :-, :DIV, :GT]
ts = [:x, :v, -1]
tst = create_single_full_tree(4, fs, ts)
function create_grow_tree(depth, fs, ts)
if depth == 1
return Expr(:call, fs[rand(1:length(fs))], ts[rand(1:length(ts))], ts[rand(1:length(ts))])
else
choice = rand(1:3)
if choice == 1
return Expr(:call, fs[rand(1:length(fs))], create_grow_tree(depth-1, fs, ts), create_grow_tree(depth-1, fs, ts))
elseif choice == 2
return Expr(:call, fs[rand(1:length(fs))], ts[rand(1:length(ts))], create_grow_tree(depth-1, fs, ts))
else
return Expr(:call, fs[rand(1:length(fs))], create_grow_tree(depth-1, fs, ts), ts[rand(1:length(ts))])
end
end
end
main()



#=
Objective: Find minimum time vehicle control program
Terminal Set: x (position)
v (velocity)
-1
Function Set: +, -, *, DIV, GT, ABS
Cost: Time to bring behicle to phase plane origin
averaged over 20 random initial conditions
Gen. Limit: 50
Pop. Size: 500
Max Initial Tree Depth: 6
Init. Method: Ramped half-and-half
Max. Tree depth: 17
X-Over Prob.: 0.9
Mutation prob.: 0
Number of elites: 2
Selection: Tournament
=#


# Define x, v as globals because I can't figure out how to get
# around creating expressions and not being able to plug
# x and v into them for the past week

pop_size = 500
max_initial_depth = 6
max_depth = 17
xover_prob = 0.9
fs = [:+, :-, :DIV, :GT]
ts = [:x,:v,-1]
xs = rand(1:10,20)
vs = rand(1:10,20)
elites = 2

pop0 = []
for i in 1:pop_size/2
push!(pop0, create_full_tree(max_initial_depth, fs, ts))
push!(pop0, create_grow_tree(max_initial_depth, fs, ts))
end


80 changes: 80 additions & 0 deletions gp_module_test.jl
@@ -0,0 +1,80 @@
#=
Objective: Find minimum time vehicle control program
Terminal Set: x (position)
v (velocity)
-1
Function Set: +, -, *, DIV, GT, ABS
Cost: Time to bring behicle to phase plane origin
averaged over 20 random initial conditions
Gen. Limit: 50
Pop. Size: 500
Max Initial Tree Depth: 6
Init. Method: Ramped half-and-half
Max. Tree depth: 17
X-Over Prob.: 0.9
Mutation prob.: 0
Number of elites: 2
Selection: Tournament
=#
module GP
function GT(a,b)
"""
GT function to be used in AST
"""
if a > b
return 1
else
return -1
end
end

function DIV(a,b)
"""
Protected division used in AST
"""
if abs(b) < 10.0^-10
return 1
else
return a/b
end
end

@eval function create_single_full_tree(depth, fs, ts)
"""
Creates a single AST with full depth
Inputs
depth Current depth of tree. Initially called from main() with max depth
fs Function Set - Array of allowed functions
ts Terminal Set - Array of allowed terminal values
Output
Full AST of typeof()==Expr
"""
# If we are at the bottom
if depth == 1
# End of tree, return function with two terminal nodes
return Expr(:call, fs[rand(1:length(fs))], ts[rand(1:length(ts))], ts[rand(1:length(ts))])
else
# Not end of expression, recurively go back through and create functions for each new node
return Expr(:call, fs[rand(1:length(fs))], create_single_full_tree(depth-1, fs, ts), create_single_full_tree(depth-1, fs, ts))
end
end
end

function main()
"""
Main function
"""
# Define functional and terminal sets
fs = [:+, :-, :DIV, :GT]
ts = [:x, :v, -1]
# Create the tree
tst = GP.create_single_full_tree(4, fs, ts)
#println(typeof(tst))
#println(tst)
#println(dump(tst))
# If I comment these globals, eval cannot find x and v in the scope
GP.x = 1
GP.v = 1
#eval(tst)
end
main()
14 changes: 14 additions & 0 deletions test.jl
@@ -0,0 +1,14 @@
macro create_ast(fns, tms)
return esc(Expr(:call, fns[1], tms[1], tms[2]))
end

function main()
fns = [:+, :-]
tms = [:x, :y]
tst = @create_ast(fns, tms)
println(tst)
x = 1
y = 2
eval(tst)
end
main()

0 comments on commit 30143f5

Please sign in to comment.