From 12aeb10e41bbb1a5937aa33752012a55086c9abe Mon Sep 17 00:00:00 2001 From: Alden Wright Date: Fri, 5 Jun 2015 17:36:07 -0600 Subject: [PATCH 01/15] Removed deepcopy() from function mutate in Mutate.jl and from function mu_lambda in Evolution.jl. This resulted in substantial speedups, expecially for larger, more redundant, chromosomes. function print_chromosome in Chromosome.jl is broken and not fixed, and the code is not cleaned up. --- examples/EvolveGoals.jl | 3 ++- src/Chromosome.jl | 11 ++++++----- src/Execute.jl | 30 +++++++++++++++++------------- src/Mutate.jl | 16 ++++++++-------- src/Node.jl | 16 ++++++++-------- 5 files changed, 41 insertions(+), 35 deletions(-) diff --git a/examples/EvolveGoals.jl b/examples/EvolveGoals.jl index 84f4040..f582466 100644 --- a/examples/EvolveGoals.jl +++ b/examples/EvolveGoals.jl @@ -58,7 +58,8 @@ end # This is the function used by pmap to evolve each goal in goal_list @everywhere function p_mu_lambda(g) (ch,gens) = mu_lambda(p,g,max_gens) - n = ch.number_active_nodes + #n = ch.number_active_nodes + n = 0 (g.truth_table,gens,n) end diff --git a/src/Chromosome.jl b/src/Chromosome.jl index 59fe258..e69edbf 100644 --- a/src/Chromosome.jl +++ b/src/Chromosome.jl @@ -7,8 +7,8 @@ type Chromosome inputs::Vector{InputNode} interiors::Matrix{InteriorNode} outputs::Vector{OutputNode} - active_set::Bool - number_active_nodes::Integer + #active_set::Bool + #number_active_nodes::Integer end function Chromosome(p::Parameters) @@ -16,10 +16,11 @@ function Chromosome(p::Parameters) interiors = Array(InteriorNode, p.numlevels, p.numperlevel) outputs = Array(OutputNode, p.numoutputs) fitness = 0.0 - active_set = false - number_active_nodes = 0 + #active_set = false + #number_active_nodes = 0 - return Chromosome(p, inputs, interiors, outputs, active_set, number_active_nodes) + #return Chromosome(p, inputs, interiors, outputs, active_set, number_active_nodes) + return Chromosome(p, inputs, interiors, outputs ) end function getindex(c::Chromosome, level::Integer, index::Integer) diff --git a/src/Execute.jl b/src/Execute.jl index 2810589..3cd7b8a 100644 --- a/src/Execute.jl +++ b/src/Execute.jl @@ -1,35 +1,39 @@ export execute_chromosome function evaluate_node(c::Chromosome, node::InputNode, context::Vector{BitString}) + #= if ! node.active node.active = true c.number_active_nodes += 1 end + =# return context[node.index] end function evaluate_node(c::Chromosome, node::InteriorNode, context::Vector{BitString}) - if ! node.active + #if ! node.active func = node.func args = map(node.inputs[1:func.arity]) do position (level, index) = position evaluate_node(c, c[level, index], context) end - node.active = true - node.cache = func.func(args...) - c.number_active_nodes += 1 - end - return node.cache + #node.active = true + #node.cache = func.func(args...) + #c.number_active_nodes += 1 + #end + #return node.cache + return func.func(args...) end function evaluate_node(c::Chromosome, node::OutputNode, context::Vector{BitString}) - if ! node.active - node.active = true + #if ! node.active + #node.active = true (level, index) = node.input - node.cache = evaluate_node(c, c[level, index], context) - c.number_active_nodes += 1 - end - return node.cache + #node.cache = evaluate_node(c, c[level, index], context) + #c.number_active_nodes += 1 + #end + #return node.cache + return evaluate_node(c, c[level, index], context) end # TODO: Since we are caching the evaluation results we should no @@ -38,7 +42,7 @@ end # around. function execute_chromosome(c::Chromosome, context::Vector{BitString}) - c.active_set = true + #c.active_set = true return BitString[evaluate_node(c, node, context) for node = c.outputs] end diff --git a/src/Mutate.jl b/src/Mutate.jl index 780c5be..c584ac8 100644 --- a/src/Mutate.jl +++ b/src/Mutate.jl @@ -29,7 +29,7 @@ function mutate(old_c::Chromosome, funcs::Vector{Func} ) end new_c = Chromosome(p) - new_c.active_set = false + #new_c.active_set = false # Choose the genes that will be modified, and store their numbers in the array genes_to_mutate genes_to_mutate = Array(Int,num_mutations) @@ -46,8 +46,8 @@ function mutate(old_c::Chromosome, funcs::Vector{Func} ) # Input nodes for i = 1:numinputs - new_c.inputs[i] = deepcopy(old_c.inputs[i]) - new_c.inputs[i].active = false + new_c.inputs[i] = old_c.inputs[i] + #new_c.inputs[i].active = false end gene_index = 1 @@ -62,8 +62,8 @@ function mutate(old_c::Chromosome, funcs::Vector{Func} ) # check if none of the genes in node will be mutated if genes_to_mutate_index > length(genes_to_mutate) || gene_index + old_func.arity < genes_to_mutate[genes_to_mutate_index] # no mutations in this node - new_c.interiors[level, index] = deepcopy(old_c.interiors[level, index]) - new_c.interiors[level, index].active = false + new_c.interiors[level, index] = old_c.interiors[level, index] + #new_c.interiors[level, index].active = false gene_index += 1+old_func.arity continue end @@ -114,10 +114,10 @@ function mutate(old_c::Chromosome, funcs::Vector{Func} ) genes_to_mutate_index += 1 (level, index) = random_node_position(p, minlevel, maxlevel) new_c.outputs[i] = OutputNode((level, index)) - new_c[level, index].active = false + #new_c[level, index].active = false else - new_c.outputs[i] = deepcopy(old_c.outputs[i]) - new_c.outputs[i].active = false + new_c.outputs[i] = old_c.outputs[i] + #new_c.outputs[i].active = false end gene_index += 1 end # for i = diff --git a/src/Node.jl b/src/Node.jl index 2431ae1..44cfd1f 100644 --- a/src/Node.jl +++ b/src/Node.jl @@ -8,24 +8,24 @@ abstract Node type InputNode <: Node index::Integer - active::Bool + #active::Bool end -InputNode(index::Integer) = InputNode(index, false) +#InputNode(index::Integer) = InputNode(index, false) type InteriorNode <: Node func::Func inputs::Vector{NodePosition} - active::Bool - cache::BitString + #active::Bool + #cache::BitString end -InteriorNode(func::Func, inputs::Vector{NodePosition}) = InteriorNode(func, inputs, false, convert(BitString, 0)) +#InteriorNode(func::Func, inputs::Vector{NodePosition}) = InteriorNode(func, inputs, false, convert(BitString, 0)) type OutputNode <: Node input::NodePosition - active::Bool - cache::BitString + #active::Bool + #cache::BitString end -OutputNode(input::NodePosition) = OutputNode(input, false, convert(BitString, 0)) +#OutputNode(input::NodePosition) = OutputNode(input, false, convert(BitString, 0)) From cb66e1eaef98b0016456f50ec7648120074e991c Mon Sep 17 00:00:00 2001 From: George Lesica Date: Tue, 9 Jun 2015 10:01:56 -0400 Subject: [PATCH 02/15] Remove commented code. --- src/Chromosome.jl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Chromosome.jl b/src/Chromosome.jl index e69edbf..8bdab84 100644 --- a/src/Chromosome.jl +++ b/src/Chromosome.jl @@ -7,8 +7,6 @@ type Chromosome inputs::Vector{InputNode} interiors::Matrix{InteriorNode} outputs::Vector{OutputNode} - #active_set::Bool - #number_active_nodes::Integer end function Chromosome(p::Parameters) @@ -16,10 +14,7 @@ function Chromosome(p::Parameters) interiors = Array(InteriorNode, p.numlevels, p.numperlevel) outputs = Array(OutputNode, p.numoutputs) fitness = 0.0 - #active_set = false - #number_active_nodes = 0 - #return Chromosome(p, inputs, interiors, outputs, active_set, number_active_nodes) return Chromosome(p, inputs, interiors, outputs ) end From 141e380a0c3ec206f071090dc9bf5d35e99b1f21 Mon Sep 17 00:00:00 2001 From: George Lesica Date: Tue, 9 Jun 2015 10:02:34 -0400 Subject: [PATCH 03/15] Style. --- src/Chromosome.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Chromosome.jl b/src/Chromosome.jl index 8bdab84..e1e31b5 100644 --- a/src/Chromosome.jl +++ b/src/Chromosome.jl @@ -15,7 +15,7 @@ function Chromosome(p::Parameters) outputs = Array(OutputNode, p.numoutputs) fitness = 0.0 - return Chromosome(p, inputs, interiors, outputs ) + return Chromosome(p, inputs, interiors, outputs) end function getindex(c::Chromosome, level::Integer, index::Integer) From 5fdee196ca9ae1f6e104851846304d14f6818d19 Mon Sep 17 00:00:00 2001 From: George Lesica Date: Tue, 9 Jun 2015 10:04:05 -0400 Subject: [PATCH 04/15] Remove commented code. --- src/Execute.jl | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/src/Execute.jl b/src/Execute.jl index 3cd7b8a..7799866 100644 --- a/src/Execute.jl +++ b/src/Execute.jl @@ -1,38 +1,22 @@ export execute_chromosome function evaluate_node(c::Chromosome, node::InputNode, context::Vector{BitString}) - #= - if ! node.active - node.active = true - c.number_active_nodes += 1 - end - =# return context[node.index] end function evaluate_node(c::Chromosome, node::InteriorNode, context::Vector{BitString}) - #if ! node.active - func = node.func - args = map(node.inputs[1:func.arity]) do position - (level, index) = position - evaluate_node(c, c[level, index], context) - end - #node.active = true - #node.cache = func.func(args...) - #c.number_active_nodes += 1 - #end - #return node.cache + func = node.func + args = map(node.inputs[1:func.arity]) do position + (level, index) = position + evaluate_node(c, c[level, index], context) + end + return func.func(args...) end function evaluate_node(c::Chromosome, node::OutputNode, context::Vector{BitString}) - #if ! node.active - #node.active = true - (level, index) = node.input - #node.cache = evaluate_node(c, c[level, index], context) - #c.number_active_nodes += 1 - #end - #return node.cache + (level, index) = node.input + return evaluate_node(c, c[level, index], context) end @@ -42,7 +26,6 @@ end # around. function execute_chromosome(c::Chromosome, context::Vector{BitString}) - #c.active_set = true return BitString[evaluate_node(c, node, context) for node = c.outputs] end From 7ae57b94c953a2ace38afcd4094e91f8c978187b Mon Sep 17 00:00:00 2001 From: George Lesica Date: Tue, 9 Jun 2015 10:05:38 -0400 Subject: [PATCH 05/15] Remove end. --- src/Execute.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Execute.jl b/src/Execute.jl index 7799866..d043211 100644 --- a/src/Execute.jl +++ b/src/Execute.jl @@ -9,7 +9,6 @@ function evaluate_node(c::Chromosome, node::InteriorNode, context::Vector{BitStr args = map(node.inputs[1:func.arity]) do position (level, index) = position evaluate_node(c, c[level, index], context) - end return func.func(args...) end From b02f73e573f801af5ae28d9ca4b09bf11cab3420 Mon Sep 17 00:00:00 2001 From: George Lesica Date: Tue, 9 Jun 2015 10:11:01 -0400 Subject: [PATCH 06/15] Remove commented code. --- src/Mutate.jl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Mutate.jl b/src/Mutate.jl index c584ac8..253cba5 100644 --- a/src/Mutate.jl +++ b/src/Mutate.jl @@ -29,7 +29,6 @@ function mutate(old_c::Chromosome, funcs::Vector{Func} ) end new_c = Chromosome(p) - #new_c.active_set = false # Choose the genes that will be modified, and store their numbers in the array genes_to_mutate genes_to_mutate = Array(Int,num_mutations) @@ -47,7 +46,6 @@ function mutate(old_c::Chromosome, funcs::Vector{Func} ) # Input nodes for i = 1:numinputs new_c.inputs[i] = old_c.inputs[i] - #new_c.inputs[i].active = false end gene_index = 1 @@ -63,7 +61,6 @@ function mutate(old_c::Chromosome, funcs::Vector{Func} ) if genes_to_mutate_index > length(genes_to_mutate) || gene_index + old_func.arity < genes_to_mutate[genes_to_mutate_index] # no mutations in this node new_c.interiors[level, index] = old_c.interiors[level, index] - #new_c.interiors[level, index].active = false gene_index += 1+old_func.arity continue end @@ -114,10 +111,8 @@ function mutate(old_c::Chromosome, funcs::Vector{Func} ) genes_to_mutate_index += 1 (level, index) = random_node_position(p, minlevel, maxlevel) new_c.outputs[i] = OutputNode((level, index)) - #new_c[level, index].active = false else new_c.outputs[i] = old_c.outputs[i] - #new_c.outputs[i].active = false end gene_index += 1 end # for i = From 4a4dcdbabc383f22bf9793dddd0b8d61fb9dd6ec Mon Sep 17 00:00:00 2001 From: George Lesica Date: Tue, 9 Jun 2015 10:16:57 -0400 Subject: [PATCH 07/15] Remove commented code. --- src/Node.jl | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/Node.jl b/src/Node.jl index 44cfd1f..202b5ad 100644 --- a/src/Node.jl +++ b/src/Node.jl @@ -8,24 +8,13 @@ abstract Node type InputNode <: Node index::Integer - #active::Bool end -#InputNode(index::Integer) = InputNode(index, false) - type InteriorNode <: Node func::Func inputs::Vector{NodePosition} - #active::Bool - #cache::BitString end -#InteriorNode(func::Func, inputs::Vector{NodePosition}) = InteriorNode(func, inputs, false, convert(BitString, 0)) - type OutputNode <: Node input::NodePosition - #active::Bool - #cache::BitString end - -#OutputNode(input::NodePosition) = OutputNode(input, false, convert(BitString, 0)) From 02a74088937142b241dba8d83ebec3fee666bb81 Mon Sep 17 00:00:00 2001 From: George Lesica Date: Tue, 9 Jun 2015 10:18:47 -0400 Subject: [PATCH 08/15] Remove commented code. --- examples/EvolveGoals.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/EvolveGoals.jl b/examples/EvolveGoals.jl index f582466..daf1841 100644 --- a/examples/EvolveGoals.jl +++ b/examples/EvolveGoals.jl @@ -58,7 +58,6 @@ end # This is the function used by pmap to evolve each goal in goal_list @everywhere function p_mu_lambda(g) (ch,gens) = mu_lambda(p,g,max_gens) - #n = ch.number_active_nodes n = 0 (g.truth_table,gens,n) end From 670a4949264e7ca5c01ccc59961938b1ad993ca6 Mon Sep 17 00:00:00 2001 From: George Lesica Date: Tue, 9 Jun 2015 10:26:18 -0400 Subject: [PATCH 09/15] Add back `end`. --- src/Execute.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Execute.jl b/src/Execute.jl index d043211..7799866 100644 --- a/src/Execute.jl +++ b/src/Execute.jl @@ -9,6 +9,7 @@ function evaluate_node(c::Chromosome, node::InteriorNode, context::Vector{BitStr args = map(node.inputs[1:func.arity]) do position (level, index) = position evaluate_node(c, c[level, index], context) + end return func.func(args...) end From dd9c5dd6d804e101121b32b552a4c1fc474efad1 Mon Sep 17 00:00:00 2001 From: Alden Wright Date: Tue, 9 Jun 2015 18:03:45 -0600 Subject: [PATCH 10/15] Wrote NodeCache.jl and ChromosomeCache.jl to implement a data structure parallel to Chromosome which can store the "active" and "cache" fields of nodes. Modified Chromosome to add this parallel data structure. Added NodeCache.jl and ChromosomeCache.jl to the files listed in CGP.jl. However, at this point, even "using CGP" is not working. --- src/ChromosomeCache.jl | 32 ++++++++++++++++++++++++++++++++ src/NodeCache.jl | 24 ++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/ChromosomeCache.jl create mode 100644 src/NodeCache.jl diff --git a/src/ChromosomeCache.jl b/src/ChromosomeCache.jl new file mode 100644 index 0000000..d481c88 --- /dev/null +++ b/src/ChromosomeCache.jl @@ -0,0 +1,32 @@ +import Base.getindex + +export ChromosomeCache, getindex + +type ChromosomeCache + params::Parameters + inputs::Vector{InputNodeCache} + interiors::Matrix{InteriorNodeCache} + outputs::Vector{OuputNodeCache} +end + +function ChromosomeCache(p::Parameters) + inputs = Array(InputNodeCache, p.numinputs) + interiors = Array(InteriorNodeCache, p.numlevels, p.numperlevel) + outputs = Array(OutputNodeCache, p.numoutputs) + + return ChromosomeCache(p, inputs, interiors, outputs) +end + +function getindex(c::ChromosomeCache, level::Integer, index::Integer) + if level == 0 + return c.inputs[index] + end + + if level > c.params.numlevels + return c.outputs[index] + end + + return c.interiors[level, index] +end + + diff --git a/src/NodeCache.jl b/src/NodeCache.jl new file mode 100644 index 0000000..d7d2263 --- /dev/null +++ b/src/NodeCache.jl @@ -0,0 +1,24 @@ +export NodeCache, InputNodeCache, InteriorNodeCache, OutputNodeCache + +abstract NodeCache + +type InputNodeCache <: NodeCache + active::Bool +end + +InputNodeCache() = InputNodeCache(false) + +type InteriorNodeCache <: NodeCache + active::Bool + cache::BitString +end + +InteriorNodeCache() = InteriorNodeCache(false, convert(BitString, 0)) + +type OutputNodeCache <: NodeCache + active::Bool + cache::BitString +end + +OutputNodeCache() = OutputNodeCache(false, convert(BitString, 0)) + From 1279d5cb8b917b8fef057f7e83d572ef443ab86c Mon Sep 17 00:00:00 2001 From: Alden Wright Date: Wed, 10 Jun 2015 17:59:10 -0600 Subject: [PATCH 11/15] Modified the Chromosome type to add the fields "has_cache" and "cache". The cache is defined in ChromosomeCache.jl and NodeCache.jl, and is a parallel data structure that contains the "active" and "cache" filds in each node. A chromosome can be executed without using the "active" and "cache" fields using execute_chromosome() and with using these fields by using execute_chromosome_cache(). Appropriate modifications to Mutate.jl and to function print_chromosome() in Chromosome.jl have NOT been made. --- src/CGP.jl | 3 +++ src/Chromosome.jl | 6 ++++- src/ChromosomeCache.jl | 18 ++++++++++--- src/ExecuteCache.jl | 60 ++++++++++++++++++++++++++++++++++++++++++ test/Evolution.jl | 2 ++ 5 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 src/ExecuteCache.jl diff --git a/src/CGP.jl b/src/CGP.jl index f8c56b5..80726dd 100644 --- a/src/CGP.jl +++ b/src/CGP.jl @@ -3,12 +3,15 @@ module CGP include("BitString.jl") include("Func.jl") include("Parameters.jl") +include("NodeCache.jl") +include("ChromosomeCache.jl") include("Node.jl") include("Chromosome.jl") include("Goal.jl") include("Fitness.jl") include("Mutate.jl") include("Execute.jl") +include("ExecuteCache.jl") include("Evolution.jl") include("Utilities.jl") diff --git a/src/Chromosome.jl b/src/Chromosome.jl index e1e31b5..8d2ed9f 100644 --- a/src/Chromosome.jl +++ b/src/Chromosome.jl @@ -7,6 +7,8 @@ type Chromosome inputs::Vector{InputNode} interiors::Matrix{InteriorNode} outputs::Vector{OutputNode} + has_cache::Bool + cache::ChromosomeCache end function Chromosome(p::Parameters) @@ -14,8 +16,10 @@ function Chromosome(p::Parameters) interiors = Array(InteriorNode, p.numlevels, p.numperlevel) outputs = Array(OutputNode, p.numoutputs) fitness = 0.0 + has_cache = false + chc = ChromosomeCache(p,true) - return Chromosome(p, inputs, interiors, outputs) + return Chromosome(p, inputs, interiors, outputs, has_cache, chc ) end function getindex(c::Chromosome, level::Integer, index::Integer) diff --git a/src/ChromosomeCache.jl b/src/ChromosomeCache.jl index d481c88..5047685 100644 --- a/src/ChromosomeCache.jl +++ b/src/ChromosomeCache.jl @@ -6,13 +6,23 @@ type ChromosomeCache params::Parameters inputs::Vector{InputNodeCache} interiors::Matrix{InteriorNodeCache} - outputs::Vector{OuputNodeCache} + outputs::Vector{OutputNodeCache} end -function ChromosomeCache(p::Parameters) - inputs = Array(InputNodeCache, p.numinputs) +function ChromosomeCache(p::Parameters, fill::Bool = false ) interiors = Array(InteriorNodeCache, p.numlevels, p.numperlevel) - outputs = Array(OutputNodeCache, p.numoutputs) + if fill + inputs = [ InputNodeCache() for i in 1:p.numinputs ] + outputs = [ OutputNodeCache() for i in 1:p.numoutputs ] + for i in 1:p.numlevels + for j in 1:p.numperlevel + interiors[i,j] = InteriorNodeCache() + end + end + else + inputs = Array(InputNodeCache, p.numinputs) + outputs = Array(OutputNodeCache, p.numoutputs) + end return ChromosomeCache(p, inputs, interiors, outputs) end diff --git a/src/ExecuteCache.jl b/src/ExecuteCache.jl new file mode 100644 index 0000000..a11a198 --- /dev/null +++ b/src/ExecuteCache.jl @@ -0,0 +1,60 @@ +export execute_chromosome_cache, get_number_active_nodes + +function evaluate_node_cache(c::Chromosome, node::InputNode, cnode::InputNodeCache, context::Vector{BitString}) + if ! cnode.active + cnode.active = true + #c.number_active_nodes += 1 # do not remove: I want to add this back in later + end + return context[node.index] +end + +function evaluate_node_cache(c::Chromosome, node::InteriorNode, cnode::InteriorNodeCache, context::Vector{BitString}) + if ! cnode.active + func = node.func + args = map(node.inputs[1:func.arity]) do position + (level, index) = position + evaluate_node_cache(c, c[level, index], c.cache[level,index], context) + end + cnode.active = true + cnode.cache = func.func(args...) + #c.number_active_nodes += 1 + end + return cnode.cache +end + +function evaluate_node_cache(c::Chromosome, node::OutputNode, cnode::OutputNodeCache, context::Vector{BitString}) + if ! cnode.active + cnode.active = true + (level, index) = node.input + cnode.cache = evaluate_node_cache(c, c[level, index], c.cache[level,index], context) + #c.number_active_nodes += 1 + end + return cnode.cache +end + +# TODO: Since we are caching the evaluation results we should no +# longer expose the context since providing two different contexts for +# the same chromosome will produce incorrect results the second time +# around. + +function execute_chromosome_cache(c::Chromosome, context::Vector{BitString}) + if ! c.has_cache + c.cache = ChromosomeCache(c.params,true) + c.has_cache = true + println("cache: ",c.cache) + end + return BitString[evaluate_node_cache(c, c.outputs[i], c.cache.outputs[i], context) + for i = 1:length(c.outputs)] +end + +# Executes chrososome using the standard input context +function execute_chromosome_cache(c::Chromosome) + params = c.params + mask = output_mask(params.numinputs) + + ctx = std_input_context(params.numinputs) + result = execute_chromosome_cache(c, ctx) + + return BitString[x & mask for x = result] +end + diff --git a/test/Evolution.jl b/test/Evolution.jl index 13b5df9..cd39c31 100644 --- a/test/Evolution.jl +++ b/test/Evolution.jl @@ -53,9 +53,11 @@ srand(1) (ch,gens) = mu_lambda(p, goal, maxgens) # The intention here is to compare ch with chromosome_half_adder(), but == does not work for comparison. +#= print_chromosome(ch) ch_ha = chromosome_half_adder() execute_chromosome(ch_ha) # Sets active nodes to active print_chromosome(ch_ha) +=# #@test ch == ch_ha From 6679be7211ec6114915818bafc5541fb932a622e Mon Sep 17 00:00:00 2001 From: Alden Wright Date: Mon, 15 Jun 2015 22:13:51 -0600 Subject: [PATCH 12/15] ChromosomeCache.jl and NodeCache.jl define a "parallel" data struture to Chromosome.jl and Node.jl which stores the cache and active fields for each node of a Chromosome. This allows execution with and without caching. For single-ouput goals, without caching seems to be considerably fast. The other changed files adapt to these changes in the data structures. --- examples/EvolveGoals.jl | 17 ++++++++------- src/Chromosome.jl | 46 ++++++++++++++++++++--------------------- src/ChromosomeCache.jl | 4 +++- src/Evolution.jl | 4 ++-- src/Execute.jl | 38 +++++++++++++++++++++++++++++++++- src/Mutate.jl | 3 ++- test/Chromosome.jl | 18 ++++++++-------- test/evolve_adders.jl | 21 +++++++++---------- 8 files changed, 96 insertions(+), 55 deletions(-) diff --git a/examples/EvolveGoals.jl b/examples/EvolveGoals.jl index daf1841..10ea48c 100644 --- a/examples/EvolveGoals.jl +++ b/examples/EvolveGoals.jl @@ -23,17 +23,18 @@ macro otime(ex) # A high-level function to run function evolve_goals. # it sets the summary to the filename, and max_gens to default values +# If use_cache is true, then each node caches its value. This may be faster for multiple outputs. # Example: run_evolve_goals("prun",2,13,10,20) # calls "evolve_goals" with numinputs=2, rseed=13,numlevels=10,runs_per_goal=20 # and the output going to the file: prun2_13_10_20.csv -function run_evolve_goals(filename_prefix,numinputs,rseed,num_levels,runs_per_goal) +function run_evolve_goals(filename_prefix,numinputs,rseed,num_levels,runs_per_goal, use_cache::Bool=false) directory = "out/" # subdirectory for output CSV file filetype = ".csv" # file extension underscore = "_" filename = "$directory$filename_prefix$numinputs$underscore$rseed$underscore$num_levels$underscore$runs_per_goal$filetype" ost = open(filename,"w") max_gens = numinputs == 2 ? 10000 : 50000 - @otime ost = evolve_goals(ost,filename,numinputs,num_levels,runs_per_goal,max_gens,rseed) + @otime ost = evolve_goals(ost,filename,numinputs,num_levels,runs_per_goal,max_gens,rseed,use_cache) close(ost) end @@ -55,15 +56,15 @@ end num_inputs end -# This is the function used by pmap to evolve each goal in goal_list +# This is the function used by mape and pmap to evolve each goal in goal_list @everywhere function p_mu_lambda(g) - (ch,gens) = mu_lambda(p,g,max_gens) - n = 0 + use_cache = true + (ch,gens) = mu_lambda(p,g,max_gens,usecache) + n = ch.cache.number_active_nodes (g.truth_table,gens,n) end @everywhere function goal_list_setup(numinputs,num_levels,runs_per_goal,maxgens) - #println("goal list setup: proc:",myid()," numinputs:",numinputs) global mutrate = 0.05 global mu = 1 global lambda = 4 @@ -98,7 +99,9 @@ end # For each goal, the output is the goal, the average number of generations, and the average number of active nodes. # Creates a CSV file with the parameter settings followed by the above described output for each run. # Also writes this information to stdout so that the user can see the progress made. -function evolve_goals( outstream::IOStream, summary::String, num_inputs, num_levels, runs_per_goal, max_gens, rseed) +function evolve_goals( outstream::IOStream, summary::String, + num_inputs, num_levels, runs_per_goal, max_gens, rseed, use_cache::Bool=false) + global usecache = use_cache for proc in procs() lg = remotecall_fetch(proc,goal_list_setup,num_inputs, num_levels, runs_per_goal, max_gens ) end diff --git a/src/Chromosome.jl b/src/Chromosome.jl index 8d2ed9f..da8dda2 100644 --- a/src/Chromosome.jl +++ b/src/Chromosome.jl @@ -11,15 +11,13 @@ type Chromosome cache::ChromosomeCache end -function Chromosome(p::Parameters) +function Chromosome(p::Parameters,use_cache::Bool=false) inputs = Array(InputNode, p.numinputs) interiors = Array(InteriorNode, p.numlevels, p.numperlevel) outputs = Array(OutputNode, p.numoutputs) - fitness = 0.0 - has_cache = false - chc = ChromosomeCache(p,true) + chc = ChromosomeCache(p,use_cache) - return Chromosome(p, inputs, interiors, outputs, has_cache, chc ) + return Chromosome(p, inputs, interiors, outputs, use_cache, chc ) end function getindex(c::Chromosome, level::Integer, index::Integer) @@ -35,17 +33,22 @@ function getindex(c::Chromosome, level::Integer, index::Integer) end # Prints the chromosome in a compact text format (on one line). Active notes -# are indicated with a "+" and inactive notes with a "*". If the chromosome -# has not been evaluated, the active field is set to "?" since the status of -# the nodes (with the exception of output nodes) is unknown. If active_only is +# are indicated with a "+" and inactive notes with a "*". If active_only is # true, then only the active notes are shown. -function print_chromosome(c::Chromosome, active_only::Bool) - active_set = c.active_set +function print_chromosome(c::Chromosome, active_only::Bool=false) + has_cache_incoming = c.has_cache + if ! c.has_cache + c.cache = ChromosomeCache(c.params,true) + c.has_cache = true + end + if ! c.cache.outputs[1].active # will be true if chromosome has been executed + execute_chromosome(c) # execute chromosome so that active nodes will be determined + end # Input nodes for i = 1:length(c.inputs) - if c.inputs[i].active || !active_only - active = c.inputs[i].active ? "+" : (active_set ? "*" : "?") + if c.cache.inputs[i].active || !active_only + active = c.cache.inputs[i].active ? "+" : "*" print("[in", i, active, "] ") end end @@ -53,8 +56,8 @@ function print_chromosome(c::Chromosome, active_only::Bool) # Interior nodes for i = 1:c.params.numlevels for j = 1:c.params.numperlevel - if c.interiors[i,j].active || !active_only - active = c.interiors[i,j].active ? "+" : (active_set ? "*" : "?") + if c.cache.interiors[i,j].active || !active_only + active = c.cache.interiors[i,j].active ? "+" : "*" print("[") for k = 1:length(c.interiors[i,j].inputs) if c.interiors[i,j].inputs[k][1] == 0 @@ -70,17 +73,14 @@ function print_chromosome(c::Chromosome, active_only::Bool) # Output nodes for i = 1:length(c.outputs) - active = c.outputs[i].active ? "+" : (active_set ? "*" : "?") + active = c.cache.outputs[i].active ? "+" : "*" print("[", c.outputs[i].input, "out", i, active, "] ") end println() + c.has_cache = has_cache_incoming # reset to original status return end -function print_chromosome(c::Chromosome) - print_chromosome(c, false) -end - function first_in_level(p::Parameters, level::Integer) if level == 0 first = 1 @@ -116,12 +116,12 @@ function random_node_position(p::Parameters, minlevel::Integer, maxlevel::Intege return (level, index) end -function random_chromosome(p::Parameters ) - return random_chromosome(p, p.funcs) +function random_chromosome(p::Parameters, fill::Bool=false ) + return random_chromosome(p, p.funcs,fill) end -function random_chromosome(p::Parameters, funcs::Vector{Func}) - c = Chromosome(p) +function random_chromosome(p::Parameters, funcs::Vector{Func}, fill::Bool=false) + c = Chromosome(p,fill) for index = 1:length(c.inputs) c.inputs[index] = InputNode(index) diff --git a/src/ChromosomeCache.jl b/src/ChromosomeCache.jl index 5047685..b03f1fb 100644 --- a/src/ChromosomeCache.jl +++ b/src/ChromosomeCache.jl @@ -7,9 +7,11 @@ type ChromosomeCache inputs::Vector{InputNodeCache} interiors::Matrix{InteriorNodeCache} outputs::Vector{OutputNodeCache} + number_active_nodes::Int end function ChromosomeCache(p::Parameters, fill::Bool = false ) + number_active_nodes = 0 interiors = Array(InteriorNodeCache, p.numlevels, p.numperlevel) if fill inputs = [ InputNodeCache() for i in 1:p.numinputs ] @@ -24,7 +26,7 @@ function ChromosomeCache(p::Parameters, fill::Bool = false ) outputs = Array(OutputNodeCache, p.numoutputs) end - return ChromosomeCache(p, inputs, interiors, outputs) + return ChromosomeCache(p, inputs, interiors, outputs, number_active_nodes ) end function getindex(c::ChromosomeCache, level::Integer, index::Integer) diff --git a/src/Evolution.jl b/src/Evolution.jl index 329d540..52c214c 100644 --- a/src/Evolution.jl +++ b/src/Evolution.jl @@ -5,14 +5,14 @@ export mu_lambda # mu is the number of parents and lambda is the number of children in each generation # mu and lambda are components of the parameters # gens is the maximum number of generations run -function mu_lambda(p::Parameters, goal::Goal, gens::Integer) +function mu_lambda(p::Parameters, goal::Goal, gens::Integer, use_cache::Bool=false) mu = p.mu lambda = p.lambda funcs = p.funcs fitfunc = p.fitfunc perfect = p.targetfitness - pop = [random_chromosome(p) for _ in 1:(mu+lambda) ] + pop = [random_chromosome(p,use_cache) for _ in 1:(mu+lambda) ] fit = [fitness(c,goal,fitfunc) for c in pop ] perm = sortperm(fit, rev=true) diff --git a/src/Execute.jl b/src/Execute.jl index 7799866..0245363 100644 --- a/src/Execute.jl +++ b/src/Execute.jl @@ -4,6 +4,14 @@ function evaluate_node(c::Chromosome, node::InputNode, context::Vector{BitString return context[node.index] end +function evaluate_node(c::Chromosome, node::InputNode, cache_node::InputNodeCache, context::Vector{BitString}) + if ! cache_node.active + cache_node.active = true + c.cache.number_active_nodes += 1 + end + return context[node.index] +end + function evaluate_node(c::Chromosome, node::InteriorNode, context::Vector{BitString}) func = node.func args = map(node.inputs[1:func.arity]) do position @@ -14,19 +22,47 @@ function evaluate_node(c::Chromosome, node::InteriorNode, context::Vector{BitStr return func.func(args...) end +function evaluate_node(c::Chromosome, node::InteriorNode, cache_node::InteriorNodeCache, context::Vector{BitString}) + if ! cache_node.active + func = node.func + args = map(node.inputs[1:func.arity]) do position + (level, index) = position + evaluate_node(c, c[level, index], c.cache[level,index], context) + end + cache_node.active = true + cache_node.cache = func.func(args...) + c.cache.number_active_nodes += 1 + end + return cache_node.cache +end + function evaluate_node(c::Chromosome, node::OutputNode, context::Vector{BitString}) (level, index) = node.input return evaluate_node(c, c[level, index], context) end +function evaluate_node(c::Chromosome, node::OutputNode, cache_node::OutputNodeCache, context::Vector{BitString}) + if ! cache_node.active + cache_node.active = true + (level, index) = node.input + cache_node.cache = evaluate_node(c, c[level, index], c.cache[level,index], context) + c.cache.number_active_nodes += 1 + end + return cache_node.cache +end + # TODO: Since we are caching the evaluation results we should no # longer expose the context since providing two different contexts for # the same chromosome will produce incorrect results the second time # around. function execute_chromosome(c::Chromosome, context::Vector{BitString}) - return BitString[evaluate_node(c, node, context) for node = c.outputs] + if c.has_cache + return BitString[evaluate_node(c, c.outputs[i], c.cache.outputs[i], context) for i in 1:length(c.outputs)] + else + return BitString[evaluate_node(c, node, context) for node = c.outputs] + end end # Executes chrososome using the standard input context diff --git a/src/Mutate.jl b/src/Mutate.jl index 253cba5..baba80b 100644 --- a/src/Mutate.jl +++ b/src/Mutate.jl @@ -28,7 +28,7 @@ function mutate(old_c::Chromosome, funcs::Vector{Func} ) error("more mutations than genes in function mutate") end - new_c = Chromosome(p) + new_c = Chromosome(p,old_c.has_cache) # Choose the genes that will be modified, and store their numbers in the array genes_to_mutate genes_to_mutate = Array(Int,num_mutations) @@ -116,5 +116,6 @@ function mutate(old_c::Chromosome, funcs::Vector{Func} ) end gene_index += 1 end # for i = + #println("mutate new_c.has_cache: ",new_c.has_cache) return new_c end diff --git a/test/Chromosome.jl b/test/Chromosome.jl index 724f545..0dceab3 100644 --- a/test/Chromosome.jl +++ b/test/Chromosome.jl @@ -11,14 +11,14 @@ numlevelsback0 = 1 f0 = default_funcs() p0 = Parameters(numinputs0, numoutputs0, numperlevel0, numlevels0, numlevelsback0) -c0 = Chromosome(p0) +c0 = Chromosome(p0,true) c0.inputs = [InputNode(1), InputNode(2)] c0.interiors = [InteriorNode(XOR, [(0, 1), (0, 2)]) InteriorNode(AND, [(0, 1), (0, 2)])] c0.outputs = [OutputNode((1, 1)), OutputNode((1, 2))] @test execute_chromosome(c0) == BitString[0x6,0x8] -@test c0.number_active_nodes == 6 +@test c0.cache.number_active_nodes == 6 numinputs1 = 2 numoutputs1 = 2 @@ -27,7 +27,7 @@ numlevels1 = 5 numlevelsback1 = 5 p1 = Parameters(numinputs1, numoutputs1, numperlevel1, numlevels1, numlevelsback1) -c1 = Chromosome(p1) +c1 = Chromosome(p1,true) c1.inputs = [InputNode(1), InputNode(2)] c1.interiors = Array(InteriorNode, p1.numlevels, p1.numperlevel) @@ -38,9 +38,9 @@ c1.interiors[4,1] = InteriorNode(AND, [(1, 1), (0, 2)]) c1.interiors[5,1] = InteriorNode(AND, [(2, 1), (0, 2)]) c1.outputs = [OutputNode((5, 1)),OutputNode((4,1))] @test execute_chromosome(c1) == BitString[0x2,0xa] -@test c1.number_active_nodes == 8 -@test c1.interiors[1,1].active == true -@test c1.interiors[2,1].active == true -@test c1.interiors[3,1].active == false -@test c1.interiors[4,1].active == true -@test c1.interiors[5,1].active == true +@test c1.cache.number_active_nodes == 8 +@test c1.cache.interiors[1,1].active == true +@test c1.cache.interiors[2,1].active == true +@test c1.cache.interiors[3,1].active == false +@test c1.cache.interiors[4,1].active == true +@test c1.cache.interiors[5,1].active == true diff --git a/test/evolve_adders.jl b/test/evolve_adders.jl index b7947ff..3f0d4ce 100644 --- a/test/evolve_adders.jl +++ b/test/evolve_adders.jl @@ -1,5 +1,5 @@ -include("../src/CGP.jl") -include("../src/Mutate.jl") +#include("../src/CGP.jl") +#include("../src/Mutate.jl") using CGP using Base.Test @@ -10,7 +10,7 @@ using Base.Test function parameters_half_adder() numperlevel = 1 - numlevels = 2 + numlevels = 7 numlevelsback = numlevels numinputs = 2 numoutputs = 2 @@ -65,29 +65,26 @@ end p = parameters_half_full_adder() g = goal_half_full_adder() n = 100000 -println("runing mu_lambda on half full adder") +println("Runing mu_lambda on half full adder") r = mu_lambda(p, g, n) -#println("trying evolve on half full adder") -#r = evolve(p, g, n) println("fitness:",fitness(r[1], g)," gens:",r[2]) @assert fitness(r[1], g) == p.targetfitness @assert r[2] <= n print_chromosome(r[1]) -#= # Full adder function parameters_full_adder() numperlevel = 1 - numlevels = 4 + numlevels = 20 numlevelsback = numlevels numinputs = 3 numoutputs = 2 mu = 1 lambda = 4 - mutrate = 0.1 + mutrate = 0.05 targetfitness = 1.0 funcs = [AND, OR, XOR] fitfunc = hamming_max @@ -101,10 +98,12 @@ end p = parameters_full_adder() g = goal_full_adder() -n = 100000 +n = 1000000 +println("Runing mu_lambda on full adder") +println("This may take a while!!") r = mu_lambda(p, g, n) +println("fitness:",fitness(r[1], g)," gens:",r[2]) @assert fitness(r[1], g) == p.targetfitness @assert r[2] <= n print_chromosome(r[1]) -=# From 2fd28e550fc9a4c5a72bb1316ec87dc6edcf3586 Mon Sep 17 00:00:00 2001 From: Alden Wright Date: Tue, 16 Jun 2015 12:58:14 -0600 Subject: [PATCH 13/15] Added comments and did cleanup. Improved some of the tests in test/Chromosome.jl and test/Evolution.jl. --- src/Chromosome.jl | 9 +++++---- src/ChromosomeCache.jl | 8 ++++++-- src/NodeCache.jl | 3 +++ test/Chromosome.jl | 18 ++++++++++++++---- test/Evolution.jl | 2 +- 5 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/Chromosome.jl b/src/Chromosome.jl index da8dda2..4682503 100644 --- a/src/Chromosome.jl +++ b/src/Chromosome.jl @@ -35,6 +35,7 @@ end # Prints the chromosome in a compact text format (on one line). Active notes # are indicated with a "+" and inactive notes with a "*". If active_only is # true, then only the active notes are shown. +# TO DO: A version that prints to a stream and a version that prints to a string function print_chromosome(c::Chromosome, active_only::Bool=false) has_cache_incoming = c.has_cache if ! c.has_cache @@ -116,12 +117,12 @@ function random_node_position(p::Parameters, minlevel::Integer, maxlevel::Intege return (level, index) end -function random_chromosome(p::Parameters, fill::Bool=false ) - return random_chromosome(p, p.funcs,fill) +function random_chromosome(p::Parameters, use_cache::Bool=false ) + return random_chromosome(p, p.funcs,use_cache) end -function random_chromosome(p::Parameters, funcs::Vector{Func}, fill::Bool=false) - c = Chromosome(p,fill) +function random_chromosome(p::Parameters, funcs::Vector{Func}, use_cache::Bool=false) + c = Chromosome(p,use_cache) for index = 1:length(c.inputs) c.inputs[index] = InputNode(index) diff --git a/src/ChromosomeCache.jl b/src/ChromosomeCache.jl index b03f1fb..88ac7ce 100644 --- a/src/ChromosomeCache.jl +++ b/src/ChromosomeCache.jl @@ -2,6 +2,8 @@ import Base.getindex export ChromosomeCache, getindex +# Inputs, interiors, and outputs can contain NodeCaches that store the active status of the Chromosome that owns the ChromosomeCache +# See NodeCache.jl for details about the NodeCache type. type ChromosomeCache params::Parameters inputs::Vector{InputNodeCache} @@ -10,10 +12,12 @@ type ChromosomeCache number_active_nodes::Int end -function ChromosomeCache(p::Parameters, fill::Bool = false ) +# if use_cache == false, then interiors, inputs, outputs are arrays whose contents are undefined. +# if use_cache == true, then interiors, inputs, outputs are arrays whose contents are NodeCaches. +function ChromosomeCache(p::Parameters, use_cache::Bool = false ) number_active_nodes = 0 interiors = Array(InteriorNodeCache, p.numlevels, p.numperlevel) - if fill + if use_cache inputs = [ InputNodeCache() for i in 1:p.numinputs ] outputs = [ OutputNodeCache() for i in 1:p.numoutputs ] for i in 1:p.numlevels diff --git a/src/NodeCache.jl b/src/NodeCache.jl index d7d2263..99e3df3 100644 --- a/src/NodeCache.jl +++ b/src/NodeCache.jl @@ -1,5 +1,8 @@ export NodeCache, InputNodeCache, InteriorNodeCache, OutputNodeCache +# Stores whether the corresponding Node is active, i. e. is used during evaluation. +# If the corresponding Node is active, then the cache stores the its value. +# Values of active and cache are set when the corresponding Chromosome is executed. abstract NodeCache type InputNodeCache <: NodeCache diff --git a/test/Chromosome.jl b/test/Chromosome.jl index 0dceab3..a16ea8a 100644 --- a/test/Chromosome.jl +++ b/test/Chromosome.jl @@ -11,14 +11,19 @@ numlevelsback0 = 1 f0 = default_funcs() p0 = Parameters(numinputs0, numoutputs0, numperlevel0, numlevels0, numlevelsback0) -c0 = Chromosome(p0,true) +c0 = Chromosome(p0,true) # c0 has a cache c0.inputs = [InputNode(1), InputNode(2)] c0.interiors = [InteriorNode(XOR, [(0, 1), (0, 2)]) InteriorNode(AND, [(0, 1), (0, 2)])] c0.outputs = [OutputNode((1, 1)), OutputNode((1, 2))] @test execute_chromosome(c0) == BitString[0x6,0x8] -@test c0.cache.number_active_nodes == 6 +@test c0.cache.number_active_nodes == 6 # set during execution +# Remove cache +c0.cache = ChromosomeCache(p0) # Nonfunctional cache +c0.has_cache = false +@test execute_chromosome(c0) == BitString[0x6,0x8] # Value should not change +#print_chromosome(c0) numinputs1 = 2 numoutputs1 = 2 @@ -27,7 +32,7 @@ numlevels1 = 5 numlevelsback1 = 5 p1 = Parameters(numinputs1, numoutputs1, numperlevel1, numlevels1, numlevelsback1) -c1 = Chromosome(p1,true) +c1 = Chromosome(p1,true) # c1 has a cache c1.inputs = [InputNode(1), InputNode(2)] c1.interiors = Array(InteriorNode, p1.numlevels, p1.numperlevel) @@ -38,9 +43,14 @@ c1.interiors[4,1] = InteriorNode(AND, [(1, 1), (0, 2)]) c1.interiors[5,1] = InteriorNode(AND, [(2, 1), (0, 2)]) c1.outputs = [OutputNode((5, 1)),OutputNode((4,1))] @test execute_chromosome(c1) == BitString[0x2,0xa] -@test c1.cache.number_active_nodes == 8 +@test c1.cache.number_active_nodes == 8 # set during execution @test c1.cache.interiors[1,1].active == true @test c1.cache.interiors[2,1].active == true @test c1.cache.interiors[3,1].active == false @test c1.cache.interiors[4,1].active == true @test c1.cache.interiors[5,1].active == true +# Remove cache +c1.cache = ChromosomeCache(p1) # Nonfunctional cache +c1.has_cache = false +@test execute_chromosome(c1) == BitString[0x2,0xa] # Value should not change +#print_chromosome(c1) diff --git a/test/Evolution.jl b/test/Evolution.jl index cd39c31..a7f7760 100644 --- a/test/Evolution.jl +++ b/test/Evolution.jl @@ -54,9 +54,9 @@ srand(1) (ch,gens) = mu_lambda(p, goal, maxgens) # The intention here is to compare ch with chromosome_half_adder(), but == does not work for comparison. #= +# If uncommented, the printed chromosomes should be the same. print_chromosome(ch) ch_ha = chromosome_half_adder() -execute_chromosome(ch_ha) # Sets active nodes to active print_chromosome(ch_ha) =# #@test ch == ch_ha From 16d715e5fc5f31ab697d1b9aef3b30cbcc840103 Mon Sep 17 00:00:00 2001 From: Alden Wright Date: Tue, 16 Jun 2015 14:27:30 -0600 Subject: [PATCH 14/15] Changed the type of the cache field of the Chromosome type from ChromosomeCache to Union(Nothing,ChromosomeCache). When there is no cache, this field will be "nothing". Revised comments and fixed a bug in examples/EvolveGoals.jl --- examples/EvolveGoals.jl | 23 ++++++++++++----------- src/Chromosome.jl | 9 ++++++--- src/Mutate.jl | 1 - 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/examples/EvolveGoals.jl b/examples/EvolveGoals.jl index 10ea48c..81b3c61 100644 --- a/examples/EvolveGoals.jl +++ b/examples/EvolveGoals.jl @@ -27,6 +27,10 @@ macro otime(ex) # Example: run_evolve_goals("prun",2,13,10,20) # calls "evolve_goals" with numinputs=2, rseed=13,numlevels=10,runs_per_goal=20 # and the output going to the file: prun2_13_10_20.csv +# The default is to not use caching and to not keep track of active nodes. +# To use caching in the above example: run_evolve_goals("prun",2,13,20,true) +# If julia is started with mulitple processes, e. g.: "julia -p 8", then these multiple processes will +# be used on different calls to function mu_lambda(). function run_evolve_goals(filename_prefix,numinputs,rseed,num_levels,runs_per_goal, use_cache::Bool=false) directory = "out/" # subdirectory for output CSV file filetype = ".csv" # file extension @@ -50,27 +54,25 @@ end return Parameters(mu, lambda, mutrate, targetfitness, numinputs, numoutputs, numperlevel, numlevels, numlevelsback, funcs, fitfunc) end -@everywhere function global_setup(numinputs,maxgens) - global num_inputs = numinputs - global max_gens = maxgens - num_inputs -end - # This is the function used by mape and pmap to evolve each goal in goal_list @everywhere function p_mu_lambda(g) - use_cache = true (ch,gens) = mu_lambda(p,g,max_gens,usecache) - n = ch.cache.number_active_nodes + if ch.has_cache + n = ch.cache.number_active_nodes + else + n = 0 + end (g.truth_table,gens,n) end -@everywhere function goal_list_setup(numinputs,num_levels,runs_per_goal,maxgens) +@everywhere function goal_list_setup(numinputs,num_levels,runs_per_goal,maxgens,use_cache) global mutrate = 0.05 global mu = 1 global lambda = 4 global num_inputs = numinputs global max_gens = maxgens global num_goals = 2^2^numinputs + global usecache = use_cache global p = Params(mu,lambda,numinputs,1,1,num_levels,num_levels,mutrate,raman_funcs) global goal_list = [Goal(numinputs,(convert(BitString,div(i,runs_per_goal)),)) for i in 0:num_goals*runs_per_goal-1] length(goal_list) @@ -101,9 +103,8 @@ end # Also writes this information to stdout so that the user can see the progress made. function evolve_goals( outstream::IOStream, summary::String, num_inputs, num_levels, runs_per_goal, max_gens, rseed, use_cache::Bool=false) - global usecache = use_cache for proc in procs() - lg = remotecall_fetch(proc,goal_list_setup,num_inputs, num_levels, runs_per_goal, max_gens ) + lg = remotecall_fetch(proc,goal_list_setup,num_inputs, num_levels, runs_per_goal, max_gens, use_cache ) end println(outstream,summary) println(outstream,Dates.now()) diff --git a/src/Chromosome.jl b/src/Chromosome.jl index 4682503..b785e32 100644 --- a/src/Chromosome.jl +++ b/src/Chromosome.jl @@ -8,15 +8,18 @@ type Chromosome interiors::Matrix{InteriorNode} outputs::Vector{OutputNode} has_cache::Bool - cache::ChromosomeCache + cache::Union(Nothing,ChromosomeCache) # If has_cache is false, then cache should be nothing. end function Chromosome(p::Parameters,use_cache::Bool=false) inputs = Array(InputNode, p.numinputs) interiors = Array(InteriorNode, p.numlevels, p.numperlevel) outputs = Array(OutputNode, p.numoutputs) - chc = ChromosomeCache(p,use_cache) - + if use_cache + chc = ChromosomeCache(p,use_cache) + else + chc = nothing + end return Chromosome(p, inputs, interiors, outputs, use_cache, chc ) end diff --git a/src/Mutate.jl b/src/Mutate.jl index baba80b..3c58606 100644 --- a/src/Mutate.jl +++ b/src/Mutate.jl @@ -116,6 +116,5 @@ function mutate(old_c::Chromosome, funcs::Vector{Func} ) end gene_index += 1 end # for i = - #println("mutate new_c.has_cache: ",new_c.has_cache) return new_c end From b0e5b7b8d390e9a72973b2dba0ff760aec61d437 Mon Sep 17 00:00:00 2001 From: Alden Wright Date: Tue, 16 Jun 2015 15:23:13 -0600 Subject: [PATCH 15/15] Added code to output the value of "usecache" to the output .csv file in examples/EvolveGoals.jl. --- examples/EvolveGoals.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/EvolveGoals.jl b/examples/EvolveGoals.jl index 81b3c61..4b743c3 100644 --- a/examples/EvolveGoals.jl +++ b/examples/EvolveGoals.jl @@ -111,6 +111,7 @@ function evolve_goals( outstream::IOStream, summary::String, print(outstream, "host: ",readall(`hostname`)) println(outstream,"num processes: ",length(procs())) print(outstream,readall(`julia -v`)) + println(outstream,"use cache: ",usecache) println(outstream,"num inputs: ",p.numinputs) println(outstream,"num outputs: ",p.numoutputs) println(outstream,"num per level: ",p.numperlevel)