pmeth 0.0.2 → 0.0.3
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 +83 -88
- 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: c10b7f39e2469c0ecfe087918e1a1bdf0fa9c200
|
4
|
+
data.tar.gz: 79da3d0a1648106e7ed3dd0bcbfb44a8964f58a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4211a9815d11ba335d958b0509902d8aa54a3aca195dff7cb242524da4d4b5fb19ba28697ef21cf4c88f29fb3e17493208b2d0536ab1f5bb012140b3e437d554
|
7
|
+
data.tar.gz: eb7d88b8b676d3ae595ef7b564ec80b8acb2461534cb4b6bf4a50abe6828c59411f446b9bc0a25f2d48e5c9e92e0c16065903f74e5f73dd57f2b41e4552df2c4
|
data/lib/pmeth.rb
CHANGED
@@ -1,124 +1,119 @@
|
|
1
1
|
#encoding: utf-8
|
2
2
|
class PMeth
|
3
|
-
#
|
4
|
-
# Output: true/false
|
3
|
+
# Returns true if n is a prime number, false if not
|
5
4
|
def self.prime?(n)
|
6
5
|
for d in 2..(n - 1)
|
7
6
|
if (n % d) == 0
|
8
|
-
|
9
|
-
|
7
|
+
return false
|
8
|
+
end
|
10
9
|
end
|
11
10
|
true
|
12
11
|
end
|
13
12
|
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
# Returns a random integer that array can be divided by to get another integer (other than the array length itself)
|
14
|
+
def self.division(array)
|
15
|
+
x = 1.5 # x assigned a non-integer value to begin with
|
16
|
+
if prime?(array.length) # array with prime number of objects is not divisible by any integer other than 1 and itself
|
17
|
+
x = 1
|
18
|
+
else
|
19
|
+
until x > 0 && array.length/x.to_f == (array.length/x.to_f).to_i && Integer === x
|
20
|
+
x = rand(array.length)
|
21
|
+
end
|
20
22
|
end
|
21
23
|
return x
|
22
24
|
end
|
23
25
|
|
24
|
-
#
|
25
|
-
|
26
|
-
|
26
|
+
# Returns a new permutation that has had a randomly sized sub-section re-ordered by shuffle
|
27
|
+
def self.chunk_mutate(permutation)
|
28
|
+
if prime?(permutation.length) # if there are a prime number of objects in the permutation
|
29
|
+
ig = rand(permutation.length)-1 # choose a random object to ignore - to add back at its original index after mutation
|
30
|
+
ig_obj = permutation[ig] # save the object
|
31
|
+
permutation.delete_at(ig)
|
32
|
+
end
|
33
|
+
mutant = []
|
34
|
+
1.times do # this is to make use of the redo statement below
|
35
|
+
x = 0 # x is the randomly chosen size of chunks that permutation will be split into
|
36
|
+
until x > 2 # the chunk to be re-ordered must have at least 2 objects
|
37
|
+
x = division(permutation)
|
38
|
+
end
|
39
|
+
sliced = permutation.each_slice(x).to_a # permutation is sliced into chunks of size x
|
40
|
+
e = rand(sliced.length-1) # one of the chunks is chosen at random...
|
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
|
+
end
|
51
|
+
return mutant[0] # new_perm
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns a new permutation where two of the objects have swapped positions (indices)
|
55
|
+
def self.swap_mutate(permutation)
|
56
|
+
a = b = x = y = 0
|
57
|
+
until a != b
|
58
|
+
x = rand(permutation.length-1) # randomly choose two indices x and y...
|
59
|
+
y = rand(permutation.length-1)
|
60
|
+
a = permutation[x] # ... and call the objects at these indices a and b
|
61
|
+
b = permutation[y]
|
62
|
+
end
|
63
|
+
mutant = permutation.dup # create a new permutation...
|
64
|
+
mutant[x] = b # ... with object b at index x...
|
65
|
+
mutant[y] = a # ... and object a at index y
|
66
|
+
return mutant
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns a permutation whose objects are ordered partly like a_parent permutation, and partly like b_parent permutation
|
27
70
|
def self.recombine(a_parent, b_parent)
|
28
|
-
|
29
|
-
1.times do #
|
30
|
-
x = division(a_parent)
|
31
|
-
if
|
32
|
-
|
33
|
-
|
34
|
-
ig
|
35
|
-
|
36
|
-
|
37
|
-
a_parent_reduced.delete_at(ig)
|
38
|
-
b_parent_reduced.delete_at(ig)
|
39
|
-
x = division(a_parent_reduced)
|
40
|
-
a_parent_sliced = a_parent_reduced.each_slice(x).to_a
|
71
|
+
child_permutation = []
|
72
|
+
1.times do # this is to make use of the redo statement below
|
73
|
+
x = division(a_parent) # the randomly chosen size of chunks that permutations will be split into
|
74
|
+
if prime?(a_parent.length) # to compensate for permutations with a prime number of objects:
|
75
|
+
ig = rand(a_parent.length)-1 # choose a random object to ignore - to add back at its original index after mutation
|
76
|
+
a_parent_reduced, b_parent_reduced = a_parent.dup, b_parent.dup # then create duplicates of the parent arrays...
|
77
|
+
a_parent_reduced.delete_at(ig); b_parent_reduced.delete_at(ig) # .. and remove the ignored object from these duplicates
|
78
|
+
x = division(a_parent_reduced) # choose a new chunk size for reduced parent permutations, that no longer have a prime number of objects
|
79
|
+
a_parent_sliced = a_parent_reduced.each_slice(x).to_a # slice the reduced parent permutations into chunks of size x
|
41
80
|
b_parent_sliced = b_parent_reduced.each_slice(x).to_a
|
42
81
|
else
|
43
|
-
a_parent_sliced = a_parent.each_slice(x).to_a
|
82
|
+
a_parent_sliced = a_parent.each_slice(x).to_a # if permutation lengths are non-prime, just slice the parent permutations into chunks of size x
|
44
83
|
b_parent_sliced = b_parent.each_slice(x).to_a
|
45
84
|
end
|
46
|
-
chosen = rand(b_parent_sliced.length)-1 # choose
|
47
|
-
child = a_parent_sliced.flatten.dup
|
48
|
-
|
49
|
-
|
50
|
-
a_parent_sliced[chosen].each do |
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
pos_array << pos
|
55
|
-
y+=1
|
85
|
+
chosen = rand(b_parent_sliced.length)-1 # choose a chunk to have b_parent ordered objects in child permutation
|
86
|
+
child = a_parent_sliced.flatten.dup # un-modified child permutation to accept chunk from b_parent (and possibly ignored object)
|
87
|
+
a_indices = []
|
88
|
+
### place each object in chosen a_parent chunk into the index it's corresponding object (from b_parent) occupies in a_parent ###
|
89
|
+
a_parent_sliced[chosen].each do |i|
|
90
|
+
index = a_parent_sliced[chosen].index(i) # the index of each object in the chosen a_parent chunk...
|
91
|
+
b_object = b_parent_sliced[chosen][index] # ... the object at that index in the chosen b_parent chunk...
|
92
|
+
a_indices << a_parent_sliced.flatten.index(b_object) # ... the index of that object (from b_parent chunk) (INDEX RHO) in a_parent is added to an array
|
56
93
|
end
|
57
|
-
if
|
94
|
+
if a_indices.include?(nil) # TODO unsure why: a_indices sometimes includes nil
|
58
95
|
redo
|
59
96
|
else
|
60
97
|
y = 0
|
61
|
-
|
62
|
-
unless b_parent_sliced[chosen].include?(a_parent_sliced[chosen][y])
|
63
|
-
child[
|
64
|
-
|
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
|
65
103
|
end
|
66
104
|
y+=1
|
67
105
|
end
|
68
106
|
end
|
69
|
-
if ig != nil
|
107
|
+
if ig != nil # if the permutations are a prime number in length, we now add the ignored object from earlier into child
|
70
108
|
if b_parent_sliced[chosen].include?(b_parent[ig]) # add the ignored object from b_parent if it's in the chosen chunk...
|
71
109
|
child.insert(ig, b_parent[ig])
|
72
110
|
else
|
73
111
|
child.insert(ig, a_parent[ig]) # ...otherwise add the ignored object from a_parent
|
74
112
|
end
|
75
113
|
end
|
76
|
-
|
77
|
-
redo
|
78
|
-
end
|
79
|
-
kid << child # so we can access this outside the loop
|
80
|
-
end
|
81
|
-
return kid[0]
|
82
|
-
end
|
83
|
-
|
84
|
-
# Input: A permutation array of unique objects
|
85
|
-
# Output: A slightly different permutation array of the same unique objects
|
86
|
-
def self.mutate(fasta)
|
87
|
-
mutant = []
|
88
|
-
1.times do
|
89
|
-
x = 0
|
90
|
-
until x > 2
|
91
|
-
x = division(fasta)
|
92
|
-
end
|
93
|
-
sliced = fasta.each_slice(x).to_a
|
94
|
-
e = rand(sliced.length-1).to_i
|
95
|
-
sliced[e] = sliced[e].shuffle
|
96
|
-
if sliced.flatten == fasta
|
97
|
-
redo
|
98
|
-
end
|
99
|
-
mutant << sliced.flatten
|
114
|
+
child_permutation << child # so we can access this outside the loop
|
100
115
|
end
|
101
|
-
return
|
116
|
+
return child_permutation[0]
|
102
117
|
end
|
103
118
|
|
104
|
-
# Input: A permutation array of unique objects
|
105
|
-
# Output: A slightly different permutation array of the same unique objects
|
106
|
-
def self.mini_mutate(fasta)
|
107
|
-
a = b = 0
|
108
|
-
until a != b
|
109
|
-
a = fasta[rand(fasta.length-1)]
|
110
|
-
b = fasta[rand(fasta.length-1)]
|
111
|
-
end
|
112
|
-
mutant = []
|
113
|
-
fasta.each do |i|
|
114
|
-
if i == a
|
115
|
-
mutant << b
|
116
|
-
elsif i == b
|
117
|
-
mutant << a
|
118
|
-
else
|
119
|
-
mutant << i
|
120
|
-
end
|
121
|
-
end
|
122
|
-
return mutant
|
123
|
-
end
|
124
119
|
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.3
|
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-04-
|
11
|
+
date: 2014-04-30 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
|