ant_colony 0.0.5
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.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.rubocop.yml +15 -0
- data/Gemfile +3 -0
- data/README.md +34 -0
- data/Rakefile +1 -0
- data/ant_colony.gemspec +28 -0
- data/bin/ant_colony +6 -0
- data/lib/ant_colony.rb +73 -0
- data/lib/ant_colony/cli.rb +22 -0
- data/lib/ant_colony/version.rb +3 -0
- data/spec/ant_colony_spec.rb +19 -0
- data/spec/spec_helper.rb +8 -0
- data/test_data/test1.yml +67 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4e82b81f4994e2ae805fcfb1d9b4b87cf3d2c883
|
4
|
+
data.tar.gz: 11e0093725cb8e441de603d1eb2b1d4a91f28998
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 23329bc7493d7d379cf6bff80b9ef12aa3465c3c4390dc852b03a0715e377db11e7d56d4b450bc3839304621dd8f08b2ea925536047710d8eb9a2a56f893b937
|
7
|
+
data.tar.gz: 350da0960564030351d9cae8e0d88c7cd50f2587460c6ae3c2de5d2c3d8b59e7080623c2b0eae48dee0ac8c1378e07963af0252f1f7510ed9b2f60e46d3f907b
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# AntColony
|
2
|
+
|
3
|
+
Simple implementation ant colony optimization algorithm
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'ant_colony'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install ant_colony
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
```ruby
|
23
|
+
graph = YAML.load_file('test_data/test1.yml')
|
24
|
+
colony = AntColony::Colony.new(graph, beta: 0.8, alpha: 0.7, pop: 200, ph: 0.3, q: 5)
|
25
|
+
colony.solve
|
26
|
+
colony.find_path 1 # path from point 1
|
27
|
+
```
|
28
|
+
## Contributing
|
29
|
+
|
30
|
+
1. Fork it ( https://github.com/[my-github-username]/ant_colony/fork )
|
31
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
32
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
33
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
34
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/ant_colony.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ant_colony/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'ant_colony'
|
8
|
+
spec.version = AntColony::VERSION
|
9
|
+
spec.date = '2016-03-05'
|
10
|
+
spec.authors = ['Alexandr Turchyn', 'Pete Matsyburka']
|
11
|
+
spec.email = %w(lexfox777@gmail.com pete.matsy@gmail.com)
|
12
|
+
spec.summary = 'Ant colony optimization algorithms.'
|
13
|
+
spec.description = 'Simple implementation ant colony optimization algorithm.'
|
14
|
+
spec.homepage = 'https://github.com/AlexandrToorchyn/AntColony'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = %w(lib)
|
21
|
+
|
22
|
+
spec.add_development_dependency 'rspec', '~> 3.4.0'
|
23
|
+
spec.add_development_dependency 'rubocop'
|
24
|
+
|
25
|
+
spec.add_dependency 'bundler', '~> 1.7'
|
26
|
+
spec.add_dependency 'rake', '~> 10.0'
|
27
|
+
spec.add_dependency 'thor'
|
28
|
+
end
|
data/bin/ant_colony
ADDED
data/lib/ant_colony.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require_relative 'ant_colony/version'
|
2
|
+
|
3
|
+
module AntColony
|
4
|
+
class Colony
|
5
|
+
DEFAULT_PHERO = 0.5
|
6
|
+
|
7
|
+
attr_reader :alpha, :beta, :ph, :q, :graph, :pop
|
8
|
+
|
9
|
+
def initialize(graph, alpha: 0.8, beta: 0.4, ph: 0.3, q: 500, pop: 200)
|
10
|
+
method(__method__).parameters.each do |_, name|
|
11
|
+
instance_variable_set(:"@#{name}", binding.local_variable_get(name))
|
12
|
+
end
|
13
|
+
set_default_tau
|
14
|
+
end
|
15
|
+
|
16
|
+
def find_path(*roadmap)
|
17
|
+
loop do
|
18
|
+
city = graph[roadmap.last] # current point(city) ant located
|
19
|
+
|
20
|
+
sum_paths = city.reduce(0.0) do |sum, (_, path)|
|
21
|
+
sum + (path[:tau]**alpha).to_f / (path[:length]**beta)
|
22
|
+
end
|
23
|
+
|
24
|
+
proposed_paths = city.each_with_object({}) do |(direction, path), paths|
|
25
|
+
unless roadmap.include? direction
|
26
|
+
paths[direction] = (((path[:tau]**alpha).to_f / path[:length])**beta) / sum_paths
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
roadmap << best_path_of(proposed_paths)
|
31
|
+
break unless roadmap.length < graph.size
|
32
|
+
end
|
33
|
+
|
34
|
+
roadmap
|
35
|
+
end
|
36
|
+
|
37
|
+
def solve
|
38
|
+
graph.size.times do |i|
|
39
|
+
pop.times do
|
40
|
+
path = find_path(i + 1)
|
41
|
+
increase_tau_for path
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def length_of(path)
|
47
|
+
[*path, path.first].each_cons(2).reduce(0.0) do |sum, (cur, nxt)|
|
48
|
+
sum + graph[cur][nxt][:length]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def set_default_tau
|
55
|
+
graph.each do |_, roads|
|
56
|
+
roads.each do |_, props|
|
57
|
+
props[:tau] = DEFAULT_PHERO
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def best_path_of(paths)
|
63
|
+
paths.max_by { |_, v| v }.first
|
64
|
+
end
|
65
|
+
|
66
|
+
def increase_tau_for(path)
|
67
|
+
[*path, path.first].each_cons(2) do |cur, nxt|
|
68
|
+
tau_next = (1.0 - ph) * graph[cur][nxt][:tau] + q.to_f / length_of(path)
|
69
|
+
graph[cur][nxt][:tau] = graph[nxt][cur][:tau] = tau_next
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module AntColony
|
5
|
+
class CLI < Thor
|
6
|
+
desc 'solve [FILE_NAME, START_POINT]', 'find the shortest path for graph from start point'
|
7
|
+
|
8
|
+
option :alpha, type: :numeric, desc: 'alpha param'
|
9
|
+
option :beta, type: :numeric, desc: 'beta param'
|
10
|
+
option :ph, type: :numeric, desc: 'pheromone constant'
|
11
|
+
option :q, type: :numeric, desc: 'Q'
|
12
|
+
option :pop, type: :numeric, desc: 'number of ants'
|
13
|
+
|
14
|
+
def solve(file, point)
|
15
|
+
params = options.map { |k, v| [k.to_sym, v] }.to_h
|
16
|
+
graph = YAML.load_file(file)
|
17
|
+
colony = AntColony::Colony.new(graph, **params)
|
18
|
+
colony.solve
|
19
|
+
$stdout.puts colony.find_path(point.to_i)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
describe AntColony::Colony do
|
5
|
+
let(:graph) { YAML.load_file('test_data/test1.yml') }
|
6
|
+
let(:colony) { AntColony::Colony.new(graph, pop: 100) }
|
7
|
+
|
8
|
+
before { colony.solve }
|
9
|
+
|
10
|
+
it 'should find the shortest way' do
|
11
|
+
paths = graph.keys.permutation.map do |path|
|
12
|
+
[path.to_s, colony.length_of(path)]
|
13
|
+
end
|
14
|
+
shortest_length = paths.min_by { |_, v| v }.last
|
15
|
+
shortest_paths = paths.select { |_, v| v == shortest_length }
|
16
|
+
|
17
|
+
expect(shortest_paths.map(&:first)).to include colony.find_path(1).to_s
|
18
|
+
end
|
19
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/test_data/test1.yml
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
---
|
2
|
+
1:
|
3
|
+
2:
|
4
|
+
:length: 26
|
5
|
+
3:
|
6
|
+
:length: 42
|
7
|
+
4:
|
8
|
+
:length: 15
|
9
|
+
5:
|
10
|
+
:length: 29
|
11
|
+
6:
|
12
|
+
:length: 25
|
13
|
+
2:
|
14
|
+
1:
|
15
|
+
:length: 26
|
16
|
+
3:
|
17
|
+
:length: 16
|
18
|
+
4:
|
19
|
+
:length: 1
|
20
|
+
5:
|
21
|
+
:length: 30
|
22
|
+
6:
|
23
|
+
:length: 8
|
24
|
+
3:
|
25
|
+
1:
|
26
|
+
:length: 42
|
27
|
+
2:
|
28
|
+
:length: 16
|
29
|
+
4:
|
30
|
+
:length: 35
|
31
|
+
5:
|
32
|
+
:length: 5
|
33
|
+
6:
|
34
|
+
:length: 1
|
35
|
+
4:
|
36
|
+
1:
|
37
|
+
:length: 15
|
38
|
+
2:
|
39
|
+
:length: 1
|
40
|
+
3:
|
41
|
+
:length: 35
|
42
|
+
5:
|
43
|
+
:length: 18
|
44
|
+
6:
|
45
|
+
:length: 18
|
46
|
+
5:
|
47
|
+
1:
|
48
|
+
:length: 29
|
49
|
+
2:
|
50
|
+
:length: 30
|
51
|
+
3:
|
52
|
+
:length: 5
|
53
|
+
4:
|
54
|
+
:length: 18
|
55
|
+
6:
|
56
|
+
:length: 5
|
57
|
+
6:
|
58
|
+
1:
|
59
|
+
:length: 25
|
60
|
+
2:
|
61
|
+
:length: 8
|
62
|
+
3:
|
63
|
+
:length: 1
|
64
|
+
4:
|
65
|
+
:length: 18
|
66
|
+
5:
|
67
|
+
:length: 5
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ant_colony
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexandr Turchyn
|
8
|
+
- Pete Matsyburka
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2016-03-05 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 3.4.0
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 3.4.0
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rubocop
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: bundler
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '1.7'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '1.7'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rake
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '10.0'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '10.0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: thor
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
description: Simple implementation ant colony optimization algorithm.
|
85
|
+
email:
|
86
|
+
- lexfox777@gmail.com
|
87
|
+
- pete.matsy@gmail.com
|
88
|
+
executables:
|
89
|
+
- ant_colony
|
90
|
+
extensions: []
|
91
|
+
extra_rdoc_files: []
|
92
|
+
files:
|
93
|
+
- ".gitignore"
|
94
|
+
- ".rubocop.yml"
|
95
|
+
- Gemfile
|
96
|
+
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- ant_colony.gemspec
|
99
|
+
- bin/ant_colony
|
100
|
+
- lib/ant_colony.rb
|
101
|
+
- lib/ant_colony/cli.rb
|
102
|
+
- lib/ant_colony/version.rb
|
103
|
+
- spec/ant_colony_spec.rb
|
104
|
+
- spec/spec_helper.rb
|
105
|
+
- test_data/test1.yml
|
106
|
+
homepage: https://github.com/AlexandrToorchyn/AntColony
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.5.1
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: Ant colony optimization algorithms.
|
130
|
+
test_files:
|
131
|
+
- spec/ant_colony_spec.rb
|
132
|
+
- spec/spec_helper.rb
|
133
|
+
has_rdoc:
|