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