Skip to content
Permalink
aa42badd5d
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
157 lines (140 sloc) 4 KB
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
#=
macro create_function(names)
for name in eval(names)
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
"""
# 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_full_tree(depth-1, fs, ts), create_full_tree(depth-1, fs, ts))
end
end
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
#=
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
# Init everything
pop_size = 500
max_iterations = 1
max_initial_depth = 6
max_depth = 17
xover_prob = 0.9
fs = [:+, :-, :DIV, :GT]
ts = [:x,:v,-1]
points = [rand(-0.75:0.05:.75,2) for i in 1:20]
println(points)
elites = 2
tau = 0.02
max_time = 5
# Create initial population
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
# Init iterations, scores
iteration = 0
scores = Dict(string(i) => Float64(i) for i in 1:pop_size)
while iteration < max_iterations
# For each member in the population
for (index, member) in enumerate(pop0)
# For each x,v pair
times = []
for point in points
global x, v
x = point[1]
v = point[2]
t = 0
while (t <= max_time) && (abs(x) > 0.01 && abs(v) > 0.01)
if eval(member) >=0
u = 1
else
u = 0
end
vk = v + tau*u
xk = x + tau*(v+vk)/2
v = vk
x = xk
t = t + tau
end
push!(times,t)
end
scores[string(index)] = mean(times)
end
sorted_scores = sort(collect(scores), by=x->x[2])
println(sorted_scores)
iteration += 1
end