pmeth 1.0.0 → 1.1.0
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 +30 -15
- 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: be93eb83871e0795baa264779bd8ba8eef3708f5
|
4
|
+
data.tar.gz: 55e2c27e3923bdb6671203c9ea896d965a9b3a25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d2ed29982589d3951b3a643e8f847ae42acf38b7f168bdf74c5dcf950bd63954560daed6d8a52c7b1220e2d7769bd660a59e7ae31f7e144b791c25905992573
|
7
|
+
data.tar.gz: c881281f8e56adeb2c6c9ffb7786ccea1119a5d24dfb13aa7f7ec594e2fde7c949957249b5a5c5db00b203443188c45d4b7cb503b112d8d1fdc0acc0a5afddf4
|
data/lib/pmeth.rb
CHANGED
@@ -3,15 +3,15 @@
|
|
3
3
|
require 'prime'
|
4
4
|
|
5
5
|
class Integer
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
#returns all positive factors of an Integer
|
7
|
+
def factors
|
8
|
+
(1..self).select { |n| (self % n).zero? }
|
9
|
+
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
#returns true if self is a prime number, false otherwise
|
12
|
+
def prime?
|
13
|
+
Prime.prime?(self)
|
14
|
+
end
|
15
15
|
end
|
16
16
|
|
17
17
|
|
@@ -26,7 +26,7 @@ class PMeth
|
|
26
26
|
# Returns a new permutation that has had a randomly sized sub-section re-ordered by shuffle
|
27
27
|
def self.chunk_mutate(permutation)
|
28
28
|
if permutation.length.prime? # if there are a prime number of objects in the permutation
|
29
|
-
ig = rand(permutation.length)
|
29
|
+
ig = rand(permutation.length) # choose a random object to ignore - to add back at its original index after mutation
|
30
30
|
ig_obj = permutation[ig] # save the object
|
31
31
|
permutation.delete_at(ig)
|
32
32
|
end
|
@@ -35,7 +35,7 @@ class PMeth
|
|
35
35
|
x = division(permutation)
|
36
36
|
end
|
37
37
|
sliced = permutation.each_slice(x).to_a # permutation is sliced into chunks of size x
|
38
|
-
e = rand(sliced.length
|
38
|
+
e = rand(sliced.length) # one of the chunks is chosen at random...
|
39
39
|
chunk = sliced[e]
|
40
40
|
until sliced[e] != chunk
|
41
41
|
sliced[e] = sliced[e].shuffle # ... and the objects within are shuffled
|
@@ -47,12 +47,12 @@ class PMeth
|
|
47
47
|
return mutant
|
48
48
|
end
|
49
49
|
|
50
|
-
# Returns a new permutation where two of the objects have swapped positions (indices)
|
50
|
+
# Returns a new permutation where two of the objects, chosen at random, have swapped positions (indices)
|
51
51
|
def self.swap_mutate(permutation)
|
52
52
|
a = b = x = y = 0
|
53
53
|
until a != b
|
54
|
-
x = rand(permutation.length
|
55
|
-
y = rand(permutation.length
|
54
|
+
x = rand(permutation.length) # randomly choose two indices x and y...
|
55
|
+
y = rand(permutation.length)
|
56
56
|
a = permutation[x] # ... and call the objects at these indices a and b
|
57
57
|
b = permutation[y]
|
58
58
|
end
|
@@ -62,11 +62,26 @@ class PMeth
|
|
62
62
|
return mutant
|
63
63
|
end
|
64
64
|
|
65
|
+
# Returns a new permutation where an object, chosen at random, has swapped position with one of it's immediate neighbours
|
66
|
+
def self.adjacent_swap(permutation)
|
67
|
+
x = rand(permutation.length) # randomly choose an index
|
68
|
+
coin = rand(2) # a 50% chance for an object to swap with it's left or right neighbour
|
69
|
+
if x == 0 || coin == 0 # object at index 0 of array can only swap with index 1
|
70
|
+
y = x + 1
|
71
|
+
elsif x == permutation.length-1 || coin == 1 # object at index -1 of array can only swap with index -2
|
72
|
+
y = x - 1
|
73
|
+
end
|
74
|
+
mutant = permutation.dup
|
75
|
+
mutant[x] = permutation[y]
|
76
|
+
mutant[y] = permutation[x]
|
77
|
+
return mutant
|
78
|
+
end
|
79
|
+
|
65
80
|
# Returns a permutation whose objects are ordered partly like parent_1 permutation, and partly like parent_2 permutation
|
66
81
|
def self.recombine(parent_1, parent_2)
|
67
82
|
x = division(parent_1) # the randomly chosen size of chunks that permutations will be split into
|
68
83
|
if parent_1.length.prime? # to compensate for permutations with a prime number of objects:
|
69
|
-
ig = rand(parent_1.length)
|
84
|
+
ig = rand(parent_1.length) # choose a random object to ignore - to add back at its original index after mutation
|
70
85
|
p2_ig = parent_2.index(parent_1[ig]) # choose the same object from parent_2
|
71
86
|
parent_1_reduced, parent_2_reduced = parent_1.dup, parent_2.dup # then create duplicates of the parent arrays...
|
72
87
|
parent_1_reduced.delete_at(ig); parent_2_reduced.delete_at(p2_ig) # .. and remove the ignored object from these duplicates
|
@@ -75,7 +90,7 @@ class PMeth
|
|
75
90
|
else
|
76
91
|
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
|
77
92
|
end
|
78
|
-
chosen = rand(p2s.length)
|
93
|
+
chosen = rand(p2s.length) # choose a chunk to have parent_2 ordered objects in child permutation
|
79
94
|
child = p1s.flatten.dup # un-modified child permutation to accept chunk from parent_2 (and possibly ignored object)
|
80
95
|
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:
|
81
96
|
index = p1s[chosen].index(i) # the index of each object in the chosen parent_1 chunk...
|
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: 1.
|
4
|
+
version: 1.1.0
|
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-06-27 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
|