annealer 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +15 -0
  2. data/LICENSE +21 -0
  3. data/README.md +1 -0
  4. data/lib/annealer.rb +80 -0
  5. metadata +46 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OGE3NzQyNDk2MmM5NGRmNWY0NTdkZTg2OGRmYmFmNzZkMjM1OTNiOQ==
5
+ data.tar.gz: !binary |-
6
+ ZWVhNzgxNGRmZWViNTE1NTU0ZThhNTVmODQyZGUwNjMxZDMwMWUxZg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NWNmYTJkZWI3OGNkMDA3ZGY5Njg0Mjg2OTA0ZGYyMGFmYzAyYTBjM2VhYTVj
10
+ NTBhOGZhNGVjMzI3OTY0NmIyNmJhMGNlYWI2MjM4NGY5NzBkYzAyZmZhNjg0
11
+ MGU2OTEzYWE3NTRkODE5YmVkN2JjNzAwNmMzNTM2ZDZkZjMzNGE=
12
+ data.tar.gz: !binary |-
13
+ MmI3Mjk2MWMwNDVkYTA0MDgyMTgzOGU3NzY2M2FmMjJjMjIzYjI3MmRmZGRh
14
+ OTkwN2VmYmRiZDNiMjMxOTQ2ZDIxMTIyZmQ5N2ZjMjc4ZDUzZjIzNjc3NmYy
15
+ ZDg4YjZmYjc1NjljYzRlODdiNDNkZTc2MzJkMTc3YmQ2MTcxMzY=
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Paul Cantrell
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1 @@
1
+ Anneal before the might of Sutekh!
data/lib/annealer.rb ADDED
@@ -0,0 +1,80 @@
1
+ class Annealer
2
+ def initialize(opts = {})
3
+ max_iter = (opts[:max_iter] || 1000)
4
+
5
+ @cooling_func = opts[:cooling_func] || lambda do |iter_count|
6
+ Math.exp(iter_count / (opts[:cooling_time] || max_iter * 1000))
7
+ end
8
+
9
+ @transition_probability = opts[:transition_probability] || lambda do |e0, e1, temp|
10
+ Math.exp((e0 - e1) / temp)
11
+ end
12
+
13
+ @stop_condition = opts[:stop_condition] || lambda do |iter_count, best_energy|
14
+ iter_count > max_iter
15
+ end
16
+
17
+ @repetition_count = opts[:repetition_count] || 1
18
+
19
+ @logger = opts[:logger] || Class.new do
20
+ def initialize(log_to)
21
+ @log_to = log_to
22
+ end
23
+
24
+ def info(msg)
25
+ @log_to.puts(msg) if @log_to
26
+ end
27
+ end.new(opts[:log_to])
28
+
29
+ @log_progress_frequency = opts[:log_progress_frequency] || 5000
30
+ end
31
+
32
+ attr_accessor :logger
33
+
34
+ # Given a (probably random) starting state, returns a state that approximately minimizes
35
+ # an arbitrary "energy" metric.
36
+ #
37
+ # The given start_state must implement two methods:
38
+ #
39
+ # - *energy*: Returns the metric you want to optimize.
40
+ # - *random_neighbor*:
41
+ # Returns a randomly selected new state which differs slightly from this one.
42
+ # This method _must not modify_ the original state, but instead return a clean copy.
43
+ # You must ensure that the entire state space you want to search is reachable by hopping
44
+ # from neighbor to neighbor. Ideally, the new state should be likely to have similar energy
45
+ # (i.e. "neighbors" should be small changes); at the same time, you don't want it to require
46
+ # too many hops between any two states.
47
+ #
48
+ def anneal(start_state)
49
+ best_state = nil
50
+ best_energy = 1 / 0.0
51
+ energy = start_state.energy
52
+
53
+ @repetition_count.times do |rep|
54
+ logger.info "Repetition #{rep}..." if @repetition_count > 1
55
+ state = best_state || start_state
56
+
57
+ iter_count = 0
58
+ while !@stop_condition.call(iter_count, best_energy)
59
+ temperature = @cooling_func.call(iter_count)
60
+ new_state = state.random_neighbor
61
+ new_energy = new_state.energy
62
+ logger.info "Iteration #{iter_count} (energy = #{new_energy})..." if iter_count % @log_progress_frequency == 0
63
+
64
+ if best_state.nil? || @transition_probability.call(energy, new_energy, temperature) > rand
65
+ state, energy = new_state, new_energy
66
+ if new_energy < best_energy
67
+ best_state, best_energy = state, energy
68
+ logger.info "New best solution on rep #{rep}, iter #{iter_count} with energy #{energy}:"
69
+ logger.info state.inspect
70
+ end
71
+ end
72
+
73
+ iter_count += 1
74
+ end
75
+ end
76
+
77
+ best_state
78
+ end
79
+
80
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: annealer
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Paul Cantrell
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-16 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email: cantrell@pobox.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/annealer.rb
20
+ - README.md
21
+ - LICENSE
22
+ homepage: http://github.com/pcantrell/annealer
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ! '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.0.7
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: Simulated annealing framework
46
+ test_files: []