answer-factory 0.0.14 → 0.0.15

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.
Files changed (58) hide show
  1. data/VERSION +1 -1
  2. data/answer-factory.gemspec +22 -53
  3. data/lib/answer-factory.rb +8 -16
  4. data/lib/answers/answer.rb +17 -8
  5. data/lib/answers/batch.rb +9 -3
  6. data/lib/factories/workstation.rb +1 -2
  7. data/lib/machines/any_one.rb +38 -0
  8. data/lib/machines/build_random.rb +21 -0
  9. data/lib/machines/evaluate_simple_score.rb +32 -0
  10. data/lib/machines/infrastructure.rb +14 -0
  11. data/lib/machines/mutate_footnotes.rb +61 -0
  12. data/lib/machines/select_nondominated.rb +32 -0
  13. data/spec/answer_spec.rb +27 -3
  14. data/spec/batch_spec.rb +14 -2
  15. data/spec/factories/workstation_spec.rb +11 -7
  16. data/spec/integration_specs/couch_db_integration.rb +60 -0
  17. data/spec/machines/any_one_spec.rb +100 -0
  18. data/spec/machines/build_random_spec.rb +69 -0
  19. data/spec/machines/evaluate_simple_score_spec.rb +113 -0
  20. data/spec/machines/infrastructure_spec.rb +10 -0
  21. data/spec/machines/mutate_footnotes_spec.rb +125 -0
  22. data/spec/machines/select_nondominated_spec.rb +84 -0
  23. data/tasks/setup_factory.thor +1 -1
  24. data/templates/answer_factory_activate_template.erb +87 -14
  25. metadata +23 -54
  26. data/lib/operators/all_duplicated_genomes_sampler.rb +0 -16
  27. data/lib/operators/any_one_sampler.rb +0 -7
  28. data/lib/operators/dominated_quantile_selector.rb +0 -16
  29. data/lib/operators/infrastructure.rb +0 -74
  30. data/lib/operators/most_dominated_subset_sampler.rb +0 -13
  31. data/lib/operators/nondominated_subset_selector.rb +0 -17
  32. data/lib/operators/point_crossover_operator.rb +0 -24
  33. data/lib/operators/point_delete_operator.rb +0 -19
  34. data/lib/operators/point_mutation_operator.rb +0 -22
  35. data/lib/operators/program_point_count_evaluator.rb +0 -18
  36. data/lib/operators/random_guess_operator.rb +0 -30
  37. data/lib/operators/resample_and_clone_operator.rb +0 -28
  38. data/lib/operators/resample_values_operator.rb +0 -40
  39. data/lib/operators/test_case_evaluator.rb +0 -82
  40. data/lib/operators/uniform_backbone_crossover_operator.rb +0 -53
  41. data/spec/integration_specs/activate_integration.rb +0 -0
  42. data/spec/integration_specs/build_integration.rb +0 -0
  43. data/spec/integration_specs/thor_integration.rb +0 -33
  44. data/spec/operators/any_one_sampler_spec.rb +0 -39
  45. data/spec/operators/dominated_quantile_spec.rb +0 -111
  46. data/spec/operators/duplicate_genomes_spec.rb +0 -35
  47. data/spec/operators/evaluators/program_point_evaluator_spec.rb +0 -48
  48. data/spec/operators/evaluators/test_case_evaluator_spec.rb +0 -129
  49. data/spec/operators/infrastructure_spec.rb +0 -45
  50. data/spec/operators/most_dominated_subset_spec.rb +0 -47
  51. data/spec/operators/nondominated_subset_spec.rb +0 -103
  52. data/spec/operators/pointCrossover_spec.rb +0 -65
  53. data/spec/operators/pointDeletion_spec.rb +0 -62
  54. data/spec/operators/pointMutation_spec.rb +0 -77
  55. data/spec/operators/random_guess_spec.rb +0 -82
  56. data/spec/operators/resample_and_clone_spec.rb +0 -60
  57. data/spec/operators/resample_values_spec.rb +0 -135
  58. data/spec/operators/uniformBackboneCrossover_spec.rb +0 -67
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.14
1
+ 0.0.15
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{answer-factory}
8
- s.version = "0.0.14"
8
+ s.version = "0.0.15"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Bill Tozier", "Trek Glowacki", "Jesse Sielaff"]
12
- s.date = %q{2010-05-07}
12
+ s.date = %q{2010-05-10}
13
13
  s.default_executable = %q{answer-factory}
14
14
  s.description = %q{The pragmaticgp gem provides a simple framework for building, running and managing genetic programming experiments which automatically discover algorithms and equations to solve user-defined problems.}
15
15
  s.email = %q{bill@vagueinnovation.com}
@@ -31,44 +31,24 @@ Gem::Specification.new do |s|
31
31
  "lib/answers/batch.rb",
32
32
  "lib/factories/factory.rb",
33
33
  "lib/factories/workstation.rb",
34
- "lib/operators/all_duplicated_genomes_sampler.rb",
35
- "lib/operators/any_one_sampler.rb",
36
- "lib/operators/dominated_quantile_selector.rb",
37
- "lib/operators/infrastructure.rb",
38
- "lib/operators/most_dominated_subset_sampler.rb",
39
- "lib/operators/nondominated_subset_selector.rb",
40
- "lib/operators/point_crossover_operator.rb",
41
- "lib/operators/point_delete_operator.rb",
42
- "lib/operators/point_mutation_operator.rb",
43
- "lib/operators/program_point_count_evaluator.rb",
44
- "lib/operators/random_guess_operator.rb",
45
- "lib/operators/resample_and_clone_operator.rb",
46
- "lib/operators/resample_values_operator.rb",
47
- "lib/operators/test_case_evaluator.rb",
48
- "lib/operators/uniform_backbone_crossover_operator.rb",
34
+ "lib/machines/any_one.rb",
35
+ "lib/machines/build_random.rb",
36
+ "lib/machines/evaluate_simple_score.rb",
37
+ "lib/machines/infrastructure.rb",
38
+ "lib/machines/mutate_footnotes.rb",
39
+ "lib/machines/select_nondominated.rb",
49
40
  "readme.md",
50
41
  "spec/answer_spec.rb",
51
42
  "spec/batch_spec.rb",
52
43
  "spec/factories/factory_spec.rb",
53
44
  "spec/factories/workstation_spec.rb",
54
- "spec/integration_specs/activate_integration.rb",
55
- "spec/integration_specs/build_integration.rb",
56
- "spec/integration_specs/thor_integration.rb",
57
- "spec/operators/any_one_sampler_spec.rb",
58
- "spec/operators/dominated_quantile_spec.rb",
59
- "spec/operators/duplicate_genomes_spec.rb",
60
- "spec/operators/evaluators/program_point_evaluator_spec.rb",
61
- "spec/operators/evaluators/test_case_evaluator_spec.rb",
62
- "spec/operators/infrastructure_spec.rb",
63
- "spec/operators/most_dominated_subset_spec.rb",
64
- "spec/operators/nondominated_subset_spec.rb",
65
- "spec/operators/pointCrossover_spec.rb",
66
- "spec/operators/pointDeletion_spec.rb",
67
- "spec/operators/pointMutation_spec.rb",
68
- "spec/operators/random_guess_spec.rb",
69
- "spec/operators/resample_and_clone_spec.rb",
70
- "spec/operators/resample_values_spec.rb",
71
- "spec/operators/uniformBackboneCrossover_spec.rb",
45
+ "spec/integration_specs/couch_db_integration.rb",
46
+ "spec/machines/any_one_spec.rb",
47
+ "spec/machines/build_random_spec.rb",
48
+ "spec/machines/evaluate_simple_score_spec.rb",
49
+ "spec/machines/infrastructure_spec.rb",
50
+ "spec/machines/mutate_footnotes_spec.rb",
51
+ "spec/machines/select_nondominated_spec.rb",
72
52
  "spec/spec_helper.rb",
73
53
  "tasks/setup_factory.thor",
74
54
  "templates/answer_factory_activate_template.erb",
@@ -85,24 +65,13 @@ Gem::Specification.new do |s|
85
65
  "spec/batch_spec.rb",
86
66
  "spec/factories/factory_spec.rb",
87
67
  "spec/factories/workstation_spec.rb",
88
- "spec/integration_specs/activate_integration.rb",
89
- "spec/integration_specs/build_integration.rb",
90
- "spec/integration_specs/thor_integration.rb",
91
- "spec/operators/any_one_sampler_spec.rb",
92
- "spec/operators/dominated_quantile_spec.rb",
93
- "spec/operators/duplicate_genomes_spec.rb",
94
- "spec/operators/evaluators/program_point_evaluator_spec.rb",
95
- "spec/operators/evaluators/test_case_evaluator_spec.rb",
96
- "spec/operators/infrastructure_spec.rb",
97
- "spec/operators/most_dominated_subset_spec.rb",
98
- "spec/operators/nondominated_subset_spec.rb",
99
- "spec/operators/pointCrossover_spec.rb",
100
- "spec/operators/pointDeletion_spec.rb",
101
- "spec/operators/pointMutation_spec.rb",
102
- "spec/operators/random_guess_spec.rb",
103
- "spec/operators/resample_and_clone_spec.rb",
104
- "spec/operators/resample_values_spec.rb",
105
- "spec/operators/uniformBackboneCrossover_spec.rb",
68
+ "spec/integration_specs/couch_db_integration.rb",
69
+ "spec/machines/any_one_spec.rb",
70
+ "spec/machines/build_random_spec.rb",
71
+ "spec/machines/evaluate_simple_score_spec.rb",
72
+ "spec/machines/infrastructure_spec.rb",
73
+ "spec/machines/mutate_footnotes_spec.rb",
74
+ "spec/machines/select_nondominated_spec.rb",
106
75
  "spec/spec_helper.rb"
107
76
  ]
108
77
 
@@ -9,22 +9,14 @@ require 'couchrest'
9
9
  require 'answers/answer'
10
10
  require 'answers/batch'
11
11
 
12
- require 'operators/infrastructure'
13
-
14
- require 'operators/all_duplicated_genomes_sampler'
15
- require 'operators/any_one_sampler'
16
- require 'operators/dominated_quantile_selector'
17
- require 'operators/most_dominated_subset_sampler'
18
- require 'operators/nondominated_subset_selector'
19
- require 'operators/point_crossover_operator'
20
- require 'operators/point_delete_operator'
21
- require 'operators/point_mutation_operator'
22
- require 'operators/program_point_count_evaluator'
23
- require 'operators/random_guess_operator'
24
- require 'operators/resample_and_clone_operator'
25
- require 'operators/resample_values_operator'
26
- require 'operators/test_case_evaluator'
27
- require 'operators/uniform_backbone_crossover_operator'
12
+ require 'machines/infrastructure'
13
+ require 'machines/any_one'
14
+ require 'machines/build_random'
15
+ require 'machines/evaluate_simple_score'
16
+ require 'machines/select_nondominated'
17
+ require 'machines/mutate_footnotes'
18
+
19
+
28
20
 
29
21
  require 'factories/factory'
30
22
  require 'factories/workstation'
@@ -4,11 +4,12 @@ module AnswerFactory
4
4
  class Answer
5
5
  attr_accessor :scores, :tags
6
6
  attr_reader :draft_blueprint, :program, :timestamp, :ancestors
7
- attr_reader :initialization_options, :progress, :couch_id
7
+ attr_reader :initialization_options, :progress
8
+ attr_accessor :couch_id, :couch_rev
8
9
 
9
10
 
10
11
  def initialize(blueprint, options = {})
11
- raise ArgumentError unless
12
+ raise ArgumentError, "Answer cannot be initialized with a #{blueprint.class}" unless
12
13
  blueprint.kind_of?(String) || blueprint.kind_of?(NudgeProgram)
13
14
  build_from_blueprint!(blueprint)
14
15
 
@@ -18,6 +19,7 @@ module AnswerFactory
18
19
  end
19
20
  @timestamp = Time.now
20
21
  @couch_id = options[:couch_id] || ""
22
+ @couch_rev = options[:couch_rev] || ""
21
23
  @progress = options[:progress] || 0
22
24
  @ancestors = options[:ancestors] || []
23
25
  @tags = Set.new(options[:tags]) || Set.new
@@ -123,11 +125,16 @@ module AnswerFactory
123
125
 
124
126
 
125
127
  def data
126
- {'blueprint' => self.blueprint,
127
- 'tags' => self.tags,
128
+ basics = Hash.new
129
+ basics["_id"] = self.couch_id unless self.couch_id.empty?
130
+ basics["_rev"] = self.couch_rev unless self.couch_rev.empty?
131
+
132
+ basics.merge!({'blueprint' => self.blueprint,
133
+ 'tags' => self.tags.to_a,
128
134
  'scores' => self.scores,
129
135
  'progress' => self.progress,
130
- 'timestamp' => self.timestamp}
136
+ 'timestamp' => self.timestamp})
137
+ return basics
131
138
  end
132
139
 
133
140
 
@@ -135,11 +142,13 @@ module AnswerFactory
135
142
  value_hash = hash["value"]
136
143
  tag_set = Set.new(value_hash["tags"].collect {|t| t.to_sym})
137
144
  symbolized_scores = value_hash["scores"].inject({}) {|memo,(k,v)| memo[k.to_sym] = v; memo }
138
-
145
+
139
146
  Answer.new(value_hash["blueprint"],
140
- couch_id:value_hash["_id"],
147
+ couch_id:value_hash['id'],
148
+ couch_rev:value_hash['rev'],
141
149
  tags:tag_set,
142
150
  scores:symbolized_scores,
143
- progress:value_hash["progress"])
151
+ progress:value_hash["progress"],
152
+ timestamp:value_hash["timestamp"])
144
153
  end
145
154
  end
data/lib/answers/batch.rb CHANGED
@@ -15,13 +15,15 @@ module AnswerFactory
15
15
 
16
16
 
17
17
  def <<(obj)
18
- raise ArgumentError unless obj.kind_of?(Answer)
18
+ raise ArgumentError, "Batch.<< cannot append class #{obj.class}" unless
19
+ obj.kind_of?(Answer)
19
20
  super
20
21
  end
21
22
 
22
23
 
23
24
  def initialize(*args)
24
- raise ArgumentError unless args.inject(true) {|anded, a| anded & a.kind_of?(Answer)}
25
+ raise ArgumentError, "Batches can only contain Answers" unless
26
+ args.inject(true) {|anded, a| anded & a.kind_of?(Answer)}
25
27
  super
26
28
  end
27
29
 
@@ -30,7 +32,11 @@ module AnswerFactory
30
32
  raise ArgumentError, "#{couchdb_uri} is not a String" unless couchdb_uri.kind_of?(String)
31
33
 
32
34
  db = CouchRest.database!(couchdb_uri)
33
- db.bulk_save(self.data)
35
+ response = db.bulk_save(self.data)
36
+ response.each_index do |idx|
37
+ self[idx].couch_id = response[idx]["id"]
38
+ self[idx].couch_rev = response[idx]["rev"]
39
+ end
34
40
  end
35
41
 
36
42
 
@@ -35,7 +35,6 @@ module AnswerFactory
35
35
 
36
36
  def gather_mine
37
37
  gathered = Batch.load_from_couch(couchdb_uri, "#{name}/current")
38
- puts "gathered: #{gathered.class}"
39
38
  @answers = gathered
40
39
  end
41
40
 
@@ -48,7 +47,7 @@ module AnswerFactory
48
47
 
49
48
  def process_with(operator)
50
49
  raise ArgumentError, "Workstation#process_with cannot process with a #{operator.class}" unless
51
- operator.kind_of?(SearchOperator)
50
+ operator.kind_of?(Machines::Machine)
52
51
  operator.generate(@answers)
53
52
  end
54
53
 
@@ -0,0 +1,38 @@
1
+ module AnswerFactory
2
+ module Machines
3
+
4
+
5
+
6
+
7
+ class SampleAnyOne < Machine
8
+
9
+ def screen(batch)
10
+ raise ArgumentError, "SampleAnyOne#screen: argument is not a Batch" unless
11
+ batch.kind_of?(Batch)
12
+ one = batch.sample
13
+ return one.nil? ? Batch.new : Batch.[](one)
14
+ end
15
+
16
+ alias :generate :screen
17
+ end
18
+
19
+
20
+
21
+
22
+ class RemoveAnyOne < Machine
23
+
24
+ def screen(batch)
25
+ raise ArgumentError, "RemoveAnyOne#screen: argument is not a Batch" unless
26
+ batch.kind_of?(Batch)
27
+ working_copy = batch.dup
28
+ where = rand(working_copy.length)
29
+ working_copy.delete_at(where)
30
+ return working_copy
31
+ end
32
+
33
+ alias :generate :screen
34
+ end
35
+
36
+
37
+ end
38
+ end
@@ -0,0 +1,21 @@
1
+ module AnswerFactory
2
+ module Machines
3
+
4
+
5
+
6
+
7
+ class BuildRandom < Machine
8
+
9
+
10
+ def build(batch = nil, overridden_options = {})
11
+ all_options = @options.merge(overridden_options)
12
+ how_many = all_options[:how_many] || 1
13
+ result = Batch.new
14
+ how_many.times {result << Answer.new(NudgeProgram.random(all_options))}
15
+ return result
16
+ end
17
+
18
+ alias generate build
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,32 @@
1
+ module AnswerFactory
2
+ module Machines
3
+
4
+
5
+
6
+
7
+ class EvaluateSimpleScore < Machine
8
+
9
+ def score(batch, overridden_options = {}, &score_block)
10
+ all_options = @options.merge(overridden_options)
11
+ name = all_options[:name]
12
+ scorer = score_block || all_options[:scorer]
13
+
14
+ raise ArgumentError, "EvaluateSimpleScore#score cannot process a #{batch.class}" unless
15
+ batch.kind_of?(Batch)
16
+ raise ArgumentError, "EvaluateSimpleScore: Undefined #name attribute" if
17
+ name.nil?
18
+ raise ArgumentError, "EvaluateSimpleScore: No scoring block available" if
19
+ scorer.nil?
20
+
21
+ batch.each do |answer|
22
+ all_options[:static_score?] ?
23
+ (answer.scores[name] ||= scorer.call(answer)) :
24
+ (answer.scores[name] = scorer.call(answer))
25
+ end
26
+ return batch
27
+ end
28
+
29
+ alias :generate :score
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,14 @@
1
+ module AnswerFactory
2
+ module Machines
3
+
4
+ class Machine
5
+
6
+ attr_reader :options
7
+
8
+ def initialize(options = {})
9
+ @options = options
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,61 @@
1
+ #encoding: utf-8
2
+ module AnswerFactory
3
+ module Machines
4
+
5
+
6
+
7
+
8
+ class MutateFootnotesUniform < Machine
9
+
10
+ def build(batch, overridden_options={})
11
+ raise ArgumentError, "MutateFootnotesUniform#build cannot process a #{batch.class}" unless
12
+ batch.kind_of?(Batch)
13
+
14
+ all_options = @options.merge(overridden_options)
15
+
16
+ fraction = all_options[:proportion_changed] || 0.5
17
+ fraction = 0.0 if fraction < 0.0
18
+ fraction = 1.0 if fraction > 1.0
19
+
20
+ replicates = all_options[:replicates] || 1
21
+
22
+ result = Batch.new
23
+
24
+ batch.each do |orig|
25
+
26
+ codeblock = orig.program.code_section.strip
27
+ fn = orig.program.footnote_section.split(/^(?=«)/)
28
+ fn_count = fn.length
29
+
30
+ replicates.times do
31
+ changes = (fraction*fn_count).ceil
32
+ which_fns_change = (0...fn_count).to_a.sample(changes)
33
+ new_blueprint = "#{codeblock} \n"
34
+ (0...fn_count).each do |f|
35
+ new_fn = which_fns_change.include?(f) ? mutated_footnote_value(fn[f],all_options) : fn[f]
36
+ new_blueprint << "\n#{new_fn.strip}"
37
+ end
38
+ result << Answer.new(new_blueprint, progress:(orig.progress+1))
39
+ end
40
+ end
41
+
42
+ return result
43
+ end
44
+
45
+
46
+ def mutated_footnote_value(footnote_string, options = {})
47
+ type = /^«([\p{Alpha}][_\p{Alnum}]*)(?=»)/.match(footnote_string)[1]
48
+ nudgified = "#{type}_type".camelize
49
+ Nudge.const_defined?(nudgified) ?
50
+ "«#{type}» #{nudgified.constantize.any_value(options)}" :
51
+ footnote_string
52
+ end
53
+
54
+
55
+
56
+ alias :generate :build
57
+
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,32 @@
1
+ module AnswerFactory
2
+ module Machines
3
+
4
+
5
+
6
+
7
+ class SelectNondominated < Machine
8
+
9
+ def screen(batch, overriden_options={})
10
+ raise ArgumentError, "SelectNondominated#screen cannot process class #{batch.class}" unless
11
+ batch.kind_of?(Batch)
12
+ all_options = @options.merge(overriden_options)
13
+
14
+ criteria = all_options[:comparison_criteria]
15
+ result = Batch.new
16
+
17
+ batch.each do |a|
18
+ if criteria.nil?
19
+ winner = batch.inject(true) {|anded, b| anded && (!a.dominated_by?(b))}
20
+ else
21
+ winner = batch.inject(true) {|anded, b| anded && (!a.dominated_by?(b, criteria))}
22
+ end
23
+ result << a if winner
24
+ end
25
+
26
+ return result
27
+ end
28
+
29
+ alias :generate :screen
30
+ end
31
+ end
32
+ end