class Factory
Attributes
connected_archipelago[RW]
optimal_archipelago[RW]
optimal_population[RW]
populations_number[RW]
solutions_number[RW]
Public Class Methods
new()
click to toggle source
# File lib/gimuby/factory.rb, line 27 def initialize @optimal_population = FALSE @optimal_archipelago = FALSE # use for test purpose to avoid provided archipelago to be connected @connected_archipelago = TRUE # those values are set by the user, let them nil and we won't use them @solutions_number = nil @populations_number = nil # if we have to generate values we store them here @_solutions_number = nil @_populations_number = nil end
Protected Class Methods
random_entry(*args)
click to toggle source
# File lib/gimuby/factory.rb, line 276 def self.random_entry *args array = args.flatten if array.respond_to? :sample array.sample else array.choice end end
Public Instance Methods
get_archipelago(&solution_generator)
click to toggle source
# File lib/gimuby/factory.rb, line 61 def get_archipelago(&solution_generator) if @optimal_archipelago return get_optimal_archipelago(&solution_generator) end get_random_archipelago(&solution_generator) end
get_optimal_archipelago(&solution_generator)
click to toggle source
# File lib/gimuby/factory.rb, line 88 def get_optimal_archipelago(&solution_generator) is_optimal = FALSE begin candidate_archipelago = get_random_archipelago(&solution_generator) is_optimal = TRUE if (candidate_archipelago.get_population_size <= 500) or (candidate_archipelago.get_population_size >= 1100) is_optimal = FALSE end if candidate_archipelago.migration_rate <= 0.25 is_optimal = FALSE end if (candidate_archipelago.populations.length < 10) or (candidate_archipelago.populations.length > 29) is_optimal = FALSE end if candidate_archipelago.get_diameter >= 100 is_optimal = FALSE end end until is_optimal candidate_archipelago end
get_optimal_population(optimizer, &solution_generator)
click to toggle source
# File lib/gimuby/factory.rb, line 68 def get_optimal_population(optimizer, &solution_generator) candidate_population = get_random_population(optimizer, &solution_generator) begin candidate_population = get_random_population(optimizer, &solution_generator) if candidate_population.solutions.length >= 1000 next end if candidate_population.solutions[0].mutation_strategy.mutation_rate >= 0.1 next end if candidate_population.replace_strategy.replace_proportion <= 0.4 next end if candidate_population.pick_strategy.pick_proportion >= 0.4 next end end while FALSE candidate_population end
get_population(&solution_generator)
click to toggle source
# File lib/gimuby/factory.rb, line 57 def get_population(&solution_generator) _get_population(:population, &solution_generator) end
get_random_archipelago(&solution_generator)
click to toggle source
# File lib/gimuby/factory.rb, line 131 def get_random_archipelago(&solution_generator) archipelago = Archipelago.new archipelago.connect_strategy = get_random_connect_strategy # between 0.01% and ~35% archipelago.migration_rate = (rand() * 35.0 / 100.0) + 0.0001 archipelago.migration_symmetric = random_entry(true, false) archipelago.migration_type = random_entry(:random, :synchronized, :fixed_time) get_populations_number.times do |_| archipelago.add_population(_get_population(:archipelago, &solution_generator)) end if @connected_archipelago archipelago.connect_all end archipelago end
get_random_population(optimizer, &solution_generator)
click to toggle source
# File lib/gimuby/factory.rb, line 111 def get_random_population(optimizer, &solution_generator) population = Population.new population.pick_strategy = get_random_pick_strategy population.replace_strategy = get_random_replace_strategy populations_number = get_populations_number unless optimizer == :archipelago populations_number = 1 end solutions_number = get_solutions_number(populations_number) number_solutions_per_population = solutions_number / populations_number mutation_rate = rand * 0.7 number_solutions_per_population.times do solution = solution_generator.call solution.mutation_strategy.mutation_rate = mutation_rate population.add_solution(solution) end population end
reset_state()
click to toggle source
# File lib/gimuby/factory.rb, line 51 def reset_state @connected_archipelago = TRUE @_populations_number = nil @_solutions_number = nil end
Protected Instance Methods
_get_population(optimizer, &solution_generator)
click to toggle source
# File lib/gimuby/factory.rb, line 149 def _get_population(optimizer, &solution_generator) if @optimal_population return get_optimal_population(optimizer, &solution_generator) end get_random_population(optimizer, &solution_generator) end
get_populations_number()
click to toggle source
# File lib/gimuby/factory.rb, line 189 def get_populations_number unless @_populations_number.nil? return @_populations_number end unless @populations_number.nil? @_populations_number = @populations_number return @_populations_number end populations_number_range = *(2..100) if @optimal_archipelago populations_number_range = *(10..29) end @_populations_number = random_entry(populations_number_range) @_populations_number end
get_random_connect_strategy()
click to toggle source
# File lib/gimuby/factory.rb, line 246 def get_random_connect_strategy r = rand(10) if r == 0 return CircleConnectStrategy.new end if r == 1 return FullyConnectedConnectStrategy.new end r = rand(4) max_degree = [22, get_populations_number - 1].min # even number means easier by two divisions average_degree = (rand((max_degree - 1)/ 2) + 1) * 2 # avoid a bug on an edge case when max_degree = 2 average_degree = [average_degree, max_degree].min case r when 0 strategy = RandomConnectStrategy.new when 1 strategy = ConstantDegreeConnectStrategy.new when 2 strategy = BarabasiAlbertConnectStrategy.new when 3 strategy = WattsStrogatzConnectStrategy.new else raise 'random value (r) has an unexpected value' end strategy.average_degree = average_degree strategy end
get_random_pick_strategy()
click to toggle source
# File lib/gimuby/factory.rb, line 208 def get_random_pick_strategy max = 10 r = rand(max) if r == 0 return BestsPickStrategy.new elsif r == 1 return TournamentPickStrategy.new end r = rand(9) + 1 strategy = RandomWheelPickStrategy.new reason = 1.0 / 10.0 * r strategy.random_wheel_probability_reason = reason # pick proportion min = 0.1 max = 0.9 spread = max - min strategy.pick_proportion = (rand() * spread) + min strategy end
get_random_replace_strategy()
click to toggle source
# File lib/gimuby/factory.rb, line 230 def get_random_replace_strategy if rand() < 0.2 strategy = UniformReplaceStrategy.new else strategy = ReplaceWorstReplaceStrategy.new end # replace proportion min = 0.05 max = 1.0 spread = max - min replace_proportion = (rand() * spread) + min strategy.replace_proportion = replace_proportion strategy end
get_solutions_number(populations_number = 1)
click to toggle source
# File lib/gimuby/factory.rb, line 156 def get_solutions_number(populations_number = 1) unless @_solutions_number.nil? return @_solutions_number end unless @solutions_number.nil? return @solutions_number end max_population_size = 5000 min_population_size = 12 * populations_number if @optimal_population max_population_size = 1000 end if @optimal_archipelago min_population_size = 500 max_population_size = [max_population_size, 1100].min end solutions_number_range = *(min_population_size..max_population_size) picked_solutions_number = 0 solutions_per_population = 0 min_solutions_per_population = min_population_size / populations_number begin picked_solutions_number = random_entry(solutions_number_range) picked_solutions_number /= populations_number picked_solutions_number *= populations_number solutions_per_population = picked_solutions_number / populations_number end while solutions_per_population < min_solutions_per_population @_solutions_number = picked_solutions_number @_solutions_number end
Private Instance Methods
random_entry(*args)
click to toggle source
# File lib/gimuby/factory.rb, line 287 def random_entry *args self.class.random_entry(*args) end