opt_alg_framework 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NTBlMTIwMTFlNmJhY2Q4YmEzYTdiNDdmYjA4NTgxOGM4NzlhNTI3NA==
5
+ data.tar.gz: !binary |-
6
+ ZmUwM2I2ZjM1YjBhNzY0YjBlOTNmYWVhM2JlY2Q5YTkyOTcwMGY1NA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NWUwZjdjYjFkZDgwYTI4ZDM5NTUxNWVkZjZkNzRmMjE2OTc2ZTZhMjg3ZjY5
10
+ Y2NlNmRiYzdlNWIxYTc1MDBiMWEzODNmNzljYmU2Nzc1NDAwNTkwNWE4YTk1
11
+ MTE3ODY4YmQwYWJiM2NjMzc0OGJmYThmZTUyMDdmMzNlNmQ0NmI=
12
+ data.tar.gz: !binary |-
13
+ MDcwNmEzZDQ2NDFlN2NlMGFkMTAxYTllMDdlYjYzOWRiODU5MjY5MGEyM2Jh
14
+ NDAzZWZjYTQxZThhN2Y3YWIyNmQwMmNmOThmZWU5ODUzNDEzYWE0ODRmNTM1
15
+ NDQ0MzhlNGJkMDc4OTE1OTAyZjBlNWRmM2IwYTI1MmY0NjI1NmM=
data/.gitignore ADDED
@@ -0,0 +1,62 @@
1
+ <<<<<<< HEAD
2
+ /.bundle/
3
+ /.yardoc
4
+ /Gemfile.lock
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
11
+ =======
12
+ *.gem
13
+ *.rbc
14
+ /.config
15
+ /coverage/
16
+ /InstalledFiles
17
+ /pkg/
18
+ /spec/reports/
19
+ /spec/examples.txt
20
+ /test/tmp/
21
+ /test/version_tmp/
22
+ /tmp/
23
+
24
+ # Used by dotenv library to load environment variables.
25
+ # .env
26
+
27
+ ## Specific to RubyMotion:
28
+ .dat*
29
+ .repl_history
30
+ build/
31
+ *.bridgesupport
32
+ build-iPhoneOS/
33
+ build-iPhoneSimulator/
34
+
35
+ ## Specific to RubyMotion (use of CocoaPods):
36
+ #
37
+ # We recommend against adding the Pods directory to your .gitignore. However
38
+ # you should judge for yourself, the pros and cons are mentioned at:
39
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
40
+ #
41
+ # vendor/Pods/
42
+
43
+ ## Documentation cache and generated files:
44
+ /.yardoc/
45
+ /_yardoc/
46
+ /doc/
47
+ /rdoc/
48
+
49
+ ## Environment normalization:
50
+ /.bundle/
51
+ /vendor/bundle
52
+ /lib/bundler/man/
53
+
54
+ # for a library or gem, you might want to ignore these files since the code is
55
+ # intended to run in multiple environments; otherwise, check them in:
56
+ # Gemfile.lock
57
+ # .ruby-version
58
+ # .ruby-gemset
59
+
60
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
61
+ .rvmrc
62
+ >>>>>>> a7821ff49db723ae966f50a7686a6e443d19b148
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in opt_alg_framework.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Rodrigo W. Ehresmann
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,86 @@
1
+ # OptAlgFramework
2
+
3
+ Opt-Alg-Framework is a framework to work and build optimization algorithm. The basic idea is: you will have a codificated problem with a method to calculate its fitnes, an algorithm to improve the this fitness and operators used with the algorithm to build new solutions.
4
+
5
+ What is already implemented:
6
+
7
+ * Problems:
8
+ * Flow Shop Permutation
9
+
10
+ * Algorithms:
11
+ * Local Searches:
12
+ * Hill-Climbing
13
+ * Simulated Annealing
14
+ * Tabu Search
15
+
16
+ * Operators
17
+ * Crossover:
18
+ * Two Point Crossover (permutational)
19
+ * Selector:
20
+ * Tournament Selection
21
+ * Tweak:
22
+ * Random Swap
23
+
24
+ ## Installation
25
+
26
+ Add this line to your application's Gemfile:
27
+
28
+ ```ruby
29
+ gem 'opt_alg_framework'
30
+ ```
31
+
32
+ And then execute:
33
+
34
+ $ bundle
35
+
36
+ Or install it yourself as:
37
+
38
+ $ gem install opt_alg_framework
39
+
40
+ ## Usage
41
+
42
+ Example: read two instances of FSP problem (about the instances format, read README in *problem* directory!) and get its best results with Simulated Annealing algorithm, using RandomSwap operator.
43
+
44
+ ```ruby
45
+ operator = Operator::Tweak::RandomSwap.new
46
+ problem = Problem::FSP.new
47
+ problem.load_schedule(path)
48
+ algorithm = Algorithm::LocalSearch::SimulatedAnnealing.new max_iterations: 10,
49
+ cooling_rate: 0.009,
50
+ problem: problem,
51
+ tweak_operator: operator
52
+
53
+ puts algorithm.start[:fitness]
54
+ ```
55
+
56
+ ## Development
57
+
58
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` or, alternatively, `bundle console` for an interactive prompt that will allow you to experiment.
59
+
60
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
61
+
62
+ ####Some conventions must be followed:
63
+
64
+ * All problem classes need to have its fitness method acessible with the name *fitness*;
65
+ * All swap operator classes need to have its swap method acessible with the name *tweak*;
66
+ * All crossover operator classes need to have its crossover method named *cross*;
67
+ * All selector operator classes need to have its selection method names *select*;
68
+ * All algorithm classes need to have its main method names *start*;
69
+ * In the algorithms, a solution is represent with a hash structure, and it's mandatory have at least the pair key-value *:solution* with the representation of the solution and *:fitness* with the fitness of the solution.
70
+
71
+ ####TODO:
72
+
73
+ * Treatments to verify if the conventions are being followed;
74
+ * General implementations, like:
75
+ * Local search algorithms;
76
+ * Population based algorithms;
77
+ * Operators (crossover, swap, selector) to any type of problem (permutational, binary, etc);
78
+ * Different type of problems.
79
+
80
+ ## Contributing
81
+
82
+ 1. Fork it ( https://github.com/[my-github-username]/opt_alg_framework/fork )
83
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
84
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
85
+ 4. Push to the branch (`git push origin my-new-feature`)
86
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "opt_alg_framework"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,34 @@
1
+ module Algorithm
2
+ module LocalSearch
3
+ class HillClimbing
4
+ # Initialize passing a instantiated class of a problem and tweak operator
5
+ def initialize(params)
6
+ @tweak_operator = params[:tweak_operator]
7
+ @problem = params[:problem]
8
+ end
9
+
10
+ # Main method
11
+ def start
12
+ best = encapsulate_solution(@problem.default_solution)
13
+ while true do
14
+ r = encapsulate_solution(@tweak_operator.tweak(best[:solution]))
15
+ if r[:fitness] < best[:fitness]
16
+ best = r.dup
17
+ else
18
+ break
19
+ end
20
+ end
21
+ best
22
+ end
23
+
24
+ # Solution is a hash, with the keys :solution and :fitness
25
+ def encapsulate_solution(solution)
26
+ hash = Hash.new
27
+ hash[:solution] = solution
28
+ hash[:fitness] = @problem.fitness(tasks_sequence: solution)
29
+ hash
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,71 @@
1
+ module Algorithm
2
+ module LocalSearch
3
+ class SimulatedAnnealing
4
+ include Math
5
+ attr_reader :temperature
6
+
7
+ # Initialize specifying the cooling rate percentage (@cooling_rate), number of iterations in each
8
+ # temperature (@max_iterations) and passing an instantiated problem and tweak operator class.
9
+ def initialize(params)
10
+ @cooling_rate = params[:cooling_rate]
11
+ @problem = params[:problem]
12
+ @tweak_operator = params[:tweak_operator]
13
+ @max_iterations = params[:max_iterations]
14
+ @temperature = initial_temperature
15
+ end
16
+
17
+ # Main method.
18
+ def start
19
+ best = encapsulate_solution(@problem.default_solution.shuffle)
20
+ current = best.dup
21
+ temperature = @temperature
22
+ while temperature > 1 do
23
+ iteration = 1
24
+ while iteration < @max_iterations do
25
+ neighbor = encapsulate_solution(@tweak_operator.tweak(current[:solution]))
26
+ current = neighbor.dup if accept?(current[:fitness], neighbor[:fitness], temperature)
27
+ best = current.dup if current[:fitness] < best[:fitness]
28
+ iteration += 1
29
+ end
30
+ temperature *= 1 - @cooling_rate
31
+ end
32
+ best
33
+ end
34
+
35
+ private
36
+
37
+ # Calculate the initial temperature, generating N neighbors of an initial solution and
38
+ # setting as initial temperature the neighbor with the worst fitness.
39
+ def initial_temperature
40
+ solution = encapsulate_solution(@problem.default_solution.shuffle)
41
+ max = solution
42
+ @max_iterations.times do
43
+ neighbor = encapsulate_solution(@tweak_operator.tweak(solution[:solution]))
44
+ max = neighbor if neighbor[:fitness] > max[:fitness]
45
+ end
46
+ max[:fitness]
47
+ end
48
+
49
+ # A solution is a hash, with the keys :solution and :fitness.
50
+ def encapsulate_solution(solution)
51
+ hash = Hash.new
52
+ hash[:solution] = solution
53
+ hash[:fitness] = @problem.fitness(tasks_sequence: solution)
54
+ hash
55
+ end
56
+
57
+ # Calculate the acceptance probability, if and only if the neighbor fitness is worst than
58
+ # the current fitness.
59
+ def accept?(fitness, neighbor_fitness, temperature)
60
+ return true if neighbor_fitness < fitness
61
+ probability = E ** - ((fitness - neighbor_fitness).abs.fdiv(temperature)) # E is the Euller number
62
+ r = Random.rand(0.0..1)
63
+ if r < probability
64
+ return true
65
+ else
66
+ false
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,47 @@
1
+ module Algorithm
2
+ module LocalSearch
3
+ class TabuSearch
4
+
5
+ # Initialize specifying as parameters the tabu list size (@list_max_size), number of tweaks in each
6
+ # current solution (@tweak_number), number of iteratiions to perform in the algorithm (@iterations)
7
+ # and an instantiated problem and tweak operator class.
8
+ def initialize(params)
9
+ @tabu_list = []
10
+ @list_max_size = params[:list_max_size]
11
+ @tweak_number = params[:tweak_number]
12
+ @iterations = params[:iterations]
13
+ @tweak_operator = params[:tweak_operator]
14
+ @problem = params[:problem]
15
+ end
16
+
17
+ # Main method.
18
+ def start
19
+ s = encapsulate_solution(@problem.default_solution.dup)
20
+ best = s.dup
21
+ @tabu_list << s[:solution]
22
+ @iterations.times do
23
+ @tabu_list.shift if @tabu_list.size == @list_max_size
24
+ r = encapsulate_solution(@tweak_operator.tweak(s[:solution]))
25
+ (@tweak_number - 1).times do
26
+ w = encapsulate_solution(@tweak_operator.tweak(s[:solution]))
27
+ r = w.dup if !@tabu_list.include?(w) && w[:fitness] < r[:fitness] || @tabu_list.include?(r[:solution])
28
+ end
29
+ if !@tabu_list.include?(r[:solution])
30
+ s = r.dup
31
+ @tabu_list << r
32
+ end
33
+ best = s.dup if s[:fitness] < best[:fitness]
34
+ end
35
+ best
36
+ end
37
+
38
+ # A solution is a hash, with the keys :solution and :fitness.
39
+ def encapsulate_solution(solution)
40
+ hash = Hash.new
41
+ hash[:solution] = solution
42
+ hash[:fitness] = @problem.fitness(tasks_sequence: solution)
43
+ hash
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,33 @@
1
+ module Operator
2
+ module Crossover
3
+ module Permutation
4
+
5
+ class TwoPointCrossover
6
+ # Main method.
7
+ def cross(chromossome1, chromossome2)
8
+ point1 = Random.rand(0..chromossome1.size - 1)
9
+ point2 = Random.rand(point1..chromossome1.size - 1)
10
+ start_piece = Array.new
11
+ middle_piece = Array.new
12
+ end_piece = Array.new
13
+
14
+ point1.upto(point2) do |i| # Get the middle of the chromossome1, between the two points
15
+ middle_piece << chromossome1[i]
16
+ end
17
+ # After the tasks of the middle are choosed, there is no need of them in the chromossomes anymore
18
+ chromossome1 -= middle_piece
19
+ chromossome2 -= middle_piece
20
+ chromossome2.size.times do |i| # Loop to check the order of the remaining genes in the chromossome2
21
+ if start_piece.size <= point1 # Check if the chromossomes will be placed before or after the "middle" point
22
+ start_piece << chromossome1[i]
23
+ else
24
+ end_piece << chromossome1[i]
25
+ end
26
+ end
27
+ start_piece + middle_piece + end_piece
28
+ end
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,22 @@
1
+ module Operator
2
+ module Selector
3
+
4
+ class TournamentSelection
5
+ # Initialize informing the tournament size.
6
+ def initialize(size)
7
+ @size = size
8
+ end
9
+
10
+ # Main method.
11
+ def select(population)
12
+ best_individual = population[Random.rand(0...population.size)]
13
+ 0.upto(@size) do
14
+ individual = population[Random.rand(0...population.size)]
15
+ best_individual = individual if individual[:fitness] < best_individual[:fitness]
16
+ end
17
+ best_individual
18
+ end
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ module Operator
2
+ module Tweak
3
+
4
+ class RandomSwap
5
+ # Main method.
6
+ def tweak(solution)
7
+ copy = solution.dup
8
+ piece1 = Random.rand(0...copy.size)
9
+ piece2 = Random.rand(0...copy.size)
10
+ x = copy[piece1]
11
+ copy[piece1] = copy[piece2]
12
+ copy[piece2] = x
13
+ copy
14
+ end
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ # About the instaces of the problems
2
+
3
+ ## FSP (Flow Shop Permutation)
4
+ The instance of this kind of problem is a matrix, specifically a matrix where the rows are tasks and columns are machines. The fitness method need that to work properly.
5
+
6
+ A valid instance example is shown bellow, with 5 tasks (lines) and 3 machines (columns):
7
+
8
+ > 12 65 23 <br>
9
+ > 45 25 12 <br>
10
+ > 17 32 56 <br>
11
+ > 33 21 22 <br>
12
+ > 10 9 11 <br>
13
+
14
+ However, if your instance file is an inverted matrix (rows are machines and columns are tasks), just set the *transpose* parameter of *load_schedule* method to *true*:
15
+
16
+ ```ruby
17
+ fsp.load_schedule(path_to_instance, true)
18
+ ```
19
+
20
+ That will invert the matrix to the right format.
@@ -0,0 +1,88 @@
1
+ module Problem
2
+
3
+ # FSP class have a inner class Schedule
4
+ class FSP
5
+ # Inner class who represents the production schedule, that is, a matrix were the rows are the tasks
6
+ # and the columns the machines.
7
+ class Schedule
8
+ require 'matrix'
9
+
10
+ attr_reader :schedule
11
+
12
+ # Fill the schedule reading the an instance from a file
13
+ def build_from_file(path, transpose)
14
+ rows = Array.new
15
+ File.foreach(path).each do |line|
16
+ rows << line.split(" ").collect{ |e| e.to_i }
17
+ end
18
+ @schedule = transpose ? Matrix.rows(rows).transpose : Matrix.rows(rows)
19
+ end
20
+
21
+ # Given a sequence of tasks, reorder the schedule in this sequence
22
+ def reorder_schedule(tasks_sequence)
23
+ rows = Array.new
24
+ tasks_sequence.each do |task|
25
+ rows << @schedule.row(task)
26
+ end
27
+ Matrix.rows(rows)
28
+ end
29
+ end
30
+
31
+ attr_reader :default_solution # Is the sequence of tasks ordered from 0...N
32
+
33
+ # Used in makespan function to compare two execution times (also if one of them or the two are blank)
34
+ @@bigger = Proc.new do |a, b|
35
+ a ||= b ||= 0
36
+ if a > b ||= 0 then a else b end
37
+ end
38
+
39
+ # Initialize the FSP problem with a empty schedule
40
+ def initialize
41
+ @schedule = Schedule.new()
42
+ end
43
+
44
+ # Load the production schedule from a file
45
+ def load_schedule(path, transpose = false)
46
+ @schedule.build_from_file(path, transpose)
47
+ @default_solution = (0...@schedule.schedule.row_size).to_a
48
+ end
49
+
50
+ # Fitness function. The hash options are:
51
+ # - schedule: matrix of the production schedule;
52
+ # - task: task index;
53
+ # - machine: machine index;
54
+ # - memory: store the total time spent at the point where the task index X is processed at the machine index Y
55
+ # (that avoid desnecessary recursive calls);
56
+ # - tasks_sequence: sequence of tasks used to reorganize the schedule after calculate its makespan.
57
+ # The default use of the method is: inform the tasks sequence as parameter and the method do all the work,
58
+ # returning the makespan as result.
59
+ def makespan(options = {}, block = @@bigger)
60
+ if options[:tasks_sequence]
61
+ schedule = @schedule.reorder_schedule(options[:tasks_sequence])
62
+ makespan({schedule: schedule, task: schedule.row_size - 1, machine: schedule.column_size - 1, memory: {}}, block)
63
+ else
64
+ schedule = options[:schedule]
65
+ task = options[:task]
66
+ machine = options[:machine]
67
+ memory = options[:memory]
68
+ key = "#{task},#{machine}"
69
+ time = schedule[task, machine]
70
+ if task == 0 && machine == 0
71
+ return time
72
+ end
73
+ if task > 0 # Before everithing, calculate the time spent in the tasks from N to 0
74
+ time_task_before = memory["#{task - 1},#{machine}"]
75
+ time_task_before = makespan({schedule: schedule, task: task - 1, machine: machine, memory: memory}, block) if memory["#{task - 1},#{machine}"].nil?
76
+ end
77
+ if machine > 0 # Calculate the time spent at the machines from N to 0
78
+ time_machine_before = memory["#{task},#{machine - 1}"]
79
+ time_machine_before = makespan({schedule: schedule, task: task, machine: machine - 1, memory: memory}, block) if memory["#{task},#{machine - 1}"].nil?
80
+ end
81
+ total_time = block.call(time_task_before, time_machine_before) + time # Calculate the total time
82
+ memory[key] = total_time # Store the total time
83
+ total_time
84
+ end
85
+ end
86
+ alias :fitness :makespan # Needed because, in the algorithm classes, to be generic we call the 'fitness' function (all problem classes need to have a 'fitness' function)
87
+ end
88
+ end
@@ -0,0 +1,3 @@
1
+ module OptAlgFramework
2
+ VERSION = "1.0.3"
3
+ end
@@ -0,0 +1,6 @@
1
+ valid_files = Dir["#{File.dirname(__FILE__)}/**/*.rb"].reject {|f| File.directory?(f) }
2
+ valid_files.each { |f| require f }
3
+
4
+ module OptAlgFramework
5
+ # Write your code here
6
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'opt_alg_framework/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "opt_alg_framework"
8
+ spec.version = OptAlgFramework::VERSION
9
+ spec.authors = ["rodrigo-ehresmann"]
10
+ spec.email = ["igoehresmann@gmail.com"]
11
+
12
+ spec.summary = %q{Gem with a optimization algorithm framework that implements problems, algorithms and operator classes.}
13
+ spec.homepage = "https://github.com/rodrigo-ehresmann/opt_alg_framework"
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ if spec.respond_to?(:metadata)
22
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
23
+ end
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.9"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: opt_alg_framework
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.3
5
+ platform: ruby
6
+ authors:
7
+ - rodrigo-ehresmann
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-06-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.9'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description:
42
+ email:
43
+ - igoehresmann@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - .rspec
50
+ - .travis.yml
51
+ - Gemfile
52
+ - LICENSE.txt
53
+ - README.md
54
+ - Rakefile
55
+ - bin/console
56
+ - bin/setup
57
+ - lib/opt_alg_framework.rb
58
+ - lib/opt_alg_framework/algorithm/local_search/hill_climbing.rb
59
+ - lib/opt_alg_framework/algorithm/local_search/simulated_annealing.rb
60
+ - lib/opt_alg_framework/algorithm/local_search/tabu_search.rb
61
+ - lib/opt_alg_framework/operator/crossover/permutation/two_point_crossover.rb
62
+ - lib/opt_alg_framework/operator/selector/tournament_selection.rb
63
+ - lib/opt_alg_framework/operator/tweak/random_swap.rb
64
+ - lib/opt_alg_framework/problem/README.md
65
+ - lib/opt_alg_framework/problem/fsp.rb
66
+ - lib/opt_alg_framework/version.rb
67
+ - opt_alg_framework.gemspec
68
+ homepage: https://github.com/rodrigo-ehresmann/opt_alg_framework
69
+ licenses:
70
+ - MIT
71
+ metadata:
72
+ allowed_push_host: https://rubygems.org
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 2.6.3
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: Gem with a optimization algorithm framework that implements problems, algorithms
93
+ and operator classes.
94
+ test_files: []