optimal-control 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+
2
+ v0.0.2 Issue with resource pathing on version 0.0.1 resolved
3
+
4
+ v0.0.1 initial format
@@ -0,0 +1,11 @@
1
+ CHANGELOG
2
+ Manifest
3
+ README
4
+ Rakefile
5
+ bin/optimalcontrol
6
+ lib/cgl/evaluate.rb
7
+ lib/cgl/neighbors.rb
8
+ lib/cgl/runner.rb
9
+ test/test_evaluate.rb
10
+ test/test_neighbors.rb
11
+ test/test_runner.rb
data/README ADDED
@@ -0,0 +1,17 @@
1
+ Optimal Control for Conway's game of Life - 0.0.1
2
+ Franziska Hinkelmann
3
+ fhinkel@vt.edu
4
+
5
+
6
+ This gem will generate an optimal controller for Conway's game of Life on a n
7
+ x n grid with periodic boundary conditions. The control objective is to have
8
+ the left upper corner dead after m iterations, the control that can be applied
9
+ is to kill the cell one to the right of it.
10
+
11
+ Cost for control is 1 cost unit, independent of the iteration step it is
12
+ applied to. Every initial state to which control should be applied is
13
+ reported, including the iteration steps at which control should be applied.
14
+
15
+ Unit tests are in test/
16
+
17
+
@@ -0,0 +1,36 @@
1
+ require 'rake/gempackagetask'
2
+ require 'echoe'
3
+
4
+ #spec = Gem::Specification.new do |s|
5
+ # s.name = "optimal-control"
6
+ # s.summary = "Simulate Conway's game of Life on a small grid with periodic
7
+ # boundary conditions and find the optimal controller for the specified
8
+ # control objective and control options"
9
+ # s.description= File.read(File.join(File.dirname(__FILE__), 'README'))
10
+ # s.author = "Franziska Hinkelmann"
11
+ # s.email = "fhinkel@vt.edu"
12
+ # s.version = "0.0.2"
13
+ # s.platform = Gem::Platform::RUBY
14
+ # s.required_ruby_version = '>=1.8.6'
15
+ # s.files = Dir['**/**']
16
+ # s.executables = [ 'optimalcontrol' ]
17
+ # s.test_files = Dir["test/test*.rb"]
18
+ # s.has_rdoc = false
19
+ #end
20
+ #Rake::GemPackageTask.new(spec).define
21
+
22
+ spec = Echoe.new("optimal-control") do |s|
23
+ s.summary = "Simulate Conway's game of Life on a small grid with periodic
24
+ boundary conditions and find the optimal controller for the specified
25
+ control objective and control options"
26
+ #s.description= File.read(File.join(File.dirname(__FILE__), 'README'))
27
+ s.author = "Franziska Hinkelmann"
28
+ s.email = "fhinkel@vt.edu"
29
+ s.url = "http://rubyforge.org/projects/optimal-control/"
30
+ s.platform = Gem::Platform::RUBY
31
+ #s.required_ruby_version = '>=1.8.6'
32
+ #s.files = Dir['**/**']
33
+ #s.executables = [ 'optimalcontrol' ]
34
+ #s.test_files = Dir["test/test*.rb"]
35
+ #s.has_rdoc = false
36
+ end
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../lib/cgl/runner'
3
+
4
+ # Optimal Control for a 4by4 Conways game of life, control objective is
5
+ # defined in the assign_final_cost function
6
+ # assume control is 1 unit cost per cell, the central 4 cells can be
7
+ # independently controlled
8
+
9
+ if /-h/ =~ ARGV.to_s
10
+ puts
11
+ puts "Optimal Control for Conway's Game of Life"
12
+ puts
13
+ puts "Usage: bin/optimalconrol Iterations Height Width"
14
+ puts "Default values are 5 for the number of steps to iterate, and 2 as\
15
+ grid height and width of the grid."
16
+ puts
17
+ exit
18
+ end
19
+
20
+ Steps = ARGV[0].to_i - 1 || 4 # Steps + 1 iterations
21
+
22
+ unless 0 <= Steps
23
+ puts "The first argument, the number of iterations, must be an integer at least 1"
24
+ exit
25
+ end
26
+
27
+ Max_cost = (Steps+1)*4 + 1 # make states that are not admissible more expensive than
28
+ # applying control before all #Steps iterations
29
+
30
+ Grid_height = ARGV[1].to_i || 2
31
+ unless 0 < Grid_height && Grid_height < 5
32
+ puts "The second argument, height of the grid, must be an integer between 1 and 5"
33
+ exit
34
+ end
35
+ Grid_width = ARGV[2].to_i || Grid_height # if no hight is given, use a square grid
36
+ unless 0 < Grid_width && Grid_width < 5
37
+ puts "The third argument, width of the grid, must be an integer between 1 and 5"
38
+ exit
39
+ end
40
+
41
+
42
+ runner = Cgl::Runner.new(Steps, Max_cost, Grid_height, Grid_width)
43
+
44
+ # result = [cost_vector[0], control[0]]
45
+ result = runner.run
46
+
47
+ n_agents = Grid_height * Grid_width
48
+ cost_vector = result[0]
49
+ control = result[1]
50
+
51
+ # print all states that can lead to a valid final state
52
+ # TODO print control input to reach final state
53
+ for i in 0..2**n_agents-1 do
54
+ if (cost_vector[i]>0)
55
+ puts "%0#{n_agents}d" % i.to_s(2) + ": cost = #{cost_vector[i]}, control applied at timeSteps \"#{control[i]}\""
56
+ end
57
+ end
58
+
@@ -0,0 +1,26 @@
1
+ module Cgl
2
+ class Evaluate
3
+ # given an array of length 9, where the first entry is the agent to
4
+ # update, return the agents updated value
5
+ def self.evaluate( neighbors )
6
+ agent = neighbors.shift.to_i
7
+ number_of_alive_neighbors = neighbors.inject(0){|sum,item| sum.to_i + item.to_i }
8
+ # assume the very first column is the agent we're computing the next state
9
+ # for
10
+ if (number_of_alive_neighbors < 2)
11
+ f = 0
12
+ elsif (number_of_alive_neighbors == 2)
13
+ if (agent==1)
14
+ f = 1
15
+ else
16
+ f = 0
17
+ end
18
+ elsif (number_of_alive_neighbors == 3)
19
+ f = 1
20
+ else # number_of_alive_neighbors > 3
21
+ f = 0
22
+ end
23
+ f
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ module Cgl
2
+ class Neighbors
3
+ # given the index of an agent and the full grid, return an array with the
4
+ # values of the 8 neighboring agents
5
+ # assume periodic boundary conditions (wrap)
6
+ # all indexing is 0 based, so a 3 x 4 grid has these indexes:
7
+ # 0 1 2 3
8
+ # 4 5 6 7
9
+ # 8 9 10 11
10
+ #
11
+ def self.neighbors(agent, all_agents, height, width = height)
12
+ neighbors = Array.new
13
+ row = agent/width
14
+ column = agent%width
15
+ neighbors.push all_agents[(row*width)+(column+1)%width]
16
+ neighbors.push all_agents[((row+1)%height)*width+(column+1)%width]
17
+ neighbors.push all_agents[((row+1)%height)*width+(column)]
18
+ neighbors.push all_agents[((row+1)%height)*width+(column-1)%width]
19
+ neighbors.push all_agents[row*width+(column-1)%width]
20
+ neighbors.push all_agents[(row-1)*width+(column-1)%width]
21
+ neighbors.push all_agents[(row-1)*width+(column)]
22
+ neighbors.push all_agents[(row-1)*width+(column+1)%width]
23
+ neighbors
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,90 @@
1
+ require File.dirname(__FILE__) + '/evaluate'
2
+ require File.dirname(__FILE__) + '/neighbors'
3
+
4
+ module Cgl
5
+ class Runner
6
+ attr_reader :steps
7
+ attr_reader :max_cost
8
+ attr_reader :grid_height
9
+ attr_reader :grid_width
10
+ attr_reader :n_agents
11
+ def initialize( steps, max_cost, grid_height, grid_width = grid_height )
12
+ @steps = steps
13
+ @max_cost = max_cost
14
+ @grid_height = grid_height
15
+ @grid_width = grid_width
16
+ @n_agents = grid_height * grid_width
17
+ end
18
+
19
+ def run
20
+ cost_vector = Array.new(@steps+2) # cost_vector[i][state]cost of getting from state to admissible state in
21
+ # @steps+2-i time@steps
22
+
23
+ # control[j][i] has a sequence for applying control to state i
24
+ control = Array.new(@steps+2) # need an extra vector of empty strings, so we
25
+ #can later concatenate without worrying about being at the last entry
26
+ for i in 0..@steps+1 do
27
+ cost_vector[i] = Array.new(2**@n_agents)
28
+ control[i] = Array.new(2**@n_agents, "")
29
+ end
30
+
31
+ for i in 0..2**@n_agents-1 do
32
+ cost_vector[@steps+1][i] = assign_final_cost(i)
33
+ end
34
+
35
+ for j in 0..@steps do
36
+ puts @steps - j
37
+ for i in 0..2**@n_agents-1 do
38
+ i_as_array = ("%0#{@n_agents}d" % i.to_s(2)).split(//)
39
+
40
+ # calculate cost without control
41
+ output = iterate i_as_array
42
+ state = output.to_s.to_i(2)
43
+ cost_without_control = cost_vector[@steps-j+1][state]
44
+
45
+ # calculate cost with control and take min
46
+ # TODO pass agent to kill as arg
47
+ # control: kill agent 2
48
+ i_as_array[1] = "0"
49
+ output = iterate i_as_array
50
+ state_with_control = output.to_s.to_i(2)
51
+ cost_for_control = 1
52
+ cost_with_control = cost_vector[@steps-j+1][state_with_control] + cost_for_control
53
+
54
+ # take min and record if control was applied
55
+ if (cost_without_control < cost_with_control)
56
+ cost_vector[@steps-j][i] = cost_without_control
57
+ control[@steps-j][i] = control[@steps-j+1][state]
58
+ else
59
+ cost_vector[@steps-j][i] = cost_with_control
60
+ control[@steps-j][i] = "#{@steps-j+1}" + control[@steps-j+1][state_with_control]
61
+ end
62
+ end
63
+ end
64
+
65
+ [cost_vector[0], control[0]]
66
+ end
67
+
68
+ private
69
+ def assign_final_cost( state )
70
+ # valid if agent 1 is dead
71
+ if ( state < 2**(@n_agents - 1) )
72
+ cost = 0
73
+ else
74
+ cost = @max_cost
75
+ end
76
+ cost
77
+ end
78
+
79
+ def iterate( i_as_array )
80
+ output = Array.new(@n_agents)
81
+ for k in 0..@n_agents-1 do # update all N_agents states
82
+ input_data = Cgl::Neighbors.neighbors(k, i_as_array, @grid_height,
83
+ @grid_width)
84
+ output[k] = Cgl::Evaluate.evaluate([i_as_array[k]] + input_data)
85
+ end
86
+ output
87
+ end
88
+ end
89
+ end
90
+
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{optimal-control}
5
+ s.version = "0.0.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Franziska Hinkelmann"]
9
+ s.date = %q{2010-01-01}
10
+ s.default_executable = %q{optimalcontrol}
11
+ s.description = %q{Simulate Conway's game of Life on a small grid with periodic
12
+ boundary conditions and find the optimal controller for the specified
13
+ control objective and control options}
14
+ s.email = %q{fhinkel@vt.edu}
15
+ s.executables = ["optimalcontrol"]
16
+ s.extra_rdoc_files = ["CHANGELOG", "README", "bin/optimalcontrol", "lib/cgl/evaluate.rb", "lib/cgl/neighbors.rb", "lib/cgl/runner.rb"]
17
+ s.files = ["CHANGELOG", "Manifest", "README", "Rakefile", "bin/optimalcontrol", "lib/cgl/evaluate.rb", "lib/cgl/neighbors.rb", "lib/cgl/runner.rb", "test/test_evaluate.rb", "test/test_neighbors.rb", "test/test_runner.rb", "optimal-control.gemspec"]
18
+ s.homepage = %q{http://rubyforge.org/projects/optimal-control/}
19
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Optimal-control", "--main", "README"]
20
+ s.require_paths = ["lib"]
21
+ s.rubyforge_project = %q{optimal-control}
22
+ s.rubygems_version = %q{1.3.5}
23
+ s.summary = %q{Simulate Conway's game of Life on a small grid with periodic boundary conditions and find the optimal controller for the specified control objective and control options}
24
+ s.test_files = ["test/test_evaluate.rb", "test/test_neighbors.rb", "test/test_runner.rb"]
25
+
26
+ if s.respond_to? :specification_version then
27
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
28
+ s.specification_version = 3
29
+
30
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
31
+ else
32
+ end
33
+ else
34
+ end
35
+ end
@@ -0,0 +1,48 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'shoulda'
4
+
5
+ require 'lib/cgl/evaluate'
6
+
7
+ class TestEvaluate < Test::Unit::TestCase
8
+ context "alive agent" do
9
+ should "die as if caused by underpopulation" do
10
+ agent = Cgl::Evaluate.evaluate( ["1", "1"] )
11
+ assert_equal agent, 0
12
+ agent = Cgl::Evaluate.evaluate( ["1"] )
13
+ assert_equal agent, 0
14
+ end
15
+ should "die as if by overcrowding " do
16
+ agent = Cgl::Evaluate.evaluate( ["1", "1", "1", "1", "1"] )
17
+ assert_equal agent, 0
18
+ end
19
+ should "life on with 2 or 3 neighbors" do
20
+ agent = Cgl::Evaluate.evaluate( ["1", "1", "1"] )
21
+ assert_equal agent, 1
22
+ agent = Cgl::Evaluate.evaluate( ["1", "0", "0", "0", "1", "1"] )
23
+ assert_equal agent, 1
24
+ agent = Cgl::Evaluate.evaluate( ["1", "1", "1", "1"] )
25
+ assert_equal agent, 1
26
+ agent = Cgl::Evaluate.evaluate( ["1", "1", "0", "1", "1", "0", "0", "0",
27
+ "0"] )
28
+ assert_equal agent, 1
29
+ agent = Cgl::Evaluate.evaluate( ["1", "0", "0", "1", "1", "0", "0", "0",
30
+ "0"] )
31
+ assert_equal agent, 1
32
+ end
33
+ end
34
+ context "dead agent" do
35
+ should "become a live cell with 3 neighbors" do
36
+ agent = Cgl::Evaluate.evaluate( ["0", "1", "1", "1"] )
37
+ assert_equal agent, 1
38
+ agent = Cgl::Evaluate.evaluate( ["0", "0", "0", "0","1", "1", "1","0", "0"] )
39
+ assert_equal agent, 1
40
+ agent = Cgl::Evaluate.evaluate( ["0", "1", "0", "0","1", "0", "1"] )
41
+ assert_equal agent, 1
42
+ agent = Cgl::Evaluate.evaluate( ["1", "1", "0", "1", "1", "0","0", "0",
43
+ "0"] )
44
+ assert_equal agent, 1
45
+ end
46
+ end
47
+ end
48
+
@@ -0,0 +1,43 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'shoulda'
4
+
5
+ require 'lib/cgl/neighbors'
6
+
7
+ class TestNeighbors < Test::Unit::TestCase
8
+ context "agent in a 1 by 1 grid " do
9
+ should "have all 8 neighbors the same" do
10
+ neighbors = Cgl::Neighbors.neighbors(0, ["0"], 1)
11
+ assert_equal ["0", "0", "0", "0", "0", "0", "0", "0"], neighbors
12
+ neighbors = Cgl::Neighbors.neighbors(0, ["aa"], 1)
13
+ assert_equal ["aa", "aa", "aa", "aa", "aa", "aa", "aa", "aa"], neighbors
14
+ end
15
+ end
16
+ context "agent a in a 2 by 2 grid " do
17
+ should "have all 8 neighbors bdcdbdcdb" do
18
+ neighbors = Cgl::Neighbors.neighbors(0, ["a", "b", "c", "d"], 2)
19
+ assert_equal ["b", "d", "c", "d", "b", "d", "c", "d"], neighbors
20
+ end
21
+ end
22
+ context "central agent a in a 3 by 3 grid " do
23
+ should "have all normal 8 neighbors" do
24
+ neighbors = Cgl::Neighbors.neighbors(4, ["a", "b", "c", "d", "e", "f", "g", "h", "i"], 3)
25
+ assert_equal ["f", "i", "h", "g", "d", "a", "b", "c"], neighbors
26
+ end
27
+ end
28
+ context "upper right agent a in a 2 by 3 grid " do
29
+ should "have all normal 8 neighbors" do
30
+ neighbors = Cgl::Neighbors.neighbors(0, ["a", "b", "c", "d", "e", "f"],
31
+ 2, 3)
32
+ assert_equal ["b", "e", "d", "f", "c", "f", "d", "e"], neighbors
33
+ end
34
+ end
35
+ context "lower right corner on 3 by 3 grid" do
36
+ should "have the following neighbors" do
37
+ neighbors = Cgl::Neighbors.neighbors(8, ["a", "b", "c", "d", "e", "f", "g", "h", "i"], 3)
38
+ assert_equal ["g", "a", "c", "b", "h", "e", "f", "d"], neighbors
39
+ end
40
+ end
41
+
42
+ end
43
+
@@ -0,0 +1,114 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'shoulda'
4
+
5
+ require 'lib/cgl/runner'
6
+
7
+ class TestRunner < Test::Unit::TestCase
8
+ context "2 by 2 grid, 1 timestep " do
9
+ should "have these intial states with max cost" do
10
+ steps = 0
11
+ max_cost = (steps+1)*1 + 1
12
+ grid_size = 2
13
+ n_agents = grid_size**2
14
+ runner = Cgl::Runner.new(steps, max_cost, grid_size)
15
+ result = runner.run
16
+ assert_equal 2, result.size
17
+ cost_vector = result[0]
18
+ control = result[1]
19
+ assert_equal 2**n_agents, cost_vector.size
20
+ assert_equal 2**n_agents, control.size
21
+ for i in 0..2**n_agents-1
22
+ unless cost_vector[i] == max_cost
23
+ assert cost_vector[i]==control[i].size
24
+ end
25
+ #puts "%0#{n_agents}d" %i.to_s(2) + ": #{cost_vector[i]}"
26
+ end
27
+ precomputed_cost = "0000000000201000".split(//).collect{|x| x.to_i}
28
+ assert precomputed_cost == cost_vector,
29
+ precomputed_cost + cost_vector
30
+ assert ["", "", "", "", "", "", "", "", "", "", "", "", "1", "", "",
31
+ ""] == control
32
+ end
33
+ end
34
+ context "2 by 3 grid, 1 timestep " do
35
+ should "have these intial states with max cost" do
36
+ steps = 0
37
+ max_cost = (steps+1)*1 + 1
38
+ grid_hight = 2
39
+ grid_width = 3
40
+ n_agents = grid_width * grid_hight
41
+ runner = Cgl::Runner.new(steps, max_cost, grid_hight, grid_width)
42
+ result = runner.run
43
+ cost_vector = result[0]
44
+ control = result[1]
45
+ for i in 0..2**n_agents-1
46
+ unless cost_vector[i] == max_cost
47
+ assert cost_vector[i]==control[i].size
48
+ end
49
+ #puts "%0#{n_agents}d" %i.to_s(2) + ": #{cost_vector[i]}"
50
+ end
51
+
52
+ precomputed_cost =
53
+ "0000000002202000011010000000000002202000022020000220200010000000".split(//).collect{|x| x.to_i}
54
+ assert precomputed_cost == cost_vector,
55
+ precomputed_cost.to_s + "\n" + cost_vector.to_s
56
+ precomputed_control = ["", "", "", "", "", "", "", "", "", "", "", "",
57
+ "", "", "", "", "", "1", "1", "", "1", "", "", "", "", "", "", "", "",
58
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
59
+ "", "", "", "", "", "", "", "", "", "1", "", "", "", "", "", "", ""]
60
+ assert precomputed_control == control, "control is wrong"
61
+ end
62
+ end
63
+ context "2 by 2 grid, 3 timestep " do
64
+ should "have these intial states with max cost" do
65
+ steps = 2
66
+ max_cost = (steps+1)*1 + 1
67
+ grid_size = 2
68
+ n_agents = grid_size**2
69
+ runner = Cgl::Runner.new(steps, max_cost, grid_size)
70
+ result = runner.run
71
+ assert_equal 2, result.size
72
+ cost_vector = result[0]
73
+ control = result[1]
74
+ assert_equal 2**n_agents, cost_vector.size
75
+ assert_equal 2**n_agents, control.size
76
+ for i in 0..2**n_agents-1
77
+ unless cost_vector[i] == max_cost
78
+ assert cost_vector[i]==control[i].size
79
+ end
80
+ end
81
+ precomputed_cost = "0000000000401000".split(//).collect{|x| x.to_i}
82
+ assert precomputed_cost == cost_vector,
83
+ precomputed_cost + cost_vector
84
+ assert ["", "", "", "", "", "", "", "", "", "", "", "", "1", "", "",
85
+ ""] == control
86
+ end
87
+ end
88
+ context "3 by 3 grid, 1 timestep " do
89
+ should "have these intial states with max cost" do
90
+ steps = 0
91
+ max_cost = (steps+1)*1 + 1
92
+ grid_size = 3
93
+ n_agents = grid_size**2
94
+ runner = Cgl::Runner.new(steps, max_cost, grid_size)
95
+ result = runner.run
96
+ assert_equal 2, result.size
97
+ cost_vector = result[0]
98
+ control = result[1]
99
+ assert_equal 2**n_agents, cost_vector.size
100
+ assert_equal 2**n_agents, control.size
101
+ for i in 0..2**n_agents-1
102
+ unless cost_vector[i] == max_cost
103
+ assert cost_vector[i]==control[i].size
104
+ end
105
+ #puts "%0#{n_agents}d" %i.to_s(2) + ": #{cost_vector[i]} control in step #{control[i]}"
106
+ end
107
+ # some hand crafted test cases
108
+ assert cost_vector[335] == 0
109
+ assert cost_vector[432] == 2
110
+ assert cost_vector[448] == 1
111
+ end
112
+ end
113
+ end
114
+
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: optimal-control
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Franziska Hinkelmann
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-01 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: |-
17
+ Simulate Conway's game of Life on a small grid with periodic
18
+ boundary conditions and find the optimal controller for the specified
19
+ control objective and control options
20
+ email: fhinkel@vt.edu
21
+ executables:
22
+ - optimalcontrol
23
+ extensions: []
24
+
25
+ extra_rdoc_files:
26
+ - CHANGELOG
27
+ - README
28
+ - bin/optimalcontrol
29
+ - lib/cgl/evaluate.rb
30
+ - lib/cgl/neighbors.rb
31
+ - lib/cgl/runner.rb
32
+ files:
33
+ - CHANGELOG
34
+ - Manifest
35
+ - README
36
+ - Rakefile
37
+ - bin/optimalcontrol
38
+ - lib/cgl/evaluate.rb
39
+ - lib/cgl/neighbors.rb
40
+ - lib/cgl/runner.rb
41
+ - test/test_evaluate.rb
42
+ - test/test_neighbors.rb
43
+ - test/test_runner.rb
44
+ - optimal-control.gemspec
45
+ has_rdoc: true
46
+ homepage: http://rubyforge.org/projects/optimal-control/
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --line-numbers
52
+ - --inline-source
53
+ - --title
54
+ - Optimal-control
55
+ - --main
56
+ - README
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "1.2"
70
+ version:
71
+ requirements: []
72
+
73
+ rubyforge_project: optimal-control
74
+ rubygems_version: 1.3.5
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: Simulate Conway's game of Life on a small grid with periodic boundary conditions and find the optimal controller for the specified control objective and control options
78
+ test_files:
79
+ - test/test_evaluate.rb
80
+ - test/test_neighbors.rb
81
+ - test/test_runner.rb