victory 0.3.1 → 0.4.0

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
  SHA256:
3
- metadata.gz: 9d60d4df31c72fa61641ad7e3c97bbdac72caed1b96bef00f249cf2597be6729
4
- data.tar.gz: 474648ec1216b1106c3afabd005c642d690a7020f3bd7c664b463affa3780ddd
3
+ metadata.gz: e1ddbe3510c3b4bddd014951aa6aebaac3a702c39b752751270e212583b1abf9
4
+ data.tar.gz: b0e3f83beeb1bf0373fbdc1fbfdf3ba76ab1bda526a2cd1537a890c0145765dc
5
5
  SHA512:
6
- metadata.gz: 51f99234f08eef7dc4d96d59db36d0ba70c8efe0b1b9046644197c4beb7cd84ec177a8cd9f224006c4cba4321ff5f807f33f3c8261c9988e927d0fd7bcea520d
7
- data.tar.gz: 7f394a441ec4242808fbb38f130aac07e1238bcca08a1aaaf7a9e50f8948c73f0e6b13f7b47c86c9826c543f6944a9587d961ad2f701ed5418789941bb285de0
6
+ metadata.gz: 8aa93ef475b81c961405ebff72d5dca34ebb464425fd5cf842b5b29b2fbef7017032bdc8c92f696b409d9733e690250ec071c7099d1c30df3212b5700e5bc03d
7
+ data.tar.gz: 425a03ea2c788e42fdfab0ade46c285635b0072c1cb6d73833e40684e1833f7c2979c46257ffb8729fcd56a031213890022f8a249d03391e13107b90e2817b0f
data/.gitignore CHANGED
@@ -101,3 +101,4 @@ fabric.properties
101
101
 
102
102
  Gemfile.lock
103
103
  **/*.gem
104
+ *.dylib
@@ -76,7 +76,7 @@ static VALUE rb_bitset_initialize(VALUE self, VALUE ary) {
76
76
  return self;
77
77
  }
78
78
 
79
- static VALUE rb_bitset_size(VALUE self, VALUE len) {
79
+ static VALUE rb_bitset_size(VALUE self) {
80
80
  Bitset * bs = get_bitset(self);
81
81
  return INT2NUM(bs->len);
82
82
  }
@@ -141,6 +141,36 @@ static VALUE rb_bitset_set(int argc, VALUE * argv, VALUE self) {
141
141
  return Qtrue;
142
142
  }
143
143
 
144
+ static VALUE rb_bitset_flip(int argc, VALUE * argv, VALUE self) {
145
+ int i;
146
+ Bitset * bs = get_bitset(self);
147
+
148
+ if (argc == 1 && rb_obj_is_kind_of(argv[0], rb_const_get(rb_cObject, rb_intern("Array")))) {
149
+ for(i = 0; i < RARRAY_LEN(argv[0]); i++) {
150
+ VALUE index = RARRAY_PTR(argv[0])[i];
151
+ int idx = NUM2INT(index);
152
+ validate_index(bs, idx);
153
+ if (_get_bit(bs, idx) == 0) {
154
+ _set_bit(bs, idx);
155
+ } else {
156
+ _clear_bit(bs, idx);
157
+ }
158
+ }
159
+ } else {
160
+ for(i = 0; i < argc; i++) {
161
+ VALUE index = argv[i];
162
+ int idx = NUM2INT(index);
163
+ validate_index(bs, idx);
164
+ if (_get_bit(bs, idx) == 0) {
165
+ _set_bit(bs, idx);
166
+ } else {
167
+ _clear_bit(bs, idx);
168
+ }
169
+ }
170
+ }
171
+ return Qtrue;
172
+ }
173
+
144
174
  static VALUE rb_bitset_clear(int argc, VALUE * argv, VALUE self) {
145
175
  int i;
146
176
  Bitset * bs = get_bitset(self);
@@ -604,9 +634,11 @@ void Init_CBitset() {
604
634
  rb_define_method(cBitset, "initialize", rb_bitset_initialize, 1);
605
635
  rb_define_method(cBitset, "reset!", rb_bitset_reset, 0);
606
636
  rb_define_method(cBitset, "size", rb_bitset_size, 0);
637
+ rb_define_alias(cBitset, "length", "size");
607
638
  rb_define_method(cBitset, "[]", rb_bitset_aref, 1);
608
639
  rb_define_method(cBitset, "[]=", rb_bitset_aset, 2);
609
640
  rb_define_method(cBitset, "set", rb_bitset_set, -1);
641
+ rb_define_method(cBitset, "flip", rb_bitset_flip, -1);
610
642
  rb_define_method(cBitset, "clear", rb_bitset_clear, -1);
611
643
  rb_define_method(cBitset, "set?", rb_bitset_set_p, -1);
612
644
  rb_define_method(cBitset, "clear?", rb_bitset_clear_p, -1);
@@ -634,6 +666,7 @@ void Init_CBitset() {
634
666
  rb_define_method(cBitset, "hamming", rb_bitset_hamming, 1);
635
667
  rb_define_method(cBitset, "each", rb_bitset_each, 0);
636
668
  rb_define_method(cBitset, "to_s", rb_bitset_to_s, 0);
669
+ rb_define_alias(cBitset, "inspect", "to_s");
637
670
  rb_define_singleton_method(cBitset, "from_s", rb_bitset_from_s, 1);
638
671
  rb_define_method(cBitset, "marshal_dump", rb_bitset_marshall_dump, 0);
639
672
  rb_define_method(cBitset, "marshal_load", rb_bitset_marshall_load, 1);
@@ -0,0 +1,71 @@
1
+ module Algorithms::GeneticAlgorithm
2
+ module Solution
3
+ abstract_method :mutate, :crossover, :score
4
+ @data = nil
5
+ attr_reader :data
6
+
7
+ def valid?; true; end
8
+
9
+ def create_new_solution(data)
10
+ new_solution = self.clone
11
+ new_solution.instance_variable_set(:@data, data)
12
+ new_solution
13
+ end
14
+ end
15
+
16
+ # population = list of solutions
17
+ def self.init(population)
18
+ Engine.new(population)
19
+ end
20
+
21
+ class Engine
22
+ attr_reader :best_solution
23
+
24
+ def initialize(population)
25
+ @population = population
26
+ @best_solution = population.max_by(&:score)
27
+ end
28
+
29
+ def run(iterations, min_size: 100, generate_retry: 10)
30
+ @population = generate_until_minimum(@population, min_size)
31
+ iterations.times do
32
+ @population = @population.map do |solution|
33
+ generate_new_solution(solution, @population, generate_retry)
34
+ end
35
+ @best_solution = (@population + [@best_solution]).max_by(&:score)
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def generate_until_minimum(population, min_size)
42
+ while population.size <= min_size
43
+ new_solutions = []
44
+ population.each_with_index do |solution, idx|
45
+ if idx % 2 == 0
46
+ new_solution = solution.mutate
47
+ new_solutions << new_solution if new_solution.valid?
48
+ else
49
+ other_solution = population.reject.with_index { |_, i| i == idx }.sample
50
+ new_solution = solution.crossover(other_solution)
51
+ new_solutions << new_solution if new_solution.valid?
52
+ end
53
+ end
54
+ population += new_solutions
55
+ end
56
+ population
57
+ end
58
+
59
+ def generate_new_solution(solution, population, generate_retry)
60
+ generate_retry.times do
61
+ new_solution = if rand < 0.5
62
+ solution.mutate
63
+ else
64
+ solution.crossover(population.sample)
65
+ end
66
+ return new_solution if new_solution.valid?
67
+ end
68
+ solution
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,31 @@
1
+ class Algorithms::GeneticAlgorithm::ArraySolution
2
+ include Algorithms::GeneticAlgorithm::Solution
3
+
4
+ def initialize(array, possible_elements: [], mutate_change_rate: 0.5)
5
+ @data, @possible_elements, @mutate_change_rate = array, possible_elements, mutate_change_rate
6
+ end
7
+
8
+ def mutate
9
+ new_data = @data.map do |val|
10
+ if rand < @mutate_change_rate
11
+ (@possible_elements || @data).sample
12
+ else
13
+ val
14
+ end
15
+ end
16
+ create_new_solution(new_data)
17
+ end
18
+
19
+ def crossover(other_solution)
20
+ other_data = other_solution.data
21
+ indices = rand(@data.size / 10).times.map { rand(@data.size) }.sort.<<(@data.size).each
22
+ current_data = @data
23
+ new_data = @data.map.with_index do |_element, idx|
24
+ if idx == indices.peek
25
+ current_data = current_data == @data ? other_data : @data
26
+ end
27
+ current_data[idx]
28
+ end
29
+ create_new_solution(new_data)
30
+ end
31
+ end
@@ -0,0 +1,28 @@
1
+ class Algorithms::GeneticAlgorithm::BitsetSolution
2
+ include Algorithms::GeneticAlgorithm::Solution
3
+
4
+ def initialize(bitset, mutate_change_rate: 0.5)
5
+ @data, @mutate_change_rate = bitset, mutate_change_rate
6
+ end
7
+
8
+ def mutate
9
+ new_data = @data.dup
10
+ indices_to_change = []
11
+ (0...@data.size).each do |idx|
12
+ if rand < @mutate_change_rate
13
+ indices_to_change << idx
14
+ end
15
+ end
16
+ new_data.flip(indices_to_change)
17
+ create_new_solution(new_data)
18
+ end
19
+
20
+ def crossover(other_solution)
21
+ new_data = if rand < 0.5
22
+ @data ^ other_solution.data
23
+ else
24
+ @data - other_solution.data
25
+ end
26
+ create_new_solution(new_data)
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ class Algorithms::GeneticAlgorithm::CombinationSolution
2
+ include Algorithms::GeneticAlgorithm::Solution
3
+
4
+ def initialize(possible_elements, size, data: possible_elements.sample(size))
5
+ @data, @possible_elements, @size = Set.new(data), possible_elements, size
6
+ end
7
+
8
+ def mutate
9
+ create_new_solution(Set.new(@possible_elements.sample(@size)))
10
+ end
11
+
12
+ def crossover(other_solution)
13
+ size = @data.size
14
+ common = @data & other_solution.data
15
+ sym_diff = @data ^ other_solution.data
16
+ sampled_sym_diff = Set.new(sym_diff.to_a.sample(size - common.size))
17
+ new_data = common.union(sampled_sym_diff)
18
+ create_new_solution(new_data)
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ class Algorithms::GeneticAlgorithm::PermutationSolution
2
+ include Algorithms::GeneticAlgorithm::Solution
3
+
4
+ def initialize(array)
5
+ @data = array
6
+ end
7
+
8
+ def mutate
9
+ create_new_solution(@data.shuffle)
10
+ end
11
+
12
+ def crossover(other_solution)
13
+ sampled_indices = @data.each_index.to_a.sample(@data.size / 2)
14
+ sampled_elements = sampled_indices.map { |i| @data[i] }
15
+ elements_from_other = other_solution.data.select { |el| sampled_elements.include?(el) }
16
+ new_data = @data.dup
17
+ sampled_indices.zip(elements_from_other).each do |idx, el|
18
+ new_data[idx] = el
19
+ end
20
+ create_new_solution(new_data)
21
+ end
22
+ end
@@ -1,6 +1,6 @@
1
- module Greedy
1
+ module Algorithms::Greedy
2
2
  module Solution
3
- attr_reader :score, :next_solutions
3
+ abstract_method :score, :next_solutions
4
4
  end
5
5
 
6
6
  def self.init(solution)
@@ -19,7 +19,7 @@ module Greedy
19
19
  end
20
20
  end
21
21
 
22
- def current_solution
22
+ def best_solution
23
23
  @solutions_history[-1]
24
24
  end
25
25
  end
@@ -1,3 +1,3 @@
1
1
  module Victory
2
- VERSION = '0.3.1'
2
+ VERSION = '0.4.0'
3
3
  end
data/lib/victory.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require "victory/version"
2
2
 
3
+ require 'abstract_method'
4
+
3
5
  module Algorithms; end
4
6
  module Containers; end
5
7
 
@@ -7,6 +9,11 @@ require 'algorithms/search'
7
9
  require 'algorithms/sort'
8
10
  require 'algorithms/string'
9
11
  require 'algorithms/greedy'
12
+ require 'algorithms/genetic_algorithm/genetic_algorithm'
13
+ require 'algorithms/genetic_algorithm/solutions/bitset'
14
+ require 'algorithms/genetic_algorithm/solutions/array'
15
+ require 'algorithms/genetic_algorithm/solutions/permutation'
16
+ require 'algorithms/genetic_algorithm/solutions/combination'
10
17
  require 'containers/prefix_tree'
11
18
  require 'containers/heap'
12
19
  require 'containers/stack'
data/victory.gemspec CHANGED
@@ -35,4 +35,5 @@ Gem::Specification.new do |spec|
35
35
 
36
36
  spec.add_runtime_dependency 'concurrent-ruby', '~> 1.1.6'
37
37
  spec.add_runtime_dependency 'rgl', '~> 0.5.4'
38
+ spec.add_runtime_dependency 'abstract_method'
38
39
  end
metadata CHANGED
@@ -1,24 +1,24 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: victory
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arnold Szederjesi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-15 00:00:00.000000000 Z
11
+ date: 2020-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
- prerelease: false
16
15
  requirement: !ruby/object:Gem::Requirement
17
16
  requirements:
18
17
  - - "~>"
19
18
  - !ruby/object:Gem::Version
20
19
  version: '2.1'
21
20
  type: :development
21
+ prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
@@ -26,13 +26,13 @@ dependencies:
26
26
  version: '2.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest
29
- prerelease: false
30
29
  requirement: !ruby/object:Gem::Requirement
31
30
  requirements:
32
31
  - - "~>"
33
32
  - !ruby/object:Gem::Version
34
33
  version: '5.0'
35
34
  type: :development
35
+ prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
@@ -40,13 +40,13 @@ dependencies:
40
40
  version: '5.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
- prerelease: false
44
43
  requirement: !ruby/object:Gem::Requirement
45
44
  requirements:
46
45
  - - "~>"
47
46
  - !ruby/object:Gem::Version
48
47
  version: '10.0'
49
48
  type: :development
49
+ prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
@@ -54,13 +54,13 @@ dependencies:
54
54
  version: '10.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake-compiler
57
- prerelease: false
58
57
  requirement: !ruby/object:Gem::Requirement
59
58
  requirements:
60
59
  - - ">="
61
60
  - !ruby/object:Gem::Version
62
61
  version: '0'
63
62
  type: :development
63
+ prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
@@ -68,13 +68,13 @@ dependencies:
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
- prerelease: false
72
71
  requirement: !ruby/object:Gem::Requirement
73
72
  requirements:
74
73
  - - ">="
75
74
  - !ruby/object:Gem::Version
76
75
  version: '0'
77
76
  type: :development
77
+ prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - ">="
@@ -82,13 +82,13 @@ dependencies:
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: concurrent-ruby
85
- prerelease: false
86
85
  requirement: !ruby/object:Gem::Requirement
87
86
  requirements:
88
87
  - - "~>"
89
88
  - !ruby/object:Gem::Version
90
89
  version: 1.1.6
91
90
  type: :runtime
91
+ prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
@@ -96,18 +96,32 @@ dependencies:
96
96
  version: 1.1.6
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rgl
99
- prerelease: false
100
99
  requirement: !ruby/object:Gem::Requirement
101
100
  requirements:
102
101
  - - "~>"
103
102
  - !ruby/object:Gem::Version
104
103
  version: 0.5.4
105
104
  type: :runtime
105
+ prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: 0.5.4
111
+ - !ruby/object:Gem::Dependency
112
+ name: abstract_method
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  description:
112
126
  email:
113
127
  - szederjesiarnold@gmail.com
@@ -156,6 +170,11 @@ files:
156
170
  - ext/containers/xor_list/extconf.rb
157
171
  - ext/containers/xor_list/xor_list.c
158
172
  - extensions.rb
173
+ - lib/algorithms/genetic_algorithm/genetic_algorithm.rb
174
+ - lib/algorithms/genetic_algorithm/solutions/array.rb
175
+ - lib/algorithms/genetic_algorithm/solutions/bitset.rb
176
+ - lib/algorithms/genetic_algorithm/solutions/combination.rb
177
+ - lib/algorithms/genetic_algorithm/solutions/permutation.rb
159
178
  - lib/algorithms/greedy.rb
160
179
  - lib/algorithms/search.rb
161
180
  - lib/algorithms/sort.rb
@@ -203,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
203
222
  - !ruby/object:Gem::Version
204
223
  version: '0'
205
224
  requirements: []
206
- rubygems_version: 3.0.3
225
+ rubygems_version: 3.1.2
207
226
  signing_key:
208
227
  specification_version: 4
209
228
  summary: A gem providing all useful algorithms and data structures for programming