Skip to content

Commit

Permalink
pcgp with node sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
d9w committed Feb 2, 2021
1 parent 66ec231 commit 4281386
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 22 deletions.
1 change: 1 addition & 0 deletions cfg/gym.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ columns: 100
recur: 0.2
out_m_rate: 0.3
env: 'HopperBulletEnv-v0'
i_start: -0.5
functions:
- f_add
- f_subtract
Expand Down
8 changes: 4 additions & 4 deletions src/crossover.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export single_point_crossover,

"single point crossover, genes from p1 up to a random point, then genes from p2"
function single_point_crossover(cfg::NamedTuple, c1::CGPInd, c2::CGPInd)
cpoint = c1.n_in + c1.n_out + 3 * rand(2:(min(length(c1.nodes)-c1.n_in,
cpoint = c1.n_in + c1.n_out + 4 * rand(2:(min(length(c1.nodes)-c1.n_in,
length(c2.nodes)-c2.n_in)-2))
if rand(Bool)
ngenes = deepcopy([c1.chromosome[1:cpoint]; c2.chromosome[(cpoint+1):end]])
Expand Down Expand Up @@ -41,8 +41,8 @@ end
"take random nodes from each parent equally, up to the size of the smaller parent"
function random_node_crossover(cfg::NamedTuple, c1::CGPInd, c2::CGPInd)
l = min(length(c1.chromosome), length(c2.chromosome)) - max(c1.n_out, c2.n_out)
p = rand(Bool, Int64(round(l / 3)))
p_nodes = repeat(p, inner=3)
p = rand(Bool, Int64(round(l / 4)))
p_nodes = repeat(p, inner=4)
append!(p_nodes, rand(Bool, c1.n_out))
genes = rand(length(c1.chromosome))
genes[p_nodes] = c1.chromosome[p_nodes]
Expand Down Expand Up @@ -114,7 +114,7 @@ function node_crossover(cfg::NamedTuple, c1::CGPInd, c2::CGPInd,
if i in c2_nodes
append!(genes, get_genes(c2, i))
else
append!(genes, rand(3))
append!(genes, rand(4))
end
end
end
Expand Down
38 changes: 22 additions & 16 deletions src/individual.jl
Original file line number Diff line number Diff line change
Expand Up @@ -77,26 +77,32 @@ function CGPInd(cfg::NamedTuple, chromosome::Array{Float64}, genes::Array{Int16}
CGPInd(cfg.n_in, cfg.n_out, chromosome, genes, outputs, nodes, buffer, fitness)
end

snap(x) = map(x->argmin(abs.(p .- x)), fc)

function CGPInd(cfg::NamedTuple, chromosome::Array{Float64})::CGPInd
R = cfg.rows
C = cfg.columns
# chromosome: node genes, output genes
genes = reshape(chromosome[1:(R*C*3)], R, C, 3)
# TODO: recurrency is ugly and slow
maxs = collect(1:R:R*C)
maxs = round.((R*C .- maxs) .* cfg.recur .+ maxs)
maxs = min.(R*C + cfg.n_in, maxs .+ cfg.n_in)
maxs = repeat(maxs, 1, R)'
genes[:, :, 1] .*= maxs
genes[:, :, 2] .*= maxs
genes[:, :, 3] .*= length(cfg.functions)
genes = Int16.(ceil.(genes))
outputs = Int16.(ceil.(chromosome[(R*C*3+1):end] .* (R * C + cfg.n_in)))
ps = chromosome[cfg.n_out+1:4:end]
ps_sort = sortperm(ps)
xs = chromosome[cfg.n_out+2:4:end][ps_sort]
ys = chromosome[cfg.n_out+3:4:end][ps_sort]
fs = chromosome[cfg.n_out+4:4:end][ps_sort]
sort!(ps)
xgenes = xs .* ((cfg.recur * (1.0 .- ps) .+ ps) .- cfg.i_start ) .+ cfg.i_start
ygenes = ys .* ((cfg.recur * (1.0 .- ps) .+ ps) .- cfg.i_start ) .- cfg.i_start
positions = collect(LinRange(cfg.i_start, 0.0, cfg.n_in+1))
positions = [positions[1:cfg.n_in]; ps]
genes = Array{Int16}(undef, R, C, 3)
genes[:, :, 1] = Int16.(map(x->argmin(abs.(positions .- x)), xgenes))
genes[:, :, 2] = Int16.(map(x->argmin(abs.(positions .- x)), ygenes))
genes[:, :, 3] = Int16.(ceil.(fs .* length(cfg.functions)))
outputs = Int16.(ceil.(chromosome[(R*C*4+1):end] .* (R * C + cfg.n_in)))
CGPInd(cfg, chromosome, genes, outputs)
end

function CGPInd(cfg::NamedTuple)::CGPInd
chromosome = rand(cfg.rows * cfg.columns * 3 + cfg.n_out)
chromosome = rand(cfg.n_out + cfg.rows * cfg.columns * 4)
CGPInd(cfg, chromosome)
end

Expand Down Expand Up @@ -156,9 +162,9 @@ end

function get_genes(c::CGPInd, node_id::Integer)::Array{Float64}
if node_id > c.n_in
return c.chromosome[(node_id-c.n_in-1)*3 .+ (1:3)]
return c.chromosome[(node_id-c.n_in-1)*4 .+ (1:4)]
else
return zeros(3)
return zeros(4)
end
end

Expand All @@ -173,8 +179,8 @@ end
"set the genes of node_id to genes"
function set_genes!(c::CGPInd, node_id::Integer, genes::Array{Float64})
if node_id > c.n_in
@assert length(genes) == 3
c.chromosome[(node_id-c.n_in-1)*3 .+ (1:3)] = genes
@assert length(genes) == 4
c.chromosome[(node_id-c.n_in-1)*4 .+ (1:4)] = genes
end
end

Expand Down
4 changes: 2 additions & 2 deletions test/individual.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import YAML
cfg = get_config("test.yaml")
ind = CGPInd(cfg)

@test length(ind.nodes) == 3 * cfg.columns + cfg.n_in
@test length(ind.nodes) == cfg.rows * cfg.columns + cfg.n_in
for node in ind.nodes
if node.active
@test node.x >= 1
Expand Down Expand Up @@ -56,7 +56,7 @@ end
@test all(genes .<= 1.0)

set_genes!(ind2, ind.n_in+1, genes)
@test all(ind.chromosome[1:3] .== ind2.chromosome[1:3])
@test all(ind.chromosome[1:4] .== ind2.chromosome[1:4])

for i in 1:length(ind.nodes)
genes = get_genes(ind, i)
Expand Down
1 change: 1 addition & 0 deletions test/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ recur: 0.0
n_in: 10
n_out: 3
out_m_rate: 0.3
i_start: -0.5
functions:
- f_add
- f_subtract
Expand Down

0 comments on commit 4281386

Please sign in to comment.