answer-factory 0.0.14 → 0.0.15

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