rubylabs 0.7.5 → 0.8.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.
- data/LICENSE +1 -1
- data/VERSION +1 -1
- data/data/huffman/testcodes.txt +30 -0
- data/data/huffman/testwords.txt +30 -0
- data/data/mars/dwarf.txt +1 -1
- data/data/spheres/fdemo.txt +6 -0
- data/data/spheres/fdemo2.txt +6 -0
- data/data/spheres/{urey.txt → melon.txt} +1 -1
- data/data/tsp/ireland.txt +23 -0
- data/data/tsp/test.txt +8 -8
- data/data/tsp/test10.txt +80 -0
- data/data/tsp/test7.txt +42 -0
- data/lib/bitlab.rb +381 -316
- data/lib/demos.rb +141 -0
- data/lib/elizalab.rb +7 -3
- data/lib/hashlab.rb +173 -115
- data/lib/introlab.rb +43 -4
- data/lib/iterationlab.rb +5 -33
- data/lib/marslab.rb +5 -5
- data/lib/permute.rb +30 -0
- data/lib/randomlab.rb +10 -29
- data/lib/recursionlab.rb +33 -25
- data/lib/rubylabs.rb +98 -76
- data/lib/sievelab.rb +6 -26
- data/lib/spherelab.rb +49 -23
- data/lib/tsplab.rb +717 -425
- data/test/bit_test.rb +5 -6
- data/test/eliza_test.rb +29 -24
- data/test/hash_test.rb +96 -0
- data/test/iteration_test.rb +20 -1
- data/test/random_test.rb +1 -1
- data/test/rubylabs_test.rb +93 -0
- data/test/sieve_test.rb +0 -1
- data/test/tsp_test.rb +140 -0
- metadata +14 -4
- data/data/huffman/hacodes.txt +0 -35
data/test/bit_test.rb
CHANGED
@@ -66,7 +66,7 @@ class TestBits < Test::Unit::TestCase
|
|
66
66
|
# Make an encoding scheme for 5 items -- we should get 5 binary codes from 000 to 100
|
67
67
|
|
68
68
|
def test_03_make_codes
|
69
|
-
a =
|
69
|
+
a = TestArray.new(5, :cars)
|
70
70
|
assert_equal a.length, 5
|
71
71
|
|
72
72
|
c = make_codes(a)
|
@@ -122,7 +122,7 @@ class TestBits < Test::Unit::TestCase
|
|
122
122
|
assert ! n2.leaf?
|
123
123
|
end
|
124
124
|
|
125
|
-
# Priority queue
|
125
|
+
# Priority queue -- uses the class defined in RubyLabs, but adds some "hooks"
|
126
126
|
|
127
127
|
def test_06_priority_queue
|
128
128
|
n0 = Node.new("A", 0.2)
|
@@ -132,6 +132,8 @@ class TestBits < Test::Unit::TestCase
|
|
132
132
|
pq = PriorityQueue.new
|
133
133
|
[n0,n1,n2].each { |x| pq << x }
|
134
134
|
|
135
|
+
assert_nil pq.on_canvas
|
136
|
+
|
135
137
|
assert_equal pq.length, 3
|
136
138
|
assert_equal pq.first, n0
|
137
139
|
assert_equal pq.last, n1
|
@@ -146,9 +148,7 @@ class TestBits < Test::Unit::TestCase
|
|
146
148
|
# Huffman tree and encoding
|
147
149
|
|
148
150
|
def test_07_huffman
|
149
|
-
|
150
|
-
freq = read_frequencies("#{data}/hafreq.txt")
|
151
|
-
|
151
|
+
freq = read_frequencies(:hafreq)
|
152
152
|
tree = build_tree(freq)
|
153
153
|
assert_equal tree.freq, 1.0
|
154
154
|
|
@@ -157,7 +157,6 @@ class TestBits < Test::Unit::TestCase
|
|
157
157
|
assert_equal codes["W"].to_s, "110010"
|
158
158
|
|
159
159
|
msg = encode("ALOHA", tree)
|
160
|
-
|
161
160
|
assert_equal msg.to_s, "100000010000110"
|
162
161
|
assert_equal decode(msg, tree), "ALOHA"
|
163
162
|
end
|
data/test/eliza_test.rb
CHANGED
@@ -11,6 +11,34 @@ require 'test_helper'
|
|
11
11
|
read from a file.
|
12
12
|
=end
|
13
13
|
|
14
|
+
=begin
|
15
|
+
TODO refactor Eliza.load, into two methods, one to read the file, the other to "compile" the lines
|
16
|
+
TODO test compiling by making a script in this file and passing it to the compile method
|
17
|
+
=end
|
18
|
+
|
19
|
+
# Example from MARS tests, showing how to build a "source file" and assemble it:
|
20
|
+
|
21
|
+
# def test_xx
|
22
|
+
# source = [
|
23
|
+
# "@label mov #0, #1 ; label needs to be alphanumeric",
|
24
|
+
# "l@bel mov #0, #1 ; label needs to be alphanumeric",
|
25
|
+
# "mov #0, #1 ; unlabeled line must start with space",
|
26
|
+
# "label @bogus #0, #1 ; opcode with non-alphanumeric",
|
27
|
+
# "label b@gus #0, #1 ; opcode with non-alphanumeric",
|
28
|
+
# "label muv #0, #1 ; unknown opcode",
|
29
|
+
# " mov #b@gus, #1 ; messed up operand",
|
30
|
+
# " mov #0 #1 ; missing comma",
|
31
|
+
# " EQU 3 ; missing label on pseudo-op",
|
32
|
+
# "x EQU 3x ; arg not an integer",
|
33
|
+
# " END foo ; undefined label",
|
34
|
+
# ]
|
35
|
+
#
|
36
|
+
# name, code, symbols, errors = MARS.assemble(source)
|
37
|
+
#
|
38
|
+
# assert_equal source.length, errors.length # every line generates an error
|
39
|
+
# assert_equal 0, code.length # should be no instructions generated
|
40
|
+
# end
|
41
|
+
|
14
42
|
include ElizaLab
|
15
43
|
|
16
44
|
class TestEliza < Test::Unit::TestCase
|
@@ -18,33 +46,10 @@ class TestEliza < Test::Unit::TestCase
|
|
18
46
|
def test_00_banner
|
19
47
|
print "\nElizaLab"
|
20
48
|
end
|
21
|
-
|
49
|
+
|
22
50
|
# A Pattern object represents a sentence pattern, which associates a regular
|
23
51
|
# expression with a set of possible responses.
|
24
52
|
|
25
|
-
# Example from MARS tests, showing how to build a "source file" and assemble it:
|
26
|
-
|
27
|
-
# def test_xx
|
28
|
-
# source = [
|
29
|
-
# "@label mov #0, #1 ; label needs to be alphanumeric",
|
30
|
-
# "l@bel mov #0, #1 ; label needs to be alphanumeric",
|
31
|
-
# "mov #0, #1 ; unlabeled line must start with space",
|
32
|
-
# "label @bogus #0, #1 ; opcode with non-alphanumeric",
|
33
|
-
# "label b@gus #0, #1 ; opcode with non-alphanumeric",
|
34
|
-
# "label muv #0, #1 ; unknown opcode",
|
35
|
-
# " mov #b@gus, #1 ; messed up operand",
|
36
|
-
# " mov #0 #1 ; missing comma",
|
37
|
-
# " EQU 3 ; missing label on pseudo-op",
|
38
|
-
# "x EQU 3x ; arg not an integer",
|
39
|
-
# " END foo ; undefined label",
|
40
|
-
# ]
|
41
|
-
#
|
42
|
-
# name, code, symbols, errors = MARS.assemble(source)
|
43
|
-
#
|
44
|
-
# assert_equal source.length, errors.length # every line generates an error
|
45
|
-
# assert_equal 0, code.length # should be no instructions generated
|
46
|
-
# end
|
47
|
-
|
48
53
|
# The simplest pattern has a literal word, and cycles through sentences when applied
|
49
54
|
# to inputs that contain that word
|
50
55
|
|
data/test/hash_test.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
require 'test_helper'
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
include HashLab
|
6
|
+
|
7
|
+
class TestHash < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def test_00_banner
|
10
|
+
print "\nHashLab"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Test the simple hash functions
|
14
|
+
|
15
|
+
def test_01_simple_hash_functions
|
16
|
+
assert_equal 0, h("apple")
|
17
|
+
assert_equal 5, h("zebra")
|
18
|
+
|
19
|
+
assert_equal 0, h0("aardvark", 10)
|
20
|
+
assert_equal 0, h0("aardvark", 1000)
|
21
|
+
assert_equal 5, h0("zymurgy", 10)
|
22
|
+
assert_equal 25, h0("zymurgy", 1000)
|
23
|
+
|
24
|
+
assert_equal 0, h1("aardvark", 10)
|
25
|
+
assert_equal 0, h1("aardvark", 1000)
|
26
|
+
assert_equal 4, h1("zymurgy", 10)
|
27
|
+
assert_equal 674, h1("zymurgy", 1000)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Test radix-26 and hash function that uses it
|
31
|
+
|
32
|
+
def test_02_radix26
|
33
|
+
assert_equal 783, radix26("bed")
|
34
|
+
assert_equal 784, radix26("bee")
|
35
|
+
assert_equal 8013894328, radix26("zymurgy")
|
36
|
+
|
37
|
+
assert_equal 8, hr("zymurgy", 10)
|
38
|
+
assert_equal 28, hr("zymurgy", 100)
|
39
|
+
assert_equal 328, hr("zymurgy", 1000)
|
40
|
+
assert_equal 4328, hr("zymurgy", 10000)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Test the stand-alone insert and lookup methods (w/o bucket)
|
44
|
+
|
45
|
+
def test_03_insert_and_lookup
|
46
|
+
t = Array.new(10)
|
47
|
+
assert_equal 3, insert("duck", t)
|
48
|
+
assert_equal 7, insert("husky", t)
|
49
|
+
assert_equal 1, insert("bruin", t)
|
50
|
+
assert_nil insert("beaver", t)
|
51
|
+
|
52
|
+
assert_equal 3, lookup("duck", t)
|
53
|
+
assert_equal 1, lookup("bruin", t)
|
54
|
+
assert_nil lookup("trojan", t)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Make a HashTable object, repeat insert and lookup tests, then
|
58
|
+
# capture the output from print_stats to verify the table structure
|
59
|
+
|
60
|
+
def test_04_hash_table
|
61
|
+
t = HashTable.new(10, :h0)
|
62
|
+
assert_equal 3, t.insert("duck")
|
63
|
+
assert_equal 1, t.insert("beaver")
|
64
|
+
assert_equal 7, t.insert("husky")
|
65
|
+
assert_equal 2, t.insert("cougar")
|
66
|
+
assert_equal 2, t.insert("cardinal")
|
67
|
+
assert_equal 1, t.insert("bear")
|
68
|
+
assert_equal 1, t.insert("bruin")
|
69
|
+
assert_equal 9, t.insert("trojan")
|
70
|
+
assert_equal 8, t.insert("sun devil")
|
71
|
+
assert_equal 2, t.insert("wildcat")
|
72
|
+
|
73
|
+
assert_equal 3, t.lookup("duck")
|
74
|
+
assert_equal 1, t.lookup("bear")
|
75
|
+
assert_nil t.lookup("eagle")
|
76
|
+
assert_nil t.lookup("buffalo")
|
77
|
+
|
78
|
+
oldout = $stdout
|
79
|
+
newout = StringIO.new
|
80
|
+
$stdout = newout
|
81
|
+
t.print_stats
|
82
|
+
$stdout = oldout
|
83
|
+
lines = newout.string.split("\n")
|
84
|
+
|
85
|
+
assert_equal 0, get_value("shortest", lines)
|
86
|
+
assert_equal 3, get_value("longest", lines)
|
87
|
+
assert_equal 4, get_value("empty", lines)
|
88
|
+
assert_equal 1.67, get_value("mean", lines)
|
89
|
+
end
|
90
|
+
|
91
|
+
def get_value(s, a)
|
92
|
+
line = a.grep(Regexp.new(s))[0]
|
93
|
+
return line[/\d+\.?\d*/].to_f
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
data/test/iteration_test.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
2
|
require 'test_helper'
|
3
|
+
require 'stringio'
|
3
4
|
|
4
5
|
include IterationLab
|
5
6
|
|
@@ -31,11 +32,29 @@ class TestIterativeAlgoritms < Test::Unit::TestCase
|
|
31
32
|
|
32
33
|
# Make some test arrays, sort them
|
33
34
|
|
34
|
-
def
|
35
|
+
def test_03_isort
|
35
36
|
[15, 16, 17].each do |size|
|
36
37
|
a = TestArray.new(size)
|
37
38
|
assert_equal isort(a), a.sort
|
38
39
|
end
|
39
40
|
end
|
40
41
|
|
42
|
+
# Capture the output of a trace when sorting a list of 5 numbers. Expect
|
43
|
+
# four lines, with left bracket moving one number to the right each time.
|
44
|
+
|
45
|
+
def test_04_trace
|
46
|
+
assert Source.clear
|
47
|
+
oldout = $stdout
|
48
|
+
newout = StringIO.new
|
49
|
+
$stdout = newout
|
50
|
+
Source.probe :isort, 5, "puts brackets(a,i)"
|
51
|
+
trace { isort(TestArray.new(5)) }
|
52
|
+
$stdout = oldout
|
53
|
+
lines = newout.string.split("\n")
|
54
|
+
assert_equal 4, lines.length
|
55
|
+
assert_match /\d+\s+\[.*\]/, lines[0]
|
56
|
+
assert_match /\d+\s+\d+\s+\[.*\]/, lines[1]
|
57
|
+
assert_match /\[\d+\]/, lines[-1]
|
58
|
+
end
|
59
|
+
|
41
60
|
end
|
data/test/random_test.rb
CHANGED
data/test/rubylabs_test.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
2
|
require 'test_helper'
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
include IterationLab
|
3
6
|
|
4
7
|
class RubyLabsTest < Test::Unit::TestCase
|
5
8
|
|
@@ -7,11 +10,101 @@ class RubyLabsTest < Test::Unit::TestCase
|
|
7
10
|
print "\nRubyLabs"
|
8
11
|
end
|
9
12
|
|
13
|
+
# A test array is an array of randomly selected integers. A method named random
|
14
|
+
# should return a number that is guaranteed to be in the array, when passed the
|
15
|
+
# :success option, or a number that is not in the array, when passed :fail
|
16
|
+
|
10
17
|
def test_01_arrays
|
11
18
|
a = TestArray.new(10)
|
12
19
|
assert a.length == 10
|
13
20
|
assert a.include?(a.random(:success))
|
14
21
|
assert !a.include?(a.random(:fail))
|
15
22
|
end
|
23
|
+
|
24
|
+
# Simple test to make sure log2 is defined...
|
25
|
+
|
26
|
+
def test_02_log2
|
27
|
+
assert_equal 3.0, log2(8)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Test min and max methods
|
31
|
+
|
32
|
+
def test_03_minmax
|
33
|
+
assert_equal 10, min(10,20)
|
34
|
+
assert_equal 10, min(20,10)
|
35
|
+
assert_equal 20, max(10,20)
|
36
|
+
assert_equal 20, max(20,10)
|
37
|
+
end
|
38
|
+
|
39
|
+
# This test just makes sure the time method runs -- no way to really test to
|
40
|
+
# see if the result is accurate
|
41
|
+
|
42
|
+
def test_04_time
|
43
|
+
assert_not_nil time { min(10,20) }
|
44
|
+
end
|
45
|
+
|
46
|
+
# Capture the listing of the 'less' method (from IterationLab); it should have
|
47
|
+
# three lines of Ruby code, with a 'def', 'return', and 'end'
|
48
|
+
|
49
|
+
def test_05_listing
|
50
|
+
oldout = $stdout
|
51
|
+
newout = StringIO.new
|
52
|
+
$stdout = newout
|
53
|
+
Source.listing :less
|
54
|
+
$stdout = oldout
|
55
|
+
lines = newout.string.split("\n")
|
56
|
+
assert_equal 3, lines.length
|
57
|
+
assert_match /1:\s+def less/, lines[0]
|
58
|
+
assert_match /2:\s+return/, lines[1]
|
59
|
+
assert_match /3:\s+end/, lines[2]
|
60
|
+
end
|
61
|
+
|
62
|
+
# This test sets a "counting probe" on the method named 'less' in the IterationLab
|
63
|
+
# module, and then counts how many times 'less' is called.
|
16
64
|
|
65
|
+
def test_06_count
|
66
|
+
assert Source.clear
|
67
|
+
assert Source.probe :less, 2, :count
|
68
|
+
n = count { less(10,20) }
|
69
|
+
assert_equal 1, n
|
70
|
+
end
|
71
|
+
|
72
|
+
# Same as above, except the probe prints a message to stdout. Capture the message
|
73
|
+
# to make sure the probe mechanism works.
|
74
|
+
|
75
|
+
def test_07_trace
|
76
|
+
oldout = $stdout
|
77
|
+
newout = StringIO.new
|
78
|
+
assert Source.probe :less, 2, "puts 'got it'"
|
79
|
+
$stdout = newout
|
80
|
+
res = trace { less(10,20) }
|
81
|
+
$stdout = oldout
|
82
|
+
assert res
|
83
|
+
assert_equal "got it", newout.string.chomp
|
84
|
+
end
|
85
|
+
|
86
|
+
# Priority Queue test
|
87
|
+
|
88
|
+
def test_08_priority_queue
|
89
|
+
pq = PriorityQueue.new
|
90
|
+
[5, 15, 10, 20, 0].each { |x| pq << x }
|
91
|
+
assert_equal 5, pq.length
|
92
|
+
assert_equal 0, pq[0]
|
93
|
+
assert_equal 20, pq[-1]
|
94
|
+
assert_equal 0, pq.shift
|
95
|
+
assert_equal 4, pq.length
|
96
|
+
assert_raise(NoMethodError) { pq[0] = 100 }
|
97
|
+
end
|
98
|
+
|
99
|
+
# 'ord' method -- maps upper and lower case letters to 0..25, others return
|
100
|
+
# self (i.e. ASCII code)
|
101
|
+
|
102
|
+
def test_09_ord
|
103
|
+
assert_equal 0, ?A.ord
|
104
|
+
assert_equal 25, ?Z.ord
|
105
|
+
assert_equal 0, ?a.ord
|
106
|
+
assert_equal 25, ?z.ord
|
107
|
+
assert_equal ?:.ord, ?:
|
108
|
+
end
|
109
|
+
|
17
110
|
end
|
data/test/sieve_test.rb
CHANGED
@@ -15,7 +15,6 @@ class TestSieve < Test::Unit::TestCase
|
|
15
15
|
def test_01_first_25
|
16
16
|
expected = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
|
17
17
|
assert_equal expected, sieve(100)
|
18
|
-
assert_equal expected, proto_sieve(100)
|
19
18
|
end
|
20
19
|
|
21
20
|
# Check length of list generated by sieve with expected number of primes (also from Wikipedia).
|
data/test/tsp_test.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
include TSPLab
|
5
|
+
|
6
|
+
class TestTSP < Test::Unit::TestCase
|
7
|
+
|
8
|
+
# load a test map used by the tests
|
9
|
+
|
10
|
+
@@map = Map.new(:test7)
|
11
|
+
|
12
|
+
def test_00_banner
|
13
|
+
print "\nTSPLab"
|
14
|
+
end
|
15
|
+
|
16
|
+
# test the factorial method
|
17
|
+
|
18
|
+
def test_01_fact
|
19
|
+
assert_equal 120, factorial(5)
|
20
|
+
assert_equal 1, factorial(1)
|
21
|
+
assert_equal 1, factorial(0)
|
22
|
+
end
|
23
|
+
|
24
|
+
# ntours(n) should compute (n-1)! / 2
|
25
|
+
|
26
|
+
def test_02_ntours
|
27
|
+
assert_equal 362880, factorial(9)
|
28
|
+
assert_equal 181440, ntours(10)
|
29
|
+
end
|
30
|
+
|
31
|
+
# generate all permutations of a 3-letter string in lexicographic order
|
32
|
+
|
33
|
+
def test_03_each_permutation
|
34
|
+
a = "ABC".each_permutation
|
35
|
+
assert_equal ["ABC", "ACB", "BAC", "BCA", "CAB", "CBA"], a
|
36
|
+
end
|
37
|
+
|
38
|
+
# check properties of the test map
|
39
|
+
|
40
|
+
def test_04_make_map
|
41
|
+
assert_equal 7, @@map.size
|
42
|
+
assert_equal [:A, :B, :C, :D, :E, :F, :G], @@map.labels
|
43
|
+
assert_equal [192, 212], @@map.coords(:A)
|
44
|
+
assert_equal [433, 133], @@map.coords(:G)
|
45
|
+
end
|
46
|
+
|
47
|
+
# check stored distances
|
48
|
+
|
49
|
+
def test_05_distances
|
50
|
+
assert_equal 151.54, @@map[ :A, :B ]
|
51
|
+
assert_equal 151.54, @@map[ :B, :A ]
|
52
|
+
assert_equal 144.51, @@map[ :F, :G ]
|
53
|
+
assert_nil @@map[:x, :y]
|
54
|
+
end
|
55
|
+
|
56
|
+
# make a short 3-city tour with the first 3 cities
|
57
|
+
|
58
|
+
def test_06_make_tour
|
59
|
+
t = @@map.make_tour [:A, :B, :C]
|
60
|
+
assert_equal [:A, :B, :C], t.path
|
61
|
+
assert_equal (@@map[:A,:B] + @@map[:B,:C] + @@map[:C,:A]), t.cost
|
62
|
+
assert_equal 1, Tour.count
|
63
|
+
end
|
64
|
+
|
65
|
+
# exhaustive search for best tour -- record the best tour, and check to
|
66
|
+
# to make sure each tour generated (by checking the count of the number made)
|
67
|
+
|
68
|
+
def test_07_exhaustive
|
69
|
+
@@best = @@map.make_tour(:random)
|
70
|
+
Tour.reset
|
71
|
+
@@map.each_tour { |t| @@best = t if t.cost < @@best.cost }
|
72
|
+
assert_in_delta 1185.43, @@best.cost, 0.001
|
73
|
+
assert_equal ntours(@@map.size), Tour.count
|
74
|
+
end
|
75
|
+
|
76
|
+
# point mutation test -- middle of the tour
|
77
|
+
|
78
|
+
def test_08_mutate_middle
|
79
|
+
t = @@map.make_tour([ :A, :B, :C, :D, :E, :F, :G ])
|
80
|
+
tc = t.cost
|
81
|
+
t.mutate!(2)
|
82
|
+
assert_equal [:A, :B, :D, :C, :E, :F, :G], t.path
|
83
|
+
assert_equal t.cost, tc - @@map[:B,:C] - @@map[:D,:E] + @@map[:B,:D] + @@map[:C,:E]
|
84
|
+
t.mutate!(2)
|
85
|
+
assert_equal [:A, :B, :C, :D, :E, :F, :G], t.path
|
86
|
+
assert_equal tc, t.cost
|
87
|
+
end
|
88
|
+
|
89
|
+
# point mutation test -- wraparound
|
90
|
+
|
91
|
+
def test_09_mutate_wrap
|
92
|
+
t = @@map.make_tour([ :A, :B, :C, :D, :E, :F, :G ])
|
93
|
+
tc = t.cost
|
94
|
+
t.mutate!(6)
|
95
|
+
assert_equal [:G, :B, :C, :D, :E, :F, :A], t.path
|
96
|
+
assert_equal t.cost, tc - @@map[:F,:G] - @@map[:A,:B] + @@map[:F,:A] + @@map[:G,:B]
|
97
|
+
t.mutate!(6)
|
98
|
+
assert_equal [:A, :B, :C, :D, :E, :F, :G], t.path
|
99
|
+
assert_equal tc, t.cost
|
100
|
+
end
|
101
|
+
|
102
|
+
# crossover test -- copy cities 2..4 from first tour, then get rest from other tour.
|
103
|
+
|
104
|
+
def test_10_cross
|
105
|
+
t0 = @@map.make_tour([ :A, :B, :C, :D, :E, :F, :G ])
|
106
|
+
t1 = @@map.make_tour([ :G, :F, :E, :D, :C, :B, :A ])
|
107
|
+
t0.cross!(t1, 2, 3)
|
108
|
+
assert_equal [:C, :D, :E, :G, :F, :B, :A], t0.path
|
109
|
+
t0.cross!(t1, 0, 1)
|
110
|
+
assert_equal [:C, :G, :F, :E, :D, :B, :A], t0.path
|
111
|
+
t0.cross!(t1, 6, 1)
|
112
|
+
assert_equal [:A, :G, :F, :E, :D, :C, :B], t0.path
|
113
|
+
end
|
114
|
+
|
115
|
+
# random search -- check to make sure 100 tours are created when rsearch is told
|
116
|
+
# to look at 100 random samples
|
117
|
+
|
118
|
+
def test_11_rsearch
|
119
|
+
Tour.reset
|
120
|
+
rsearch(@@map, 100)
|
121
|
+
assert_equal 100, Tour.count
|
122
|
+
end
|
123
|
+
|
124
|
+
# evolutionary search -- instead of trying to test components (init_population,
|
125
|
+
# select_survivors, rebuild population) this test just checks to see if esearch
|
126
|
+
# finds the best tour. Since there are only 7 cites (360 tours) running for
|
127
|
+
# 25 generations with a population size of 50 should be more than enough to find
|
128
|
+
# the optimal tour (saved by the exhaustive search in a previous test). The search
|
129
|
+
# should make around 625 tours; checking for a count between 525 and 725 should be safe.
|
130
|
+
|
131
|
+
def test_12_esearch
|
132
|
+
popsize = 50
|
133
|
+
ngen = 25
|
134
|
+
Tour.reset
|
135
|
+
t = esearch(@@map, ngen, :popsize => popsize, :distribution => :mixed)
|
136
|
+
assert_in_delta @@best.cost, t.cost, 100*Float::EPSILON
|
137
|
+
assert_in_delta (popsize*ngen/2), Tour.count, 100
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubylabs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- conery
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-05-17 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -45,9 +45,10 @@ files:
|
|
45
45
|
- data/arrays/wordlist.txt
|
46
46
|
- data/eliza/doctor.txt
|
47
47
|
- data/huffman/aafreq.txt
|
48
|
-
- data/huffman/hacodes.txt
|
49
48
|
- data/huffman/hafreq.txt
|
50
49
|
- data/huffman/hvfreq.txt
|
50
|
+
- data/huffman/testcodes.txt
|
51
|
+
- data/huffman/testwords.txt
|
51
52
|
- data/mars/chang1.txt
|
52
53
|
- data/mars/dwarf.txt
|
53
54
|
- data/mars/ferret.txt
|
@@ -61,18 +62,25 @@ files:
|
|
61
62
|
- data/mars/test_hello.txt
|
62
63
|
- data/mars/test_mult.txt
|
63
64
|
- data/mars/test_threads.txt
|
65
|
+
- data/spheres/fdemo.txt
|
66
|
+
- data/spheres/fdemo2.txt
|
64
67
|
- data/spheres/fourbody.txt
|
68
|
+
- data/spheres/melon.txt
|
65
69
|
- data/spheres/solarsystem.txt
|
66
|
-
- data/
|
70
|
+
- data/tsp/ireland.txt
|
67
71
|
- data/tsp/pac10.txt
|
68
72
|
- data/tsp/test.txt
|
73
|
+
- data/tsp/test10.txt
|
74
|
+
- data/tsp/test7.txt
|
69
75
|
- lib/bitlab.rb
|
76
|
+
- lib/demos.rb
|
70
77
|
- lib/elizalab.rb
|
71
78
|
- lib/encryptionlab.rb
|
72
79
|
- lib/hashlab.rb
|
73
80
|
- lib/introlab.rb
|
74
81
|
- lib/iterationlab.rb
|
75
82
|
- lib/marslab.rb
|
83
|
+
- lib/permute.rb
|
76
84
|
- lib/randomlab.rb
|
77
85
|
- lib/recursionlab.rb
|
78
86
|
- lib/rubylabs.rb
|
@@ -111,6 +119,7 @@ test_files:
|
|
111
119
|
- test/bit_test.rb
|
112
120
|
- test/eliza_test.rb
|
113
121
|
- test/encryption_test.rb
|
122
|
+
- test/hash_test.rb
|
114
123
|
- test/iteration_test.rb
|
115
124
|
- test/mars_test.rb
|
116
125
|
- test/random_test.rb
|
@@ -119,3 +128,4 @@ test_files:
|
|
119
128
|
- test/sieve_test.rb
|
120
129
|
- test/sphere_test.rb
|
121
130
|
- test/test_helper.rb
|
131
|
+
- test/tsp_test.rb
|
data/data/huffman/hacodes.txt
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# The binary numbers are Hawaiian words, encoded with a Huffman code based on the
|
2
|
-
# letter frequencies in hafreq.txt. The word next to a code is the English translation
|
3
|
-
# of the Hawaiian word -- after decoding a string of bits look for the word in a
|
4
|
-
# Hawaiian-English dictionary to see if the decoding is correct.
|
5
|
-
|
6
|
-
011010 rain
|
7
|
-
001010 sugarcane
|
8
|
-
0011111 carving
|
9
|
-
110011010 night
|
10
|
-
0011000110 duck
|
11
|
-
1100001010 chicken
|
12
|
-
1001110110 swordfish
|
13
|
-
111001101111 large
|
14
|
-
001010111010 leeward
|
15
|
-
110000100010110 island
|
16
|
-
1100001010111010 ocean
|
17
|
-
0001110101111101 octopus
|
18
|
-
0000101110101111 porch
|
19
|
-
1110110111101101 goose
|
20
|
-
0010110110000110 teacher
|
21
|
-
100000111101111111 royalty
|
22
|
-
00110000110001101111 beach
|
23
|
-
11000100001100000010 thankyou
|
24
|
-
11000100011011101111 wind
|
25
|
-
0001010100000010000110 friend
|
26
|
-
0011000110000111111000110 morning
|
27
|
-
0001100110011101000001111 happy
|
28
|
-
110001000110000111110011111 year
|
29
|
-
00010100111010001111111001110 hospitality
|
30
|
-
1100010000011110001111111101111 visitor
|
31
|
-
11000100010110100001111111101101 mother
|
32
|
-
00011000001000110000111110011111 pineapple
|
33
|
-
110001101111011010001011011101101 imp
|
34
|
-
0011011110011011000100001111111101101 daughter
|
35
|
-
000101101100001100001011011000011011100110001011011100110001011010110011011010011110 triggerfish
|