pmeth 0.0.3 → 0.0.4
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/pmeth.rb +43 -62
- 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: 16aba86c56088b02d3a72b8400c645aa1dfec5f2
|
4
|
+
data.tar.gz: a6ac908c2e1a370e363cd002fa25bba08cdccd37
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c446aca00d392d2cf81458e37691d32fc81a78ca7fdad97bda379cf8a3914728fa6984dfe9d3b042a93122bd6acafb46bf20b1ec06ce83e51ca049d41816ebd
|
7
|
+
data.tar.gz: 0df635df12846fea56937794a9510404f1c93da78e04c21bc9f1c0d492d8671a67d44b5121dc7e45e4666922f259b5019253b81469410fad58115f0a83e123b1
|
data/lib/pmeth.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#encoding: utf-8
|
2
2
|
class PMeth
|
3
|
-
# Returns true if n is a prime number, false if not
|
3
|
+
# Returns true if integer n is a prime number, false if not
|
4
4
|
def self.prime?(n)
|
5
5
|
for d in 2..(n - 1)
|
6
6
|
if (n % d) == 0
|
@@ -30,25 +30,21 @@ class PMeth
|
|
30
30
|
ig_obj = permutation[ig] # save the object
|
31
31
|
permutation.delete_at(ig)
|
32
32
|
end
|
33
|
-
|
34
|
-
|
35
|
-
x =
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
33
|
+
x = 0 # x is the randomly chosen size of chunks that permutation will be split into
|
34
|
+
until x > 2 # the chunk to be re-ordered must have at least 2 objects
|
35
|
+
x = division(permutation)
|
36
|
+
end
|
37
|
+
sliced = permutation.each_slice(x).to_a # permutation is sliced into chunks of size x
|
38
|
+
e = rand(sliced.length-1) # one of the chunks is chosen at random...
|
39
|
+
chunk = sliced[e]
|
40
|
+
until sliced[e] != chunk
|
41
41
|
sliced[e] = sliced[e].shuffle # ... and the objects within are shuffled
|
42
|
-
new_perm = sliced.flatten
|
43
|
-
if new_perm == permutation # if the size of the chunk to be shuffled is small, there is a chance that it may not be differently ordered by shuffle...
|
44
|
-
redo # ... redo is used to ensure that a mutant permutation is created
|
45
|
-
end
|
46
|
-
if ig != nil
|
47
|
-
new_perm.insert(ig, ig_obj)
|
48
|
-
end
|
49
|
-
mutant << new_perm # the new permutation has been added to an array for access outside the 1.times loop
|
50
42
|
end
|
51
|
-
|
43
|
+
mutant = sliced.flatten
|
44
|
+
if ig != nil
|
45
|
+
mutant.insert(ig, ig_obj)
|
46
|
+
end
|
47
|
+
return mutant
|
52
48
|
end
|
53
49
|
|
54
50
|
# Returns a new permutation where two of the objects have swapped positions (indices)
|
@@ -66,54 +62,39 @@ class PMeth
|
|
66
62
|
return mutant
|
67
63
|
end
|
68
64
|
|
69
|
-
# Returns a permutation whose objects are ordered partly like
|
70
|
-
def self.recombine(
|
65
|
+
# Returns a permutation whose objects are ordered partly like parent_1 permutation, and partly like parent_2 permutation
|
66
|
+
def self.recombine(parent_1, parent_2)
|
71
67
|
child_permutation = []
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
68
|
+
x = division(parent_1) # the randomly chosen size of chunks that permutations will be split into
|
69
|
+
if prime?(parent_1.length) # to compensate for permutations with a prime number of objects:
|
70
|
+
ig = rand(parent_1.length)-1 # choose a random object to ignore - to add back at its original index after mutation
|
71
|
+
p2_ig = parent_2.index(parent_1[ig]) # choose the same object from parent_2
|
72
|
+
parent_1_reduced, parent_2_reduced = parent_1.dup, parent_2.dup # then create duplicates of the parent arrays...
|
73
|
+
parent_1_reduced.delete_at(ig); parent_2_reduced.delete_at(p2_ig) # .. and remove the ignored object from these duplicates
|
74
|
+
x = division(parent_1_reduced) # choose a new chunk size for reduced parent permutations, that no longer have a prime number of objects
|
75
|
+
p1s, p2s = parent_1_reduced.each_slice(x).to_a, parent_2_reduced.each_slice(x).to_a # slice the reduced parent permutations into chunks of size x
|
76
|
+
else
|
77
|
+
p1s, p2s = parent_1.each_slice(x).to_a, parent_2.each_slice(x).to_a # if permutation lengths are non-prime, just slice the parent permutations into chunks of size x
|
78
|
+
end
|
79
|
+
chosen = rand(p2s.length)-1 # choose a chunk to have parent_2 ordered objects in child permutation
|
80
|
+
child = p1s.flatten.dup # un-modified child permutation to accept chunk from parent_2 (and possibly ignored object)
|
81
|
+
p1s[chosen].each do |i| # place each object in chosen parent_1 chunk into the index it's corresponding object (from parent_2) occupies in parent_1:
|
82
|
+
index = p1s[chosen].index(i) # the index of each object in the chosen parent_1 chunk...
|
83
|
+
p2_object = p2s[chosen][index] # ... the object at that index in the chosen parent_2 chunk...
|
84
|
+
p1_index = p1s.flatten.index(p2_object) # ... the index of that object (from parent_2 chunk) in parent_1
|
85
|
+
unless p2s[chosen].include?(p1s[chosen][index]) # unless the chosen chunk from parent_2 includes objects from the chosen parent_1 chunk...
|
86
|
+
child[p1_index] = p1s[chosen][index] # ... the object from the chosen chunk in parent_1 is added to p1_index in child
|
87
|
+
chosen_index = p1s.flatten.index(p1s[chosen][index]) # index of object from parent_1's chosen chunk in parent_1
|
88
|
+
child[chosen_index] = p2s[chosen][index] # swapping the indices of objects in chunks from parents, to give their indices in child
|
93
89
|
end
|
94
|
-
|
95
|
-
|
90
|
+
end
|
91
|
+
if ig != nil # if the permutations are a prime number in length, we now add the ignored object from earlier into child
|
92
|
+
if p2s[chosen].include?(parent_2[p2_ig]) # add the ignored object from parent_2 if it's in the chosen chunk...
|
93
|
+
child.insert(p2_ig, parent_2[p2_ig])
|
96
94
|
else
|
97
|
-
|
98
|
-
a_indices.each do |ai|
|
99
|
-
unless b_parent_sliced[chosen].include?(a_parent_sliced[chosen][y]) # unless the chosen chunk from b_parent includes objects from the chosen a_parent chunk...
|
100
|
-
child[ai] = a_parent_sliced[chosen][y] # ... the object from the chosen chunk in parent_a is added to INDEX RHO in child
|
101
|
-
chosen_index = a_parent_sliced.flatten.index(a_parent_sliced[chosen][y]) # index of object from a_parent's chosen chunk in a_parent
|
102
|
-
child[chosen_index] = b_parent_sliced[chosen][y] # swapping the indices of objects in chunks from parents, to give their indices in child
|
103
|
-
end
|
104
|
-
y+=1
|
105
|
-
end
|
106
|
-
end
|
107
|
-
if ig != nil # if the permutations are a prime number in length, we now add the ignored object from earlier into child
|
108
|
-
if b_parent_sliced[chosen].include?(b_parent[ig]) # add the ignored object from b_parent if it's in the chosen chunk...
|
109
|
-
child.insert(ig, b_parent[ig])
|
110
|
-
else
|
111
|
-
child.insert(ig, a_parent[ig]) # ...otherwise add the ignored object from a_parent
|
112
|
-
end
|
95
|
+
child.insert(ig, parent_1[ig]) # ...otherwise add the ignored object from parent_1
|
113
96
|
end
|
114
|
-
child_permutation << child # so we can access this outside the loop
|
115
97
|
end
|
116
|
-
return
|
98
|
+
return child
|
117
99
|
end
|
118
|
-
|
119
100
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pmeth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Edward Chalstrey
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: "Reproduction methods for genetic (and other iterative improvement) algorithms,
|
14
14
|
being used to solve permutation problems, \n where permutations are arrays of unique
|