rsearch 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "rspec", "~> 2.3.0"
10
+ gem "bundler", "~> 1.0.0"
11
+ gem "jeweler", "~> 1.6.2"
12
+ gem "rcov", ">= 0"
13
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,28 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.2)
5
+ git (1.2.5)
6
+ jeweler (1.6.2)
7
+ bundler (~> 1.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ rake (0.9.2)
11
+ rcov (0.9.9)
12
+ rspec (2.3.0)
13
+ rspec-core (~> 2.3.0)
14
+ rspec-expectations (~> 2.3.0)
15
+ rspec-mocks (~> 2.3.0)
16
+ rspec-core (2.3.1)
17
+ rspec-expectations (2.3.0)
18
+ diff-lcs (~> 1.1.2)
19
+ rspec-mocks (2.3.0)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ bundler (~> 1.0.0)
26
+ jeweler (~> 1.6.2)
27
+ rcov
28
+ rspec (~> 2.3.0)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Serguei Filimonov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,19 @@
1
+ = rsearch
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to rsearch
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
+ * Fork the project
10
+ * Start a feature/bugfix branch
11
+ * Commit and push until you are happy with your contribution
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2011 Serguei Filimonov. See LICENSE.txt for
18
+ further details.
19
+
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "rsearch"
18
+ gem.homepage = "http://github.com/sergueif/rsearch"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{one-line summary of your gem}
21
+ gem.description = %Q{longer description of your gem}
22
+ gem.email = "serguei.filimonov@gmail.com"
23
+ gem.authors = ["Serguei Filimonov"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ task :default => :spec
40
+
41
+ require 'rake/rdoctask'
42
+ Rake::RDocTask.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "rsearch #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
@@ -0,0 +1,27 @@
1
+ require 'set'
2
+ require File.dirname(__FILE__) + '/search'
3
+
4
+ class BFS
5
+ def initialize(options)
6
+ queue = []
7
+ marked = Set.new
8
+ marked << options[:start]
9
+ scheduler = Proc.new do |states|
10
+ states.each do |state|
11
+ if !marked.include?(state)
12
+ queue << state
13
+ marked << state
14
+ end
15
+ end
16
+ queue.shift
17
+ end
18
+
19
+ @search = Search.new(start: options[:start],
20
+ generator: options[:generator],
21
+ scheduler: scheduler)
22
+ end
23
+
24
+ def method_missing(meth, *args, &block)
25
+ @search.send(meth, *args, &block)
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ require 'set'
2
+ require File.dirname(__FILE__) + '/search'
3
+
4
+ class DFS
5
+ def initialize(options)
6
+
7
+ stack = []
8
+ marked = Set.new
9
+ marked << options[:start]
10
+
11
+ scheduler = Proc.new do |states|
12
+ states.reverse.each do |state|
13
+ stack << state if !marked.include?(state)
14
+ marked << state
15
+ end
16
+ stack.pop
17
+ end
18
+
19
+ @search = Search.new(start: options[:start],
20
+ generator: options[:generator],
21
+ scheduler: scheduler)
22
+ end
23
+
24
+ def method_missing(meth, *args, &block)
25
+ @search.send(meth, *args, &block)
26
+ end
27
+ end
@@ -0,0 +1,57 @@
1
+ require 'set'
2
+
3
+ class Search
4
+ attr_reader :iterations, :current_state
5
+
6
+ #Search object is initialized with a start node, a generator function that expands
7
+ #neighbours of the node, and scheduler that chooses which neighbour to expand next
8
+ def initialize(options)
9
+ @start = options[:start]
10
+ @generator = options[:generator]
11
+ @scheduler = options[:scheduler]
12
+ @iterations = 0 #keep track of iterations executed
13
+ @current_state = @start #set start as current state of the search
14
+ @child_to_parent = {} #parent tree to find paths
15
+ @parents = Set.new #keep track of parents to prevent back-edges in the parent tree
16
+ end
17
+
18
+
19
+ #performs an iteration of a search, expanding the current node in the search tree
20
+ #and scheduling neighbours, as well as keep track of paths and iterations
21
+ def run
22
+ raise "dead end" if @current_state.nil?
23
+ @iterations += 1
24
+
25
+ new_states = @generator.call(@current_state)
26
+ @parents << @current_state if new_states.any?
27
+ new_states.each do |new_state|
28
+ if !@parents.include?(new_state) && #prevent back-edges
29
+ !@child_to_parent[new_state] #respect expansion order in the path
30
+ @child_to_parent[new_state] = @current_state
31
+ end
32
+ end
33
+ next_state = @scheduler.call(new_states)
34
+ @current_state = next_state
35
+ end
36
+
37
+ #returns the path to the current node from the start
38
+ def path
39
+ path_to(@current_state)
40
+ end
41
+
42
+ #how far is the search right now from the start
43
+ def distance
44
+ path.size - 1
45
+ end
46
+
47
+ private
48
+
49
+ def path_to(node)
50
+ anc = [node]
51
+ while @child_to_parent[node]
52
+ anc << @child_to_parent[node]
53
+ node = @child_to_parent[node]
54
+ end
55
+ anc.reverse
56
+ end
57
+ end
@@ -0,0 +1,23 @@
1
+ #this class maintains a tabu list and kicks elements out if they are too old
2
+ class Tabu
3
+
4
+ def initialize(size)
5
+ @hash = {}
6
+ @max = size
7
+ end
8
+
9
+ #decrease longevity of all keys and insert new one
10
+ def insert(elem)
11
+ @hash.each_key do |key|
12
+ @hash[key] -= 1
13
+ if @hash[key] <= 0
14
+ @hash.delete(key)
15
+ end
16
+ end
17
+ @hash[elem] = @max
18
+ end
19
+
20
+ def include?(elem)
21
+ !@hash[elem].nil?
22
+ end
23
+ end
data/lib/rsearch.rb ADDED
@@ -0,0 +1,2 @@
1
+ Dir[File.dirname(__FILE__) + "/**/*.rb"].each { |file| require file }
2
+
data/rsearch.gemspec ADDED
@@ -0,0 +1,69 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{rsearch}
8
+ s.version = "0.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Serguei Filimonov"]
12
+ s.date = %q{2011-06-12}
13
+ s.description = %q{longer description of your gem}
14
+ s.email = %q{serguei.filimonov@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE.txt",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "lib/rsearch.rb",
29
+ "lib/rsearch/bfs.rb",
30
+ "lib/rsearch/dfs.rb",
31
+ "lib/rsearch/search.rb",
32
+ "lib/rsearch/tabu.rb",
33
+ "rsearch.gemspec",
34
+ "spec/bfs_spec.rb",
35
+ "spec/dfs_spec.rb",
36
+ "spec/rsearch_spec.rb",
37
+ "spec/search_spec.rb",
38
+ "spec/searcher_spec.rb",
39
+ "spec/spec_helper.rb",
40
+ "spec/tabu_spec.rb"
41
+ ]
42
+ s.homepage = %q{http://github.com/sergueif/rsearch}
43
+ s.licenses = ["MIT"]
44
+ s.require_paths = ["lib"]
45
+ s.rubygems_version = %q{1.6.2}
46
+ s.summary = %q{one-line summary of your gem}
47
+
48
+ if s.respond_to? :specification_version then
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
52
+ s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
53
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
54
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.2"])
55
+ s.add_development_dependency(%q<rcov>, [">= 0"])
56
+ else
57
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
58
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
59
+ s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
60
+ s.add_dependency(%q<rcov>, [">= 0"])
61
+ end
62
+ else
63
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
64
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
65
+ s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
66
+ s.add_dependency(%q<rcov>, [">= 0"])
67
+ end
68
+ end
69
+
data/spec/bfs_spec.rb ADDED
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe BFS do
4
+ it "works" do
5
+ start = 1
6
+ generator = Proc.new do |state|
7
+ new_states = if state.abs < 5
8
+ [state+2,state-1]
9
+ else
10
+ []
11
+ end
12
+ new_states
13
+ end
14
+ @search = BFS.new(:start => start, :generator => generator)
15
+ @search.run
16
+ @search.path.should == [1,3]
17
+ @search.run
18
+ @search.path.should == [1,0]
19
+ @search.run
20
+ @search.path.should == [1,3,5]
21
+ @search.run
22
+ @search.path.should == [1,3,2]
23
+ @search.run
24
+ @search.path.should == [1,0,-1]
25
+ @search.run
26
+ @search.path.should == [1,3,2,4]
27
+ @search.run
28
+ @search.path.should == [1,0,-1,-2]
29
+ @search.run
30
+ @search.path.should == [1,3,2,4,6]
31
+ @search.run
32
+ @search.path.should == [1,0,-1,-2,-3]
33
+ end
34
+ end
data/spec/dfs_spec.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe DFS do
4
+ it "works" do
5
+ start = 1
6
+ generator = Proc.new do |state|
7
+ new_states = if state.abs < 5
8
+ [state+2,state-1]
9
+ else
10
+ []
11
+ end
12
+ new_states
13
+ end
14
+ @search = DFS.new(:start => start, :generator => generator)
15
+ @search.run
16
+ @search.path.should == [1,3]
17
+ @search.run
18
+ @search.path.should == [1,3,5]
19
+ @search.run
20
+ @search.path.should == [1,3,2]
21
+ @search.run
22
+ @search.path.should == [1,3,2,4]
23
+ @search.run
24
+ @search.path.should == [1,3,2,4,6]
25
+ @search.run
26
+ @search.path.should == [1,0]
27
+ @search.run
28
+ @search.path.should == [1,0,-1]
29
+ @search.run
30
+ @search.path.should == [1,0,-1,-2]
31
+ end
32
+ end
@@ -0,0 +1 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe Search do
4
+ before do
5
+ @search = Search.new(start: nil, generator: nil, scheduler: nil)
6
+ end
7
+
8
+ it "is an object" do
9
+ @search.should be
10
+ end
11
+
12
+ describe "run" do
13
+ it "executes the callback with start node on first iteration" do
14
+ generator = Proc.new do |state|
15
+ [state+1]
16
+ end
17
+ scheduler = Proc.new{|states| states.first}
18
+ generator.should_receive(:call).with(0).and_return([1])
19
+ @search = Search.new(start: 0, generator: generator, scheduler: scheduler)
20
+ @search.iterations.should == 0
21
+ @search.run
22
+ @search.iterations.should == 1
23
+ end
24
+ it "maintains a current state" do
25
+ generator = Proc.new do |state|
26
+ [state+1]
27
+ end
28
+ scheduler = Proc.new{|states| states.first}
29
+ @search = Search.new(start: 0, generator: generator, scheduler: scheduler)
30
+ @search.current_state.should == 0
31
+ @search.run
32
+ @search.current_state.should == 1
33
+ end
34
+ it "maintains a parent tree state" do
35
+ generator = Proc.new do |state|
36
+ [state+1]
37
+ end
38
+ scheduler = Proc.new{|states| states.first}
39
+ @search = Search.new(start: 0, generator: generator, scheduler: scheduler)
40
+ @search.run
41
+ @search.path.should == [0,1]
42
+ @search.distance.should == 1
43
+ @search.run
44
+ @search.path.should == [0,1,2]
45
+ @search.distance.should == 2
46
+ end
47
+ end
48
+ end
@@ -0,0 +1 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'rsearch'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
data/spec/tabu_spec.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tabu do
4
+ it "works" do
5
+ t = Tabu.new(2)
6
+ t.insert(1)
7
+ t.include?(1).should be_true
8
+ t.insert(2)
9
+ t.include?(2).should be_true
10
+ t.insert(3)
11
+ t.include?(3).should be_true
12
+ t.include?(1).should be_false
13
+ t.insert(2)
14
+ t.include?(2).should be_true
15
+ t.include?(3).should be_true
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rsearch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Serguei Filimonov
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-06-12 00:00:00.000000000 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ requirement: &71325450 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 2.3.0
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: *71325450
26
+ - !ruby/object:Gem::Dependency
27
+ name: bundler
28
+ requirement: &71324900 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *71324900
37
+ - !ruby/object:Gem::Dependency
38
+ name: jeweler
39
+ requirement: &71324440 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: 1.6.2
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *71324440
48
+ - !ruby/object:Gem::Dependency
49
+ name: rcov
50
+ requirement: &71324030 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *71324030
59
+ description: longer description of your gem
60
+ email: serguei.filimonov@gmail.com
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files:
64
+ - LICENSE.txt
65
+ - README.rdoc
66
+ files:
67
+ - .document
68
+ - .rspec
69
+ - Gemfile
70
+ - Gemfile.lock
71
+ - LICENSE.txt
72
+ - README.rdoc
73
+ - Rakefile
74
+ - VERSION
75
+ - lib/rsearch.rb
76
+ - lib/rsearch/bfs.rb
77
+ - lib/rsearch/dfs.rb
78
+ - lib/rsearch/search.rb
79
+ - lib/rsearch/tabu.rb
80
+ - rsearch.gemspec
81
+ - spec/bfs_spec.rb
82
+ - spec/dfs_spec.rb
83
+ - spec/rsearch_spec.rb
84
+ - spec/search_spec.rb
85
+ - spec/searcher_spec.rb
86
+ - spec/spec_helper.rb
87
+ - spec/tabu_spec.rb
88
+ has_rdoc: true
89
+ homepage: http://github.com/sergueif/rsearch
90
+ licenses:
91
+ - MIT
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ segments:
103
+ - 0
104
+ hash: -63201453
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 1.6.2
114
+ signing_key:
115
+ specification_version: 3
116
+ summary: one-line summary of your gem
117
+ test_files: []