metaheuristic_algorithms 0.1.3 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3dd2ffc0aa34514ddb6b911b08301698c1651fff
4
- data.tar.gz: 7cb81d28bee88c63d10ed5835b3f762b0a89728b
3
+ metadata.gz: 27858264b3ec8d6e8f908c77b72aaf02bb4fe520
4
+ data.tar.gz: 7f4fd083bb8a261f2ac48f8e50d7df18a714b28b
5
5
  SHA512:
6
- metadata.gz: b2c0db5f019af8720c407ff8ab1d8859041baa8bd9293a822734edc8892d56423dd6204798f565b7031d76fdf5ce882088f92fc7188444742afb1039ae907001
7
- data.tar.gz: 15f10112749131b6e775385228c8985207017ebe13550380c67b06b194940e746566c68fbb14e0a803767ed04c896b39f01e67152008403f19fe62da3d80673e
6
+ metadata.gz: 943a04193e2133c5cdc2aac48d5f1d6dddf5184363f6f38cd62e4d5d88abbf5f042a1935f4c92b4cf02e69823206e3492ed9d4acb31fd67d58bc07658096235b
7
+ data.tar.gz: 3a7ded6b05592213c574a06ed2019c7a5524f39e99723f0f12f27859b4b132088e3455740dbc861f84276e73a93a56fed338f1bcb30efaef4c73ae9a8da8e65f
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.2.2
1
+ 2.2.3
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in metaheuristic_algorithms.gemspec
4
4
  gemspec
5
+
6
+ gem "pry-byebug", group: [:development, :test], platforms: :ruby # In order to exclude jruby
data/README.md CHANGED
@@ -18,6 +18,32 @@ Or install it yourself as:
18
18
 
19
19
  $ gem install metaheuristic_algorithms
20
20
 
21
+ ## Supported Platforms
22
+
23
+ * MRI Ruby 2.2 or above.
24
+
25
+ * JRuby 9.0.0.0 or above. (In an attempt to have better speed, if not fast.)
26
+
27
+ ## Available Algorithms
28
+
29
+ In alphabetical order:
30
+
31
+ * Firefly Algorithm
32
+ MetaheuristicAlgorithms::FireflyAlgorithm
33
+ * Genetic Algorithm
34
+ MetaheuristicAlgorithms::GeneticAlgorithm
35
+ * Harmony Search
36
+ MetaheuristicAlgorithms::HarmonySearch
37
+ * Simplified Particle Swarm Optimization
38
+ MetaheuristicAlgorithms::SimplifiedParticleSwarmOptimization
39
+ * Simulated Annealing
40
+ MetaheuristicAlgorithms::SimulatedAnnealing
41
+
42
+ Algorithms under construction:
43
+
44
+ * Ant Colony Optimization
45
+ * Virtual Bee Algorithm
46
+
21
47
  ## Usage
22
48
 
23
49
  Step 1. Create a Function Wrapper for your objective function by extending MetaheuristicAlgorithms::FunctionWrappers::AbstractWrapper
@@ -26,25 +52,24 @@ Step 1. Create a Function Wrapper for your objective function by extending Metah
26
52
 
27
53
  ```ruby
28
54
  require 'metaheuristic_algorithms'
29
- require 'bigdecimal'
30
55
 
31
56
  class RosenbrookFunctionWrapper < MetaheuristicAlgorithms::FunctionWrappers::AbstractWrapper
32
57
 
33
58
  def maximum_decision_variable_values
34
- [BigDecimal('5'), BigDecimal('5')]
59
+ [5, 5]
35
60
  end
36
61
 
37
62
  def miminum_decision_variable_values
38
- [BigDecimal('-5'), BigDecimal('-5')]
63
+ [-5, -5]
39
64
  end
40
65
 
41
66
  def objective_function_value(decision_variable_values)
42
- (BigDecimal('1') - decision_variable_values[0]).power(2) + BigDecimal('100') * (decision_variable_values[1] - decision_variable_values[0].power(2)).power(2)
67
+ (1 - decision_variable_values[0])**2 + 100 * (decision_variable_values[1] - decision_variable_values[0]**2)**2
43
68
  end
44
69
 
45
70
  # For the algorithm that requires initial estimate that is depending on the particular objective function:
46
71
  def initial_decision_variable_value_estimates
47
- [BigDecimal('2'), BigDecimal('2')]
72
+ [2, 2]
48
73
  end
49
74
 
50
75
  end
@@ -58,25 +83,24 @@ Step 2. Instantiate the created Function Wrapper and pass it as the first argume
58
83
 
59
84
  ```ruby
60
85
  require 'metaheuristic_algorithms'
61
- require 'bigdecimal'
62
86
 
63
87
  rosenbrook_function_wrapper = RosenbrookFunctionWrapper.new
64
88
 
65
89
  harmony_search = MetaheuristicAlgorithms::HarmonySearch.new(rosenbrook_function_wrapper, number_of_variables: 2, objective: :minimization)
66
90
 
67
91
  maximum_attempt = 25000
68
- pitch_adjusting_range = BigDecimal('100')
92
+ pitch_adjusting_range = 100
69
93
  harmony_search_size = 20
70
- harmony_memory_acceping_rate = BigDecimal('0.95')
71
- pitch_adjusting_rate = BigDecimal('0.7')
94
+ harmony_memory_acceping_rate = 0.95
95
+ pitch_adjusting_rate = 0.7
72
96
 
73
97
  result = harmony_search.search(maximum_attempt: maximum_attempt, pitch_adjusting_range: pitch_adjusting_range,
74
98
  harmony_search_size: harmony_search_size, harmony_memory_acceping_rate: harmony_memory_acceping_rate,
75
99
  pitch_adjusting_rate: pitch_adjusting_rate)
76
100
 
77
- puts result[:best_decision_variable_values][0] # x value: Example: BigDecimal('1.0112')
78
- puts result[:best_decision_variable_values][1] # y value: Example: BigDecimal('0.9988')
79
- puts result[:best_objective_function_value] # f(x,y) value: Example: BigDecimal('0.0563')
101
+ puts result[:best_decision_variable_values][0] # x value: Example: 1.0112
102
+ puts result[:best_decision_variable_values][1] # y value: Example: 0.9988
103
+ puts result[:best_objective_function_value] # f(x,y) value: Example: 0.0563
80
104
  ```
81
105
 
82
106
  ## Development
@@ -87,7 +111,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
87
111
 
88
112
  ## Contributing
89
113
 
90
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/metaheuristic_algorithms. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
114
+ Bug reports and pull requests are welcome on GitHub at https://github.com/tadatoshi/metaheuristic_algorithms. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
91
115
 
92
116
 
93
117
  ## License
@@ -3,10 +3,23 @@ module MetaheuristicAlgorithms
3
3
  module BaseAlgorithmModule
4
4
 
5
5
  def get_decision_variable_value_by_randomization(decision_variable_index)
6
+ # @function_wrapper.miminum_decision_variable_values[decision_variable_index]
7
+ # + (@function_wrapper.maximum_decision_variable_values[decision_variable_index] - @function_wrapper.miminum_decision_variable_values[decision_variable_index]) * bigdecimal_rand
6
8
  @function_wrapper.miminum_decision_variable_values[decision_variable_index]
7
- + (@function_wrapper.maximum_decision_variable_values[decision_variable_index] - @function_wrapper.miminum_decision_variable_values[decision_variable_index]) * bigdecimal_rand
9
+ + (@function_wrapper.maximum_decision_variable_values[decision_variable_index] - @function_wrapper.miminum_decision_variable_values[decision_variable_index]) * rand
8
10
  end
9
11
 
12
+ # Based on the code by antonakos on http://stackoverflow.com/questions/5825680/code-to-generate-gaussian-normally-distributed-random-numbers-in-ruby
13
+ # His code is under CC0 1.0 Universal (CC0 1.0)
14
+ def gaussian(mean, stddev)
15
+ theta = 2 * Math::PI * Kernel.rand
16
+ rho = Math.sqrt(-2 * Math.log(1 - Kernel.rand))
17
+ scale = stddev * rho
18
+ x = mean + scale * Math.cos(theta)
19
+ # y = mean + scale * Math.sin(theta)
20
+ return x
21
+ end
22
+
10
23
  end
11
24
 
12
25
  end
@@ -1,13 +1,17 @@
1
+ require 'bigdecimal'
2
+
1
3
  module MetaheuristicAlgorithms
2
4
 
3
5
  module CalculationHelper
4
6
 
5
7
  def degree_to_radian(degree)
6
- degree * BigDecimal(Math::PI.to_s) / BigDecimal('180')
8
+ # degree * BigDecimal(Math::PI.to_s) / BigDecimal('180')
9
+ degree * Math::PI / 180
7
10
  end
8
11
 
9
12
  def radian_to_degree(radian)
10
- radian * BigDecimal('180') / BigDecimal(Math::PI.to_s)
13
+ # radian * BigDecimal('180') / BigDecimal(Math::PI.to_s)
14
+ radian * 180 / Math::PI
11
15
  end
12
16
 
13
17
  def bigdecimal_exp(bigdecimal_value)
@@ -1,5 +1,5 @@
1
- require 'bigdecimal'
2
- require 'bigdecimal/math'
1
+ # require 'bigdecimal'
2
+ # require 'bigdecimal/math'
3
3
 
4
4
  module MetaheuristicAlgorithms
5
5
 
@@ -42,17 +42,19 @@ module MetaheuristicAlgorithms
42
42
  end
43
43
  end
44
44
 
45
- def search(number_of_fireflies: 10, maximun_generation: 10, randomization_parameter_alpha: BigDecimal('0.2'), absorption_coefficient_gamma: BigDecimal('1.0'))
45
+ # def search(number_of_fireflies: 10, maximun_generation: 10, randomization_parameter_alpha: BigDecimal('0.2'), absorption_coefficient_gamma: BigDecimal('1.0'))
46
+ def search(number_of_fireflies: 10, maximun_generation: 10, randomization_parameter_alpha: 0.2, absorption_coefficient_gamma: 1.0)
46
47
 
47
48
  number_of_fireflies = number_of_fireflies.to_i unless number_of_fireflies.kind_of?(Integer)
48
49
  maximun_generation = maximun_generation.to_i unless maximun_generation.kind_of?(Integer)
49
- randomization_parameter_alpha = BigDecimal(randomization_parameter_alpha.to_s) unless randomization_parameter_alpha.kind_of?(BigDecimal)
50
- absorption_coefficient_gamma = BigDecimal(absorption_coefficient_gamma.to_s) unless absorption_coefficient_gamma.kind_of?(BigDecimal)
50
+ # randomization_parameter_alpha = BigDecimal(randomization_parameter_alpha.to_s) unless randomization_parameter_alpha.kind_of?(BigDecimal)
51
+ # absorption_coefficient_gamma = BigDecimal(absorption_coefficient_gamma.to_s) unless absorption_coefficient_gamma.kind_of?(BigDecimal)
52
+ randomization_parameter_alpha = randomization_parameter_alpha.to_f unless randomization_parameter_alpha.kind_of?(Float)
53
+ absorption_coefficient_gamma = absorption_coefficient_gamma.to_f unless absorption_coefficient_gamma.kind_of?(Float)
51
54
 
52
55
  initialize_fireflies(number_of_fireflies)
53
56
 
54
- # 0 to maximun_generation-1
55
- (0...maximun_generation).each do |generation|
57
+ maximun_generation.times do |generation|
56
58
 
57
59
  @fireflies.each { |firefly| firefly.update_light_intensity }
58
60
 
@@ -76,7 +78,8 @@ module MetaheuristicAlgorithms
76
78
  get_decision_variable_value_by_randomization(variable_index)
77
79
  end
78
80
 
79
- firefly = Firefly.new(@function_wrapper, decision_variable_values, BigDecimal('0'))
81
+ # firefly = Firefly.new(@function_wrapper, decision_variable_values, BigDecimal('0'))
82
+ firefly = Firefly.new(@function_wrapper, decision_variable_values, 0)
80
83
  @fireflies << firefly
81
84
  end
82
85
 
@@ -84,7 +87,8 @@ module MetaheuristicAlgorithms
84
87
 
85
88
  def move_fireflies(randomization_parameter_alpha, absorption_coefficient_gamma)
86
89
 
87
- attractiveness_beta_at_distance_0 = BigDecimal('1')
90
+ # attractiveness_beta_at_distance_0 = BigDecimal('1')
91
+ attractiveness_beta_at_distance_0 = 1
88
92
 
89
93
  fireflies_copy = @fireflies.map(&:deep_clone)
90
94
 
@@ -98,12 +102,16 @@ module MetaheuristicAlgorithms
98
102
 
99
103
  distance_of_two_fireflies = distance_of_two_fireflies(firefly_i, firefly_j)
100
104
 
101
- attractiveness_beta = attractiveness_beta_at_distance_0 * BigMath.exp(-absorption_coefficient_gamma * distance_of_two_fireflies.power(2), 10)
105
+ # attractiveness_beta = attractiveness_beta_at_distance_0 * BigMath.exp(-absorption_coefficient_gamma * distance_of_two_fireflies.power(2), 10)
106
+ attractiveness_beta = attractiveness_beta_at_distance_0 * Math.exp(-absorption_coefficient_gamma * distance_of_two_fireflies**2)
102
107
 
103
- (0...@number_of_variables).each do |variable_index|
104
- new_location_coordinate = firefly_i.location_coordinates[variable_index] * (BigDecimal('1') - attractiveness_beta)
108
+ @number_of_variables.times do |variable_index|
109
+ # new_location_coordinate = firefly_i.location_coordinates[variable_index] * (BigDecimal('1') - attractiveness_beta)
110
+ # + firefly_j.location_coordinates[variable_index] * attractiveness_beta
111
+ # + randomization_parameter_alpha * (bigdecimal_rand - BigDecimal('0.5'))
112
+ new_location_coordinate = firefly_i.location_coordinates[variable_index] * (1 - attractiveness_beta)
105
113
  + firefly_j.location_coordinates[variable_index] * attractiveness_beta
106
- + randomization_parameter_alpha * (bigdecimal_rand - BigDecimal('0.5'))
114
+ + randomization_parameter_alpha * (rand - 0.5)
107
115
  new_location_coordinate = constrain_within_range(new_location_coordinate, variable_index)
108
116
 
109
117
  firefly_i.location_coordinates[variable_index] = new_location_coordinate
@@ -129,11 +137,12 @@ module MetaheuristicAlgorithms
129
137
 
130
138
  def distance_of_two_fireflies(firefly_1, firefly_2)
131
139
 
132
- sum_of_squares = (0...@number_of_variables).inject(BigDecimal('0')) do |sum, variable_index|
133
- sum + (firefly_1.location_coordinates[variable_index] - firefly_2.location_coordinates[variable_index]).power(2)
140
+ # sum_of_squares = (0...@number_of_variables).inject(BigDecimal('0')) do |sum, variable_index|
141
+ sum_of_squares = (0...@number_of_variables).inject(0) do |sum, variable_index|
142
+ sum + (firefly_1.location_coordinates[variable_index] - firefly_2.location_coordinates[variable_index])**2
134
143
  end
135
144
 
136
- sum_of_squares.sqrt(10)
145
+ Math.sqrt(sum_of_squares)
137
146
 
138
147
  end
139
148
 
@@ -1,4 +1,4 @@
1
- require 'bigdecimal/math'
1
+ # require 'bigdecimal/math'
2
2
 
3
3
  module MetaheuristicAlgorithms
4
4
 
@@ -8,15 +8,18 @@ module MetaheuristicAlgorithms
8
8
  include MetaheuristicAlgorithms::CalculationHelper
9
9
 
10
10
  def maximum_decision_variable_values
11
- [BigDecimal('10')]
11
+ # [BigDecimal('10')]
12
+ [10]
12
13
  end
13
14
 
14
15
  def miminum_decision_variable_values
15
- [BigDecimal('-10')]
16
+ # [BigDecimal('-10')]
17
+ [-10]
16
18
  end
17
19
 
18
20
  def objective_function_value(decision_variable_values)
19
- -bigdecimal_cos(decision_variable_values[0]) * BigMath.exp((-(decision_variable_values[0] - BigMath.PI(10)).power(2)), 10)
21
+ # -bigdecimal_cos(decision_variable_values[0]) * BigMath.exp((-(decision_variable_values[0] - BigMath.PI(10)).power(2)), 10)
22
+ -Math.cos(decision_variable_values[0]) * Math.exp(-(decision_variable_values[0] - Math::PI)**2)
20
23
  end
21
24
 
22
25
  def initial_decision_variable_value_estimates
@@ -1,4 +1,4 @@
1
- require 'bigdecimal/math'
1
+ # require 'bigdecimal/math'
2
2
 
3
3
  module MetaheuristicAlgorithms
4
4
 
@@ -8,16 +8,20 @@ module MetaheuristicAlgorithms
8
8
  include MetaheuristicAlgorithms::CalculationHelper
9
9
 
10
10
  def maximum_decision_variable_values
11
- [BigDecimal('4'), BigDecimal('4')]
11
+ # [BigDecimal('4'), BigDecimal('4')]
12
+ [4, 4]
12
13
  end
13
14
 
14
15
  def miminum_decision_variable_values
15
- [BigDecimal('0'), BigDecimal('0')]
16
+ # [BigDecimal('0'), BigDecimal('0')]
17
+ [0, 0]
16
18
  end
17
19
 
18
20
  def objective_function_value(decision_variable_values)
19
- -bigdecimal_sin(decision_variable_values[0]) * bigdecimal_sin(decision_variable_values[0].power(2) / BigMath.PI(10)).power(20) -
20
- bigdecimal_sin(decision_variable_values[1]) * bigdecimal_sin(decision_variable_values[1].power(2) / BigMath.PI(10)).power(20)
21
+ # -bigdecimal_sin(decision_variable_values[0]) * bigdecimal_sin(decision_variable_values[0].power(2) / BigMath.PI(10)).power(20) -
22
+ # bigdecimal_sin(decision_variable_values[1]) * bigdecimal_sin(decision_variable_values[1].power(2) / BigMath.PI(10)).power(20)
23
+ -Math.sin(decision_variable_values[0]) * (Math.sin(decision_variable_values[0]**2 / Math::PI))**20 -
24
+ Math.sin(decision_variable_values[1]) * (Math.sin(decision_variable_values[1]**2 / Math::PI))**20
21
25
  end
22
26
 
23
27
  def initial_decision_variable_value_estimates
@@ -1,4 +1,4 @@
1
- require 'bigdecimal/math'
1
+ # require 'bigdecimal/math'
2
2
 
3
3
  module MetaheuristicAlgorithms
4
4
 
@@ -7,15 +7,18 @@ module MetaheuristicAlgorithms
7
7
  class NonsmoothMultipeakFunctionWrapper < AbstractWrapper
8
8
 
9
9
  def maximum_decision_variable_values
10
- [BigDecimal('5'), BigDecimal('5')]
10
+ # [BigDecimal('5'), BigDecimal('5')]
11
+ [5, 5]
11
12
  end
12
13
 
13
14
  def miminum_decision_variable_values
14
- [BigDecimal('-5'), BigDecimal('-5')]
15
+ # [BigDecimal('-5'), BigDecimal('-5')]
16
+ [-5, -5]
15
17
  end
16
18
 
17
19
  def objective_function_value(decision_variable_values)
18
- (decision_variable_values[0].abs + decision_variable_values[1].abs) * BigMath.exp((BigDecimal('-0.0625') * (decision_variable_values[0].power(2) + decision_variable_values[1].power(2))), 10)
20
+ # (decision_variable_values[0].abs + decision_variable_values[1].abs) * BigMath.exp((BigDecimal('-0.0625') * (decision_variable_values[0].power(2) + decision_variable_values[1].power(2))), 10)
21
+ (decision_variable_values[0].abs + decision_variable_values[1].abs) * Math.exp(-0.0625 * (decision_variable_values[0]**2 + decision_variable_values[1]**2))
19
22
  end
20
23
 
21
24
  def initial_decision_variable_value_estimates
@@ -5,19 +5,23 @@ module MetaheuristicAlgorithms
5
5
  class RosenbrookFunctionWrapper < AbstractWrapper
6
6
 
7
7
  def maximum_decision_variable_values
8
- [BigDecimal('5'), BigDecimal('5')]
8
+ # [BigDecimal('5'), BigDecimal('5')]
9
+ [5, 5]
9
10
  end
10
11
 
11
12
  def miminum_decision_variable_values
12
- [BigDecimal('-5'), BigDecimal('-5')]
13
+ # [BigDecimal('-5'), BigDecimal('-5')]
14
+ [-5, -5]
13
15
  end
14
16
 
15
17
  def objective_function_value(decision_variable_values)
16
- (BigDecimal('1') - decision_variable_values[0]).power(2) + BigDecimal('100') * (decision_variable_values[1] - decision_variable_values[0].power(2)).power(2)
18
+ # (BigDecimal('1') - decision_variable_values[0]).power(2) + BigDecimal('100') * (decision_variable_values[1] - decision_variable_values[0].power(2)).power(2)
19
+ (1 - decision_variable_values[0])**2 + 100 * (decision_variable_values[1] - decision_variable_values[0]**2)**2
17
20
  end
18
21
 
19
22
  def initial_decision_variable_value_estimates
20
- [BigDecimal('2'), BigDecimal('2')]
23
+ # [BigDecimal('2'), BigDecimal('2')]
24
+ [2, 2]
21
25
  end
22
26
 
23
27
  end
@@ -19,23 +19,28 @@ module MetaheuristicAlgorithms
19
19
  # @string_length_in_bits = 16
20
20
  end
21
21
 
22
- def search(population_size: 20, maximum_number_of_generations: 100, number_of_mutation_sites: BigDecimal('2'), crossover_probability: BigDecimal('0.95'), mutation_probability: BigDecimal('0.05'))
22
+ # def search(population_size: 20, maximum_number_of_generations: 100, number_of_mutation_sites: BigDecimal('2'), crossover_probability: BigDecimal('0.95'), mutation_probability: BigDecimal('0.05'))
23
+ def search(population_size: 20, maximum_number_of_generations: 100, number_of_mutation_sites: 2, crossover_probability: 0.95, mutation_probability: 0.05)
23
24
 
24
25
  population_size = population_size.to_i unless population_size.kind_of?(Integer)
25
26
  maximum_number_of_generations = maximum_number_of_generations.to_i unless maximum_number_of_generations.kind_of?(Integer)
26
- number_of_mutation_sites = BigDecimal(number_of_mutation_sites.to_s) unless number_of_mutation_sites.kind_of?(BigDecimal)
27
- crossover_probability = BigDecimal(crossover_probability.to_s) unless crossover_probability.kind_of?(BigDecimal)
28
- mutation_probability = BigDecimal(mutation_probability.to_s) unless mutation_probability.kind_of?(BigDecimal)
27
+ # number_of_mutation_sites = BigDecimal(number_of_mutation_sites.to_s) unless number_of_mutation_sites.kind_of?(BigDecimal)
28
+ # crossover_probability = BigDecimal(crossover_probability.to_s) unless crossover_probability.kind_of?(BigDecimal)
29
+ # mutation_probability = BigDecimal(mutation_probability.to_s) unless mutation_probability.kind_of?(BigDecimal)
30
+ number_of_mutation_sites = number_of_mutation_sites.to_i unless number_of_mutation_sites.kind_of?(Integer)
31
+ crossover_probability = crossover_probability.to_f unless crossover_probability.kind_of?(Float)
32
+ mutation_probability = mutation_probability.to_f unless mutation_probability.kind_of?(Float)
29
33
 
30
34
  initialize_population(population_size)
31
35
 
32
- (0...maximum_number_of_generations).each do |generation_index|
36
+ maximum_number_of_generations.times do |generation_index|
33
37
 
34
38
  @population_copy = deep_clone_population
35
39
 
36
- (0...population_size).each do |individual_index|
40
+ population_size.times do |individual_index|
37
41
 
38
- if bigdecimal_rand < crossover_probability
42
+ # if bigdecimal_rand < crossover_probability
43
+ if rand < crossover_probability
39
44
 
40
45
  # Crossover pair:
41
46
  crossover_pair_1_index = generate_random_index(population_size)
@@ -45,7 +50,8 @@ module MetaheuristicAlgorithms
45
50
 
46
51
  end
47
52
 
48
- if bigdecimal_rand < mutation_probability
53
+ # if bigdecimal_rand < mutation_probability
54
+ if rand < mutation_probability
49
55
 
50
56
  mutation_individual_index = generate_random_index(population_size)
51
57
 
@@ -71,8 +77,7 @@ module MetaheuristicAlgorithms
71
77
  @population = []
72
78
  @population_fitness = []
73
79
 
74
- # 0 to population_size-1
75
- (0...population_size).each do |individual_index|
80
+ population_size.times do |individual_index|
76
81
  decision_variable_values = (0...@number_of_variables).map do |variable_index|
77
82
  get_decision_variable_value_by_randomization(variable_index)
78
83
  end
@@ -91,7 +96,7 @@ module MetaheuristicAlgorithms
91
96
  crossover_pair_1_decimal_values = []
92
97
  crossover_pair_2_decimal_values = []
93
98
 
94
- (0...@number_of_variables).each do |variable_index|
99
+ @number_of_variables.times do |variable_index|
95
100
 
96
101
  crossover_pair_1_decimal_value = @population_copy[crossover_pair_1_index][variable_index]
97
102
  crossover_pair_2_decimal_value = @population_copy[crossover_pair_2_index][variable_index]
@@ -143,7 +148,7 @@ module MetaheuristicAlgorithms
143
148
 
144
149
  def binary_32_string_to_decimal(binary_32_string)
145
150
  decimal_float_value = [binary_32_string].pack("B*").unpack('g')[0].round(4)
146
- BigDecimal(decimal_float_value.to_s)
151
+ # BigDecimal(decimal_float_value.to_s)
147
152
  end
148
153
 
149
154
  def mutate(individual_index, number_of_mutation_sites)
@@ -155,7 +160,7 @@ module MetaheuristicAlgorithms
155
160
 
156
161
  mutated_binary_32_string = binary_32_string.clone
157
162
 
158
- (0...number_of_mutation_sites).each do |i|
163
+ number_of_mutation_sites.to_i.times do |i|
159
164
  mutation_site_index = generate_mutation_site_index
160
165
  # Flips 1 to 0 or 0 to 1:
161
166
  mutated_binary_32_string[mutation_site_index] = ((binary_32_string[mutation_site_index].to_i + 1).modulo(2)).to_s
@@ -20,22 +20,23 @@ module MetaheuristicAlgorithms
20
20
  when :minimization
21
21
  :<
22
22
  end
23
-
24
- @decision_variable_range = [@function_wrapper.miminum_decision_variable_values, @function_wrapper.maximum_decision_variable_values]
25
23
  end
26
24
 
27
- def search(maximum_attempt: 2500, pitch_adjusting_range: BigDecimal('100'), harmony_search_size: 20, harmony_memory_acceping_rate: BigDecimal('0.95'), pitch_adjusting_rate: BigDecimal('0.7'))
25
+ # def search(maximum_attempt: 2500, pitch_adjusting_range: BigDecimal('100'), harmony_search_size: 20, harmony_memory_acceping_rate: BigDecimal('0.95'), pitch_adjusting_rate: BigDecimal('0.7'))
26
+ def search(maximum_attempt: 2500, pitch_adjusting_range: 100, harmony_search_size: 20, harmony_memory_acceping_rate: 0.95, pitch_adjusting_rate: 0.7)
28
27
 
29
28
  maximum_attempt = maximum_attempt.to_i unless maximum_attempt.kind_of?(Integer)
30
- pitch_adjusting_range = BigDecimal(pitch_adjusting_range.to_s) unless pitch_adjusting_range.kind_of?(BigDecimal)
29
+ # pitch_adjusting_range = BigDecimal(pitch_adjusting_range.to_s) unless pitch_adjusting_range.kind_of?(BigDecimal)
30
+ pitch_adjusting_range = pitch_adjusting_range.to_f unless pitch_adjusting_range.kind_of?(Float)
31
31
  harmony_search_size = harmony_search_size.to_i unless harmony_search_size.kind_of?(Integer)
32
- harmony_memory_acceping_rate = BigDecimal(harmony_memory_acceping_rate.to_s) unless harmony_memory_acceping_rate.kind_of?(BigDecimal)
33
- pitch_adjusting_rate = BigDecimal(pitch_adjusting_rate.to_s) unless pitch_adjusting_rate.kind_of?(BigDecimal)
32
+ # harmony_memory_acceping_rate = BigDecimal(harmony_memory_acceping_rate.to_s) unless harmony_memory_acceping_rate.kind_of?(BigDecimal)
33
+ # pitch_adjusting_rate = BigDecimal(pitch_adjusting_rate.to_s) unless pitch_adjusting_rate.kind_of?(BigDecimal)
34
+ harmony_memory_acceping_rate = harmony_memory_acceping_rate.to_f unless harmony_memory_acceping_rate.kind_of?(Float)
35
+ pitch_adjusting_rate = pitch_adjusting_rate.to_f unless pitch_adjusting_rate.kind_of?(Float)
34
36
 
35
37
  initialize_harmony_memory(harmony_search_size)
36
38
 
37
- # 0 to maximum_attempt-1
38
- (0...maximum_attempt).each do |count|
39
+ maximum_attempt.times do |count|
39
40
 
40
41
  decision_variable_values = (0...@number_of_variables).map do |variable_index|
41
42
 
@@ -43,12 +44,15 @@ module MetaheuristicAlgorithms
43
44
  decision_variable_value = get_decision_variable_value_by_randomization(variable_index)
44
45
  else
45
46
  # Since the array index starts with 0 unlike MatLab, 1 is not added as in the code example in MatLab:
46
- harmony_memory_random_index = (harmony_search_size * bigdecimal_rand).fix
47
+ # harmony_memory_random_index = (harmony_search_size * bigdecimal_rand).fix
48
+ harmony_memory_random_index = (harmony_search_size * rand).to_i
47
49
  decision_variable_value = @harmony_memory[harmony_memory_random_index][variable_index]
48
50
 
49
- if bigdecimal_rand < pitch_adjusting_rate
51
+ # if bigdecimal_rand < pitch_adjusting_rate
52
+ if rand < pitch_adjusting_rate
50
53
  pitch_adjusting = (@function_wrapper.maximum_decision_variable_values[variable_index] - @function_wrapper.miminum_decision_variable_values[variable_index]) / pitch_adjusting_range
51
- decision_variable_value = decision_variable_value + pitch_adjusting * (bigdecimal_rand - BigDecimal('0.5'))
54
+ # decision_variable_value = decision_variable_value + pitch_adjusting * (bigdecimal_rand - BigDecimal('0.5'))
55
+ decision_variable_value = decision_variable_value + pitch_adjusting * (rand -0.5)
52
56
  end
53
57
  end
54
58
 
@@ -15,20 +15,22 @@ module MetaheuristicAlgorithms
15
15
  end
16
16
  end
17
17
 
18
- def search(number_of_particiles: 20, number_of_iterations: 15, social_coefficient: BigDecimal('0.5'), random_variable_coefficient: BigDecimal('0.2'))
18
+ # def search(number_of_particiles: 20, number_of_iterations: 15, social_coefficient: BigDecimal('0.5'), random_variable_coefficient: BigDecimal('0.2'))
19
+ def search(number_of_particiles: 20, number_of_iterations: 15, social_coefficient: 0.5, random_variable_coefficient: 0.2)
19
20
 
20
21
  number_of_particiles = number_of_particiles.to_i unless number_of_particiles.kind_of?(Integer)
21
22
  number_of_iterations = number_of_iterations.to_i unless number_of_iterations.kind_of?(Integer)
22
- social_coefficient = BigDecimal(social_coefficient.to_s) unless social_coefficient.kind_of?(BigDecimal)
23
- random_variable_coefficient = BigDecimal(random_variable_coefficient.to_s) unless random_variable_coefficient.kind_of?(BigDecimal)
23
+ # social_coefficient = BigDecimal(social_coefficient.to_s) unless social_coefficient.kind_of?(BigDecimal)
24
+ # random_variable_coefficient = BigDecimal(random_variable_coefficient.to_s) unless random_variable_coefficient.kind_of?(BigDecimal)
25
+ social_coefficient = social_coefficient.to_f unless social_coefficient.kind_of?(Float)
26
+ random_variable_coefficient = random_variable_coefficient.to_f unless random_variable_coefficient.kind_of?(Float)
24
27
 
25
28
  initialize_particles(number_of_particiles)
26
29
 
27
30
  global_best_position = nil
28
31
  best_function_value = nil
29
32
 
30
- # 0 to number_of_iterations-1
31
- (0...number_of_iterations).each do |iteration|
33
+ number_of_iterations.times do |iteration|
32
34
 
33
35
  function_values = @particle_locations.map do |particle_location|
34
36
  @function_wrapper.objective_function_value(particle_location)
@@ -50,8 +52,7 @@ module MetaheuristicAlgorithms
50
52
 
51
53
  @particle_locations = []
52
54
 
53
- # 0 to number_of_particiles-1
54
- (0...number_of_particiles).each do |individual_index|
55
+ number_of_particiles.times do |individual_index|
55
56
  decision_variable_values = (0...@number_of_variables).map do |variable_index|
56
57
  get_decision_variable_value_by_randomization(variable_index)
57
58
  end
@@ -68,10 +69,12 @@ module MetaheuristicAlgorithms
68
69
  (0...@number_of_variables).map do |variable_index|
69
70
 
70
71
  # The value out-of-range in order to enter while loop
71
- new_particle_location_coordinate = @function_wrapper.miminum_decision_variable_values[variable_index] - BigDecimal('1')
72
+ # new_particle_location_coordinate = @function_wrapper.miminum_decision_variable_values[variable_index] - BigDecimal('1')
73
+ new_particle_location_coordinate = @function_wrapper.miminum_decision_variable_values[variable_index] - 1
72
74
 
73
75
  while new_particle_location_coordinate < @function_wrapper.miminum_decision_variable_values[variable_index] || new_particle_location_coordinate > @function_wrapper.maximum_decision_variable_values[variable_index]
74
- new_particle_location_coordinate = (BigDecimal('1') - social_coefficient) * particle_location[variable_index] + social_coefficient * global_best_position[variable_index] + random_variable_coefficient * (bigdecimal_rand - BigDecimal('0.5'))
76
+ # new_particle_location_coordinate = (BigDecimal('1') - social_coefficient) * particle_location[variable_index] + social_coefficient * global_best_position[variable_index] + random_variable_coefficient * (bigdecimal_rand - BigDecimal('0.5'))
77
+ new_particle_location_coordinate = (1 - social_coefficient) * particle_location[variable_index] + social_coefficient * global_best_position[variable_index] + random_variable_coefficient * (rand - 0.5)
75
78
  end
76
79
 
77
80
  new_particle_location_coordinate
@@ -1,10 +1,12 @@
1
- require 'bigdecimal/math'
2
- require 'distribution'
1
+ # require 'bigdecimal/math'
2
+ # In order to support JRuby, decided not to use distribution gem:
3
+ # require 'distribution'
3
4
 
4
5
  module MetaheuristicAlgorithms
5
6
 
6
7
  class SimulatedAnnealing
7
8
  include MetaheuristicAlgorithms::Helper
9
+ include MetaheuristicAlgorithms::BaseAlgorithmModule
8
10
 
9
11
  def initialize(function_wrapper, number_of_variables: 1, objective: :maximization)
10
12
  @function_wrapper = function_wrapper
@@ -17,21 +19,32 @@ module MetaheuristicAlgorithms
17
19
  end
18
20
  end
19
21
 
20
- def search(temperature: BigDecimal('100.0'), minimal_temperature: BigDecimal('1'), maximum_number_of_rejections: 2500,
22
+ # def search(temperature: BigDecimal('100.0'), minimal_temperature: BigDecimal('1'), maximum_number_of_rejections: 2500,
23
+ # maximum_number_of_runs: 500, maximum_number_of_acceptances: 15,
24
+ # bolzmann_constant: BigDecimal('1'), cooling_factor: BigDecimal('0.95'), energy_norm: BigDecimal('10'),
25
+ # standard_diviation_for_estimation: BigDecimal('6'), ratio_of_energy_delta_over_evaluation_delta: BigDecimal('10'))
26
+ def search(temperature: 100.0, minimal_temperature: 1, maximum_number_of_rejections: 2500,
21
27
  maximum_number_of_runs: 500, maximum_number_of_acceptances: 15,
22
- bolzmann_constant: BigDecimal('1'), cooling_factor: BigDecimal('0.95'), energy_norm: BigDecimal('10'),
23
- standard_diviation_for_estimation: BigDecimal('6'), ratio_of_energy_delta_over_evaluation_delta: BigDecimal('10'))
28
+ bolzmann_constant: 1, cooling_factor: 0.95, energy_norm: 10,
29
+ standard_diviation_for_estimation: 6, ratio_of_energy_delta_over_evaluation_delta: 10)
24
30
 
25
- temperature = BigDecimal(temperature.to_s) unless temperature.kind_of?(BigDecimal)
26
- minimal_temperature = BigDecimal(minimal_temperature.to_s) unless minimal_temperature.kind_of?(BigDecimal)
31
+ # temperature = BigDecimal(temperature.to_s) unless temperature.kind_of?(BigDecimal)
32
+ # minimal_temperature = BigDecimal(minimal_temperature.to_s) unless minimal_temperature.kind_of?(BigDecimal)
33
+ temperature = temperature.to_f unless temperature.kind_of?(Float)
34
+ minimal_temperature = minimal_temperature.to_f unless minimal_temperature.kind_of?(Float)
27
35
  maximum_number_of_rejections = maximum_number_of_rejections.to_i unless maximum_number_of_rejections.kind_of?(Integer)
28
36
  maximum_number_of_runs = maximum_number_of_runs.to_i unless maximum_number_of_runs.kind_of?(Integer)
29
37
  maximum_number_of_acceptances = maximum_number_of_acceptances.to_i unless maximum_number_of_acceptances.kind_of?(Integer)
30
- bolzmann_constant = BigDecimal(bolzmann_constant.to_s) unless bolzmann_constant.kind_of?(BigDecimal)
31
- cooling_factor = BigDecimal(cooling_factor.to_s) unless cooling_factor.kind_of?(BigDecimal)
32
- energy_norm = BigDecimal(energy_norm.to_s) unless energy_norm.kind_of?(BigDecimal)
33
- standard_diviation_for_estimation = BigDecimal(standard_diviation_for_estimation.to_s) unless standard_diviation_for_estimation.kind_of?(BigDecimal)
34
- ratio_of_energy_delta_over_evaluation_delta = BigDecimal(ratio_of_energy_delta_over_evaluation_delta.to_s) unless ratio_of_energy_delta_over_evaluation_delta.kind_of?(BigDecimal)
38
+ # bolzmann_constant = BigDecimal(bolzmann_constant.to_s) unless bolzmann_constant.kind_of?(BigDecimal)
39
+ # cooling_factor = BigDecimal(cooling_factor.to_s) unless cooling_factor.kind_of?(BigDecimal)
40
+ # energy_norm = BigDecimal(energy_norm.to_s) unless energy_norm.kind_of?(BigDecimal)
41
+ # standard_diviation_for_estimation = BigDecimal(standard_diviation_for_estimation.to_s) unless standard_diviation_for_estimation.kind_of?(BigDecimal)
42
+ # ratio_of_energy_delta_over_evaluation_delta = BigDecimal(ratio_of_energy_delta_over_evaluation_delta.to_s) unless ratio_of_energy_delta_over_evaluation_delta.kind_of?(BigDecimal)
43
+ bolzmann_constant = bolzmann_constant.to_f unless bolzmann_constant.kind_of?(Float)
44
+ cooling_factor = cooling_factor.to_f unless cooling_factor.kind_of?(Float)
45
+ energy_norm = energy_norm.to_f unless energy_norm.kind_of?(Float)
46
+ standard_diviation_for_estimation = standard_diviation_for_estimation.to_f unless standard_diviation_for_estimation.kind_of?(Float)
47
+ ratio_of_energy_delta_over_evaluation_delta = ratio_of_energy_delta_over_evaluation_delta.to_f unless ratio_of_energy_delta_over_evaluation_delta.kind_of?(Float)
35
48
 
36
49
  number_of_runs = 0
37
50
  number_of_rejections = 0
@@ -66,13 +79,15 @@ module MetaheuristicAlgorithms
66
79
  # Accept if improved:
67
80
  # When objective = :maximization, "if evaluation_delta > 0 && evaluation_delta > energy_norm"
68
81
  # When objective = :minimization, "if evaluation_delta < 0 && -evaluation_delta > energy_norm"
69
- if evaluation_delta.send(@objective_comparison_operator, BigDecimal('0')) && evaluation_delta.abs > energy_norm
82
+ # if evaluation_delta.send(@objective_comparison_operator, BigDecimal('0')) && evaluation_delta.abs > energy_norm
83
+ if evaluation_delta.send(@objective_comparison_operator, 0) && evaluation_delta.abs > energy_norm
70
84
  best_solution = new_estimates
71
85
  best_evaluation = new_evaluation
72
86
  number_of_acceptances = number_of_acceptances + 1
73
87
  number_of_rejections = 0
74
88
  # Accept with a small probability if not improved
75
- elsif acceptance_probability(evaluation_delta, temperature, bolzmann_constant) > bigdecimal_rand
89
+ # elsif acceptance_probability(evaluation_delta, temperature, bolzmann_constant) > bigdecimal_rand
90
+ elsif acceptance_probability(evaluation_delta, temperature, bolzmann_constant) > rand
76
91
  best_solution = new_estimates
77
92
  best_evaluation = new_evaluation
78
93
  number_of_acceptances = number_of_acceptances + 1
@@ -92,13 +107,17 @@ module MetaheuristicAlgorithms
92
107
  (0...@number_of_variables).map do |variable_index|
93
108
 
94
109
  # The value out-of-range in order to enter while loop
95
- new_estimate = @function_wrapper.miminum_decision_variable_values[variable_index] - BigDecimal('1')
110
+ # new_estimate = @function_wrapper.miminum_decision_variable_values[variable_index] - BigDecimal('1')
111
+ new_estimate = @function_wrapper.miminum_decision_variable_values[variable_index] - 1
96
112
 
97
113
  while new_estimate < @function_wrapper.miminum_decision_variable_values[variable_index] || new_estimate > @function_wrapper.maximum_decision_variable_values[variable_index]
98
114
 
99
115
  # MatLab example code uses newGuess = initialGuess + rand(1,2) * randn;
100
116
  # But in our case, the value range is different.
101
- new_estimate = BigDecimal(Distribution::Normal.rng(previous_estimates[variable_index], standard_diviation_for_estimation).call.to_s)
117
+ # In order to support JRuby, decided not to use Distribution::Normal.rng:
118
+ # new_estimate = BigDecimal(Distribution::Normal.rng(previous_estimates[variable_index], standard_diviation_for_estimation).call.to_s)
119
+ # new_estimate = BigDecimal(gaussian(previous_estimates[variable_index], standard_diviation_for_estimation).to_s)
120
+ new_estimate = gaussian(previous_estimates[variable_index], standard_diviation_for_estimation)
102
121
 
103
122
  end
104
123
 
@@ -1,3 +1,3 @@
1
1
  module MetaheuristicAlgorithms
2
- VERSION = "0.1.3"
3
- end
2
+ VERSION = "0.2.1"
3
+ end
@@ -1,4 +1,4 @@
1
- require 'bigdecimal'
1
+ # require 'bigdecimal'
2
2
 
3
3
  module MetaheuristicAlgorithms
4
4
 
@@ -1,9 +1,9 @@
1
1
  require 'metaheuristic_algorithms/version'
2
- require 'bigdecimal'
2
+ # require 'bigdecimal'
3
3
  require 'metaheuristic_algorithms/calculation_helper'
4
4
  require 'metaheuristic_algorithms/function_wrappers'
5
- require 'metaheuristic_algorithms/base_algorithm_module'
6
5
  require 'metaheuristic_algorithms/helper'
6
+ require 'metaheuristic_algorithms/base_algorithm_module'
7
7
  require 'metaheuristic_algorithms/harmony_search'
8
8
  require 'metaheuristic_algorithms/firefly_algorithm'
9
9
  require 'metaheuristic_algorithms/genetic_algorithm'
@@ -32,5 +32,6 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency "bundler", "~> 1.10"
33
33
  spec.add_development_dependency "rake", "~> 10.0"
34
34
  spec.add_development_dependency "rspec"
35
- spec.add_development_dependency "pry-byebug"
35
+ # Requires native C extension. Doesn't work with JRuby. Hence moved to Gemfile:
36
+ #spec.add_development_dependency "pry-byebug"
36
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metaheuristic_algorithms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tadatoshi Takahashi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-08-09 00:00:00.000000000 Z
11
+ date: 2015-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: distribution
@@ -66,20 +66,6 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: pry-byebug
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
69
  description: Various metaheuristic algorithms implemented in Ruby.
84
70
  email:
85
71
  - tadatoshi@gmail.com
@@ -139,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
125
  version: '0'
140
126
  requirements: []
141
127
  rubyforge_project:
142
- rubygems_version: 2.4.7
128
+ rubygems_version: 2.4.5.1
143
129
  signing_key:
144
130
  specification_version: 4
145
131
  summary: Various metaheuristic algorithms implemented in Ruby.