Skip to content

Return the best (lowest energy) state instead of the final state#31

Open
paceheart wants to merge 14 commits into3zcurdia:mainfrom
paceheart:main
Open

Return the best (lowest energy) state instead of the final state#31
paceheart wants to merge 14 commits into3zcurdia:mainfrom
paceheart:main

Conversation

@paceheart
Copy link

The final state isn't necessarily the best (lowest-energy) state. Now Simulator::run keeps track of the best state as it runs, and returns the best state instead of the happenstance final state.

The final state isn't necessarily the best (lowest-energy) state. Now Simulator::run keeps track of the best state as it runs, and returns the best state instead of the happenstance final state.
@paceheart
Copy link
Author

Oops! Sorry for not running the tests first. I'll take a look.

also factor out a helper method, to get out of ruby jail
…al energy

rake just displays the error and moves merrily along, but that's better than nothing
This test (almost always) fails before the "keep track of the best state" patch, and consistently succeeds after.
@paceheart
Copy link
Author

fixed!

Copy link
Owner

@3zcurdia 3zcurdia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution, but since this gem is being used in exiting projects we need to consider to this change to be available through configuration

paceheart and others added 6 commits March 20, 2025 07:36
Co-authored-by: Luis Ezcurdia <ing.ezcurdia@gmail.com>
Co-authored-by: Luis Ezcurdia <ing.ezcurdia@gmail.com>
Co-authored-by: Luis Ezcurdia <ing.ezcurdia@gmail.com>
"extracting this into a smaller method just to make rubocop happy is unnecessary; we can tell rubocop to skip the cop on this method" -3zcurdia
When true, returns the best (lowest energy) state. When false, returns the final state (preserves old behavior).
@paceheart
Copy link
Author

Thanks for your contribution, but since this gem is being used in exiting projects we need to consider to this change to be available through configuration

I added a new configuration option 'return_best'. I set the default to true, but if you think it's more important to maintain backward compatibility, we can set it to false instead.

@paceheart paceheart requested a review from 3zcurdia March 20, 2025 16:57
Copy link
Collaborator

@chrisbloom7 chrisbloom7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion, thanks for the contribution. Left some feedback below.

Comment on lines +144 to +164
def test_finds_suboptimal_solution_when_not_return_best
max_iterations = 10
initial_energy = real_energy_calculator(@collection)
final_energy = 1
iteration_count = 0

# The simulator might happen to finish on the optimal state by random chance.
# If that happens, run it again up to MAX_ITERATIONS times.
until final_energy > 1 || iteration_count > max_iterations
iteration_count += 1
final_metal = @simulator.run(@collection,
energy_calculator: ->(x) { real_energy_calculator(x) },
state_change: ->(state) { state.shuffle },
return_best: false)
final_energy = real_energy_calculator(final_metal.state)

assert final_energy < initial_energy
end

refute_equal 1, final_energy
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's still a chance this test could fail after max_attempts since it's just relying on random chance. I'd prefer a test that is deterministic, even if that means using stubs or mocks to setup the specific scenario this test is exercising.

class Configuration
DEFAULT_COOLING_RATE = 0.0003
DEFAULT_INITIAL_TEMPERATURE = 10_000.0
DEFAULT_RETURN_BEST = true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this should default to false if this will end up going into a minor release. If we want to make it default to true, then we should def give a major version bump and I'd expect to see documentation about the upgrade path to keep the old functionality. I defer to @3zcurdia about which route he would prefer to see.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants