feldtruby 0.4.5 → 0.4.6
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 +4 -4
- data/lib/feldtruby/optimize/differential_evolution.rb +17 -1
- data/lib/feldtruby/optimize/objective.rb +22 -2
- data/lib/feldtruby/optimize/optimizer.rb +1 -1
- data/lib/feldtruby/version.rb +1 -1
- data/test/test_optimize_differential_evolution.rb +22 -0
- data/test/test_optimize_objective.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc84378ec9d25a827e522fd84024d0dec4c3658e
|
4
|
+
data.tar.gz: 34f48433331c60b650fb2ea7022b4a4f22cb1d64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a44e07d27e5a69fac7b5f044091be9f0f0700174a657625bbeef428156a0046939ff2bb24fb75e36bdda67fb93c603e0014bd0c473f3b37cee03ec7b249f5dc9
|
7
|
+
data.tar.gz: 0a51a26c2502ce997ee1a00fd9362096efeb8e5d0beb7e9f2f7518e00dda2fbcc670e6284d4eac3c1e62ee7be29c01cc2e72cc68e82214e61421794f48f34ed3
|
@@ -188,11 +188,27 @@ class DEOptimizer_Best_1_Bin < DEOptimizerBase
|
|
188
188
|
include DE_MutationStrategy_Best_1
|
189
189
|
end
|
190
190
|
|
191
|
+
# The DE/best/1/* mutation strategy.
|
192
|
+
module DE_MutationStrategy_Best_2
|
193
|
+
# We need four parents for two donor vectors. And then the target, so 1+4 in total.
|
194
|
+
def num_parents_to_sample; 5; end
|
195
|
+
|
196
|
+
def mutate(targetIndex, donorParentsIndices)
|
197
|
+
p1, p2, p3, p4 = get_candidates_with_indices(donorParentsIndices)
|
198
|
+
f = scale_factor(targetIndex)
|
199
|
+
candidate_from_array(best) + (f * (p1 - p2)) + (f * (p3 - p4))
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
class DEOptimizer_Best_2_Bin < DEOptimizer_Best_1_Bin
|
204
|
+
include DE_MutationStrategy_Best_2
|
205
|
+
end
|
206
|
+
|
191
207
|
# DE/rand/1/bin is the default DE optimizer since it does not converge too
|
192
208
|
# quickly but is generally good. For many problems the DEOptimizer_Best_1_Bin
|
193
209
|
# gives better results faster though.
|
194
210
|
DEOptimizer = DEOptimizer_Rand_1_Bin
|
195
|
-
#DEOptimizer =
|
211
|
+
#DEOptimizer = DEOptimizer_Best_2_Bin
|
196
212
|
|
197
213
|
# Optimize the _numVariables_ between the _min_ and _max_ values given _costFunction_.
|
198
214
|
# Default is to minimize.
|
@@ -214,7 +214,7 @@ class Objective
|
|
214
214
|
private
|
215
215
|
|
216
216
|
def update_quality_value_of(candidate, subQualities, weights)
|
217
|
-
qv =
|
217
|
+
qv = @aggregator.make_quality_value subQualities, candidate, self
|
218
218
|
update_quality_value_in_object candidate, qv
|
219
219
|
end
|
220
220
|
|
@@ -328,6 +328,10 @@ end
|
|
328
328
|
class Objective::QualityAggregator
|
329
329
|
attr_reader :objective
|
330
330
|
|
331
|
+
def make_quality_value(subQvs, candidate, objective)
|
332
|
+
QualityValue.new subQvs, candidate, objective
|
333
|
+
end
|
334
|
+
|
331
335
|
# Set the objective to use.
|
332
336
|
def objective=(objective)
|
333
337
|
# Calculate the signs to be used in inverting the max methods later.
|
@@ -366,6 +370,10 @@ end
|
|
366
370
|
# their peers; the aggregate fitness value is fully determined by the individual
|
367
371
|
# and the global min and max values for each objective.
|
368
372
|
class Objective::MeanWeigthedGlobalRatios < Objective::WeightedSumAggregator
|
373
|
+
def make_quality_value(subQvs, candidate, objective)
|
374
|
+
PercentageQualityValue.new subQvs, candidate, objective
|
375
|
+
end
|
376
|
+
|
369
377
|
def ratio(index, value, min, max)
|
370
378
|
return 1000.0 if value == nil # We heavily penalize if one sub-quality could not be calculated. Max is otherwise 1.0.
|
371
379
|
if objective.is_min_goal?(index)
|
@@ -458,14 +466,26 @@ class QualityValue
|
|
458
466
|
-(@sub_qualities[index])
|
459
467
|
end
|
460
468
|
|
469
|
+
def value_to_s
|
470
|
+
"#{value.to_significant_digits(4)}"
|
471
|
+
end
|
472
|
+
|
461
473
|
def to_s
|
462
474
|
subqs = sub_qualities.map {|f| f ? f.to_significant_digits(3) : nil}
|
463
475
|
# Note! We ask for the value first which guarantees that we then have a version number.
|
464
|
-
qstr =
|
476
|
+
qstr = value_to_s
|
465
477
|
"#{qstr} (SubQs = #{subqs.inspect}, ver. #{@version})"
|
466
478
|
end
|
467
479
|
end
|
468
480
|
|
481
|
+
class PercentageQualityValue < QualityValue
|
482
|
+
def value_to_s
|
483
|
+
return "N/A" if @sub_qualities.any? {|sq| sq.nil?}
|
484
|
+
"%s%%" % (value * 100.0).to_significant_digits(6).to_s
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
|
469
489
|
# Short hand for when the objective function is given as a block that should be minimized.
|
470
490
|
class ObjectiveMinimizeBlock < Objective
|
471
491
|
def initialize(&objFunc)
|
@@ -209,7 +209,7 @@ end
|
|
209
209
|
DefaultOptimizationOptions = {
|
210
210
|
:terminationCriterionClass => FeldtRuby::Optimize::MaxStepsTerminationCriterion,
|
211
211
|
:verbose => true,
|
212
|
-
:populationSize =>
|
212
|
+
:populationSize => 100,
|
213
213
|
:samplerClass => FeldtRuby::Optimize::RadiusLimitedPopulationSampler,
|
214
214
|
:samplerRadius => 8 # Max distance between individuals selected in same tournament.
|
215
215
|
}
|
data/lib/feldtruby/version.rb
CHANGED
@@ -63,4 +63,26 @@ describe "DE/best/1/bin" do
|
|
63
63
|
de2.best.sum.must_be :<=, 0.40
|
64
64
|
de2.num_optimization_steps.must_equal 1234
|
65
65
|
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "DE/best/2/bin" do
|
69
|
+
it "works for rms of small vector" do
|
70
|
+
s2 = SearchSpace.new_symmetric(2, 1)
|
71
|
+
o1 = MinimizeRMS.new
|
72
|
+
de1 = DEOptimizer_Best_2_Bin.new(o1, s2, {:verbose => false, :maxNumSteps => 1000})
|
73
|
+
de1.optimize()
|
74
|
+
# Very unlikely we get a number over 0.30 (2 elements) after 1000 steps...
|
75
|
+
de1.best.sum.must_be :<=, 0.30
|
76
|
+
de1.num_optimization_steps.must_equal 1000
|
77
|
+
end
|
78
|
+
|
79
|
+
it "works for rms and sum of small vector and with more steps" do
|
80
|
+
s4 = SearchSpace.new_symmetric(4, 1)
|
81
|
+
o2 = MinimizeRMSAndSum.new
|
82
|
+
de2 = DEOptimizer_Best_2_Bin.new(o2, s4, {:verbose => false, :maxNumSteps => 1234})
|
83
|
+
de2.optimize()
|
84
|
+
# Very unlikely we get a number over 0.40 (4 elements)...
|
85
|
+
de2.best.sum.must_be :<=, 0.40
|
86
|
+
de2.num_optimization_steps.must_equal 1234
|
87
|
+
end
|
66
88
|
end
|
@@ -492,11 +492,11 @@ describe "Can handle objectives that return nil" do
|
|
492
492
|
q1 = o.quality_of([1])
|
493
493
|
q1.sub_qualities.must_equal [1]
|
494
494
|
q1.value.must_equal 0.0 # Perfect score
|
495
|
-
q1.to_s.must_equal "0.0 (SubQs = [1.0], ver. 2)"
|
495
|
+
q1.to_s.must_equal "0.0% (SubQs = [1.0], ver. 2)"
|
496
496
|
|
497
497
|
q2 = o.quality_of([])
|
498
498
|
q2.sub_qualities.must_equal [nil]
|
499
499
|
q2.value.must_equal 1000.0 # Max penalty
|
500
|
-
q2.to_s.must_equal "
|
500
|
+
q2.to_s.must_equal "N/A (SubQs = [nil], ver. 2)"
|
501
501
|
end
|
502
502
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: feldtruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Feldt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-04-
|
11
|
+
date: 2013-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rinruby
|