Provide notification callbacks for progress and new solutions

This commit is contained in:
Manuel Bustillo 2025-09-08 16:32:13 +02:00
parent ac659bef86
commit 0d1b64256d
2 changed files with 24 additions and 1 deletions

View File

@ -5,6 +5,7 @@
module VNS module VNS
class Engine class Engine
PERTURBATION_SIZES = [1, 1, 1, 2, 2, 3].freeze PERTURBATION_SIZES = [1, 1, 1, 2, 2, 3].freeze
ITERATIONS = 50
class << self class << self
def sequence(elements) def sequence(elements)
elements = elements.to_a elements = elements.to_a
@ -26,6 +27,14 @@ module VNS
@perturbations << klass @perturbations << klass
end end
def notify_progress(&block)
@progress_notifier = block
end
def on_better_solution(&block)
@better_solution_notifier = block
end
attr_writer :initial_solution attr_writer :initial_solution
def run def run
@ -40,18 +49,24 @@ module VNS
run_all_optimizations run_all_optimizations
@progress_notifier&.call(Rational(1, ITERATIONS + 1))
best_solution = @current_solution best_solution = @current_solution
50.times do ITERATIONS.times do |iteration|
@current_solution = Tables::WheelSwap.new(best_solution).call(PERTURBATION_SIZES.sample) @current_solution = Tables::WheelSwap.new(best_solution).call(PERTURBATION_SIZES.sample)
@best_score = @target_function.call(@current_solution) @best_score = @target_function.call(@current_solution)
Rails.logger.debug { "After perturbation: #{@best_score}" } Rails.logger.debug { "After perturbation: #{@best_score}" }
run_all_optimizations run_all_optimizations
@progress_notifier&.call(Rational(iteration + 1, ITERATIONS + 1))
next unless best_solution.discomfort > @current_solution.discomfort next unless best_solution.discomfort > @current_solution.discomfort
best_solution = @current_solution best_solution = @current_solution
@better_solution_notifier&.call(best_solution)
Rails.logger.debug do Rails.logger.debug do
"Found better solution after perturbation optimization: #{@current_solution.discomfort}" "Found better solution after perturbation optimization: #{@current_solution.discomfort}"
end end

View File

@ -21,6 +21,14 @@ namespace :vns do
engine.target_function(&:discomfort) engine.target_function(&:discomfort)
engine.notify_progress do |current_progress|
Rails.logger.info "Progress: #{(current_progress * 100.0).round(2)}%"
end
engine.on_better_solution do |better_solution|
Rails.logger.info "New best solution found with discomfort: #{better_solution.discomfort}"
end
solution = Rails.benchmark('VNS Benchmarking') { engine.run } solution = Rails.benchmark('VNS Benchmarking') { engine.run }
Rails.logger.info "Best solution found with discomfort: #{solution.discomfort}" Rails.logger.info "Best solution found with discomfort: #{solution.discomfort}"