diff --git a/lib/alns/stop/no_improvement.rb b/lib/alns/stop/no_improvement.rb new file mode 100644 index 0000000..f6a4a53 --- /dev/null +++ b/lib/alns/stop/no_improvement.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'alns/stop/base' + +module ALNS + module Stop + class NoImprovement < Base + def initialize(max_iterations) + super() + @max_iterations = max_iterations + @target = nil + @counter = 0 + end + + def done?(_rnd, best, _current) + if @target.nil? || best.objective < @target + @target = best.objective + @counter = 0 + else + @counter += 1 + end + @counter >= @max_iterations + end + end + end +end diff --git a/test/stop/no_improvement_test.rb b/test/stop/no_improvement_test.rb new file mode 100644 index 0000000..c92fd8b --- /dev/null +++ b/test/stop/no_improvement_test.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require_relative '../test_helper' +require_relative '../models' +require 'minitest/autorun' +require 'alns/stop/no_improvement' + +class NoImprovementTest < Minitest::Test + def test_done? + stop = ALNS::Stop::NoImprovement.new(2) + + assert !stop.done?(nil, FakeState.new(2), nil) + assert !stop.done?(nil, FakeState.new(2), nil) + assert !stop.done?(nil, FakeState.new(1), nil) + assert !stop.done?(nil, FakeState.new(1), nil) + assert stop.done?(nil, FakeState.new(1), nil) + end +end