class Archipelago
Attributes
connect_strategy[RW]
connections[RW]
migration_rate[RW]
migration_symmetric[RW]
migration_type[RW]
populations[RW]
Public Class Methods
new()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 9 def initialize @populations = [] # each population is an island @connections = {} # an hash of array containing indexes pointing population, # (sparse adjacency matrix) @connect_strategy = RandomConnectStrategy.new @migration_rate = (1.0/100.0) @migration_type = :random # use also :synchronized or :fixed_time @migration_symmetric = FALSE @generation_step_count = 0 #internal usage @populations_to_migrate_indexes = [] reset_topological_metrics trigger(:on_archipelago_init) end
Public Instance Methods
add_edge(population_index1, population_index2)
click to toggle source
Create a connection from a population to another
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 114 def add_edge(population_index1, population_index2) if population_index1 == population_index2 return end unless @connections.has_key? population_index1 @connections[population_index1] = [] end unless @connections[population_index1].include? population_index2 @connections[population_index1].push(population_index2) end end
add_population(population)
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 51 def add_population population @populations.push population reset_topological_metrics end
connect(population_index1, population_index2)
click to toggle source
Connect two population from their index in the list @internal
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 104 def connect(population_index1, population_index2) if population_index1 == population_index2 return end add_edge(population_index1, population_index2) add_edge(population_index2, population_index1) reset_topological_metrics end
connect_all()
click to toggle source
Connect the different populations of the archipelago
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 57 def connect_all @connect_strategy.connect(self) end
connect_path(path, closed_path = FALSE)
click to toggle source
@internal
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 190 def connect_path(path, closed_path = FALSE) previous = nil previous = path[-1] if closed_path path.each do |current| connect(previous, current) unless previous.nil? previous = current end end
generation_step()
click to toggle source
Trigger a generation step on each subpopulation
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 34 def generation_step reset_populations_migration_state @generation_step_count += 1 archipelago_level_migration = FALSE if @migration_type == :synchronized archipelago_level_migration = rand() < @migration_rate end if @migration_type == :fixed_time archipelago_level_migration = should_fixed_time_migrate end @populations.each do |population| population.generation_step migrate(population, archipelago_level_migration) end trigger(:on_archipelago_generation_step) end
get_average_degree()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 162 def get_average_degree nodes_count = @populations.length.to_f edges_count = get_edges_count.to_f edges_count / nodes_count end
get_average_fitness()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 168 def get_average_fitness sum = 0 @populations.each do |population| sum += population.get_average_fitness end # Beware of that division by 0 sum / @populations.length end
get_best_fitness()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 177 def get_best_fitness best_solution = get_best_solution best_solution.get_fitness end
get_best_solution()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 182 def get_best_solution best_population = @populations.min_by do |population| population.get_best_fitness end best_population.get_best_solution end
get_clustering_coefficient()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 81 def get_clustering_coefficient unless @clustering_coefficient.nil? return @clustering_coefficient end @clustering_coefficient = ClusteringCoefficientMeasure.new.compute(self) end
get_connected_classes_count()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 73 def get_connected_classes_count ConnectedMeasure.new.compute(self) end
get_degree(node)
click to toggle source
@internal
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 200 def get_degree(node) unless @connections.has_key?(node) return 0 end @connections[node].length end
get_diameter()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 77 def get_diameter DiameterMeasure.new.compute(self) end
get_edges()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 143 def get_edges edges = [] @connections.each do |node, facing_nodes| facing_nodes.each do |facing_node| edges.push([node, facing_node]) end end edges end
get_edges_count()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 153 def get_edges_count edges_count = 0 @connections.values.each do |target_connections| target_connections_length = target_connections.length edges_count += target_connections_length end edges_count end
get_neighbors(node)
click to toggle source
@internal
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 95 def get_neighbors(node) unless @connections.has_key?(node) return [] end @connections[node].clone end
get_nodes()
click to toggle source
@internal
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 89 def get_nodes nodes = *(0..@populations.length - 1) nodes end
get_population_size()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 61 def get_population_size size = 0 @populations.each do |population| size += population.get_population_size end size end
get_size()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 69 def get_size @populations.size end
has_edge(population_index1, population_index2)
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 136 def has_edge(population_index1, population_index2) unless @connections.has_key? population_index1 return FALSE end @connections[population_index1].include? population_index2 end
remove_edge(population_index1, population_index2)
click to toggle source
Remove a connection
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 127 def remove_edge(population_index1, population_index2) if @connections.has_key? population_index1 @connections[population_index1].delete(population_index2) end if @connections.has_key? population_index2 @connections[population_index2].delete(population_index1) end end
Protected Instance Methods
get_event_manager()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 302 def get_event_manager $dependencies.event_manager end
get_migration_period()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 290 def get_migration_period if @migration_rate == 0 return FALSE end 1.0 / @migration_rate end
is_population_migrated(population)
click to toggle source
@return [Boolean]
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 276 def is_population_migrated(population) population_index = @populations.index(population) # If population is migrated it's not anymore in the list @populations_to_migrate.index(population_index).nil? end
mark_population_as_migrated(population)
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 270 def mark_population_as_migrated(population) population_index = @populations.index(population) @populations_to_migrate_indexes.delete(population_index) end
migrate(population, forced = FALSE)
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 209 def migrate(population, forced = FALSE) if (not forced) && (@migration_type != :random) return FALSE end unless forced r = rand() unless (r <= @migration_rate) return FALSE end end if is_population_migrated(population) # the population has already been migrated, we avoid to do it twice return FALSE end population_index = @populations.index(population) unless @connections.has_key?(population_index) return FALSE end connected_populations_indexes = @connections[population_index] if connected_populations_indexes.length == 0 return FALSE end random_index = rand(connected_populations_indexes.length + 1) - 1 # +1 -1 to avoid strange suspected behavior on rand(1) target_population_index = connected_populations_indexes[random_index] if target_population_index.nil? # Why handling that case ? No idea, # a bug occurred randomly return FALSE end target_population = @populations[target_population_index] migrate_from_to(population, target_population) TRUE end
migrate_from_to(population, target_population)
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 242 def migrate_from_to(population, target_population) selected_solutions_1 = population.pick to_migrate_count = selected_solutions_1.length selected_solutions_2 = nil if @migration_symmetric selected_solutions_2 = target_population.pick to_migrate_count += selected_solutions_2.length end trigger(:on_archipelago_migration_begin, {:migrated_solutions_count => to_migrate_count}) target_population.replace(selected_solutions_1) mark_population_as_migrated(population) unless selected_solutions_2.nil? population.replace(selected_solutions_2) mark_population_as_migrated(target_population) end trigger(:on_archipelago_migration_end, {:migrated_solutions_count => to_migrate_count}) end
reset_populations_migration_state()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 266 def reset_populations_migration_state @populations_to_migrate = get_nodes end
reset_topological_metrics()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 262 def reset_topological_metrics @clustering_coefficient = nil end
should_fixed_time_migrate()
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 282 def should_fixed_time_migrate migration_period = get_migration_period if migration_period.nil? return FALSE end (@generation_step_count % get_migration_period).round == 0 end
trigger(event_type, event_data = {})
click to toggle source
# File lib/gimuby/genetic/archipelago/archipelago.rb, line 297 def trigger(event_type, event_data = {}) event_data[:archipelago] = self get_event_manager.trigger_event(event_type, event_data) end