-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimplex_parse.rb
104 lines (90 loc) · 3.01 KB
/
simplex_parse.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
require 'compsci/simplex/parse'
require 'minitest/autorun'
include CompSci
describe Simplex::Parse do
parallelize_me!
P = Simplex::Parse
describe "Parse.term" do
it "must parse valid terms" do
{ "-1.2A" => [-1.2, :A],
"99x" => [99.0, :x],
"z" => [ 1.0, :z],
"-b" => [-1.0, :b] }.each { |valid, expected|
expect(P.term(valid)).must_equal expected
}
end
it "must reject invalid terms" do
["3xy", "24/7x", "x17", "2*x"].each { |invalid|
expect(proc { P.term(invalid) }).must_raise RuntimeError
}
end
end
describe "Parse.expression" do
it "must parse valid expressions" do
{ "x + y" => { x: 1.0, y: 1.0 },
"2x - 5y" => { x: 2.0, y: -5.0 },
"-2x - 3y + -42.7z" => { x: -2.0, y: -3.0, z: -42.7 },
" -5y + -x " => { y: -5.0, x: -1.0 },
"a - -b" => { a: 1.0, b: 1.0 },
"a A b" => { a: 1.0, :A => 1.0, b: 1.0 },
}.each { |valid, expected|
expect(P.expression(valid)).must_equal expected
}
end
it "must reject invalid expressions" do
["a2 + b2 = c2",
"x + xy",
"x * 2"].each { |invalid|
expect(proc { P.expression(invalid) }).must_raise P::Error
}
end
end
describe "Parse.tokenize" do
it "ignores leading or trailing whitespace" do
expect(P.tokenize(" 5x + 2.9y ")).must_equal ["5x", "+", "2.9y"]
end
it "ignores multiple spaces" do
expect(P.tokenize("5x + 2.9y")).must_equal ["5x", "+", "2.9y"]
end
end
describe "Parse.inequality" do
it "must parse valid inequalities" do
{ "x + y <= 4" => [{ x: 1.0, y: 1.0 }, 4.0],
"0.94a - 22.1b <= -14.67" => [{ a: 0.94, b: -22.1 }, -14.67],
"x <= 0" => [{ x: 1.0 }, 0],
}.each { |valid, expected|
expect(P.inequality(valid)).must_equal expected
}
end
it "must reject invalid inequalities" do
["x + y >= 4",
"0.94a - 22.1b <= -14.67c",
"x < 0",
].each { |invalid|
expect(proc { P.inequality(invalid) }).must_raise P::Error
}
end
end
end
describe "Simplex.maximize" do
it "must solve a problem" do
prob = Simplex.problem(maximize: 'x + y',
constraints: ['2x + y <= 4',
'x + 2y <= 3'])
sol = prob.solution
expect(sol).must_equal [Rational(5, 3), Rational(2, 3)]
end
it "must maximize" do
expect(Simplex.maximize('x + y',
'2x + y <= 4',
'x + 2y <= 3')).must_equal [Rational(5, 3),
Rational(2, 3)]
end
it "must reject bad expressions" do
expect(proc { Simplex.maximize(5) }).must_raise ArgumentError
expect(proc {
Simplex.maximize('5')
}).must_raise Simplex::Parse::InvalidTerm
# proc { Simplex.maximize('5x') }.must_raise Simplex::Parse::InvalidTerm
end
end