Class: Archipelago

Inherits:
Object
  • Object
show all
Defined in:
lib/gimuby/genetic/archipelago/archipelago.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeArchipelago

Returns a new instance of Archipelago.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 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

Instance Attribute Details

#connect_strategyObject

Returns the value of attribute connect_strategy.



28
29
30
# File 'lib/gimuby/genetic/archipelago/archipelago.rb', line 28

def connect_strategy
  @connect_strategy
end

#connectionsObject

Returns the value of attribute connections.



27
28
29
# File 'lib/gimuby/genetic/archipelago/archipelago.rb', line 27

def connections
  @connections
end

#migration_rateObject

Returns the value of attribute migration_rate.



29
30
31
# File 'lib/gimuby/genetic/archipelago/archipelago.rb', line 29

def migration_rate
  @migration_rate
end

#migration_symmetricObject

Returns the value of attribute migration_symmetric.



31
32
33
# File 'lib/gimuby/genetic/archipelago/archipelago.rb', line 31

def migration_symmetric
  @migration_symmetric
end

#migration_typeObject

Returns the value of attribute migration_type.



30
31
32
# File 'lib/gimuby/genetic/archipelago/archipelago.rb', line 30

def migration_type
  @migration_type
end

#populationsObject

Returns the value of attribute populations.



26
27
28
# File 'lib/gimuby/genetic/archipelago/archipelago.rb', line 26

def populations
  @populations
end

Instance Method Details

#add_edge(population_index1, population_index2) ⇒ Object

Create a connection from a population to another



114
115
116
117
118
119
120
121
122
123
124
# 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) ⇒ Object



51
52
53
54
# 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) ⇒ Object

Connect two population from their index in the list



104
105
106
107
108
109
110
111
# 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_allObject

Connect the different populations of the archipelago



57
58
59
# File 'lib/gimuby/genetic/archipelago/archipelago.rb', line 57

def connect_all
  @connect_strategy.connect(self)
end

#connect_path(path, closed_path = FALSE) ⇒ Object



190
191
192
193
194
195
196
197
# 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_stepObject

Trigger a generation step on each subpopulation



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 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_degreeObject



162
163
164
165
166
# 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_fitnessObject



168
169
170
171
172
173
174
175
# 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_fitnessObject



177
178
179
180
# 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_solutionObject



182
183
184
185
186
187
# 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_coefficientObject



81
82
83
84
85
86
# 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_countObject



73
74
75
# File 'lib/gimuby/genetic/archipelago/archipelago.rb', line 73

def get_connected_classes_count
  ConnectedMeasure.new.compute(self)
end

#get_degree(node) ⇒ Object



200
201
202
203
204
205
# 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_diameterObject



77
78
79
# File 'lib/gimuby/genetic/archipelago/archipelago.rb', line 77

def get_diameter
  DiameterMeasure.new.compute(self)
end

#get_edgesObject



143
144
145
146
147
148
149
150
151
# 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_countObject



153
154
155
156
157
158
159
160
# 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) ⇒ Object



95
96
97
98
99
100
# 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_nodesObject



89
90
91
92
# File 'lib/gimuby/genetic/archipelago/archipelago.rb', line 89

def get_nodes
  nodes = *(0..@populations.length - 1)
  nodes
end

#get_population_sizeObject



61
62
63
64
65
66
67
# 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_sizeObject



69
70
71
# File 'lib/gimuby/genetic/archipelago/archipelago.rb', line 69

def get_size
  @populations.size
end

#has_edge(population_index1, population_index2) ⇒ Object



136
137
138
139
140
141
# 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) ⇒ Object

Remove a connection



127
128
129
130
131
132
133
134
# 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