feldtruby 0.4.5 → 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|