Skip to content

Added Simulated Annealing #1371

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open

Added Simulated Annealing #1371

wants to merge 24 commits into from

Conversation

Proxihox
Copy link

Article with explanation of approach for simulated annealing and a template code which can be used to implement the same.

Closes #996

@mhayter
Copy link
Contributor

mhayter commented Oct 19, 2024

Thanks for the contribution! I don't think I've solved a problem with simulated annealing before, so I'm excited to learn!

Regarding the article, I haven't thoroughly reviewed yet, but initially what I see is that README.md needs to be updated and some of the formatting is not rendering properly (reduce the spaces between $$).

You can preview: https://cp-algorithms.com/preview.html.

Please give the title of the practice problem in addition to the links.(Hyperlink the title of the problem).

Consider naming the function and making it callable rather than using int main{}

Thanks.

@Proxihox
Copy link
Author

@mhayter , Thanks for reviewing my PR. I've fixed the changes you mentioned. I'm not able to figure out why the preview throws an error when I write the following cpp inline code :

points = {{0,0},{2,2},{0,2},{2,0},{0,1},{1,2},{2,1},{1,0}};

This is trivial, as the actual values of these points isnt important and for now I've replaced it with a comment asking the user to fill it in with a set of points of their own choice.
Lmk if there is anything else I need to change.

@mhayter
Copy link
Contributor

mhayter commented Oct 19, 2024

Thanks for your progress this far. Unfortunately there are still many variables/ formula that don't render well or are not formatted at all like $s$ , $T$, $s_{next}$, the acceptance function, etc.

You're right I was curious about the $points$ initialization error too.

Regarding the substance of the article, I believe that the analogy of how 'temperature' plays into this process need to be explained likely via analogy.

Also, it may make more sense to have a more descriptive function name than $E()$. It seems like this may be 'standard' so maybe I'm incorrect here but, in a vacuum, I see $E()$ and it doesn't mean anything to me.

Also, there seemed to be confusing capitalization conventions like capitalizing state and temperature, which is unclear on why that convention was chosen.

Again these are just initial thoughts. I hoping someone more senior, will review this as well but I believe we owe you prompt feedback given your timely response.

@jxu
Copy link
Contributor

jxu commented Oct 20, 2024

I've implemented simulating annealing for fun in the past but not for programming contests because randomized and not guaranteed to get the right answer. Unlike say convex optimization or iterative relaxation which is guaranteed to converge.

@Proxihox
Copy link
Author

Proxihox commented Oct 21, 2024

@mhayter Thanks once more for the quick response. I agree that the temperature part could have been elaborated more, so I added a small section on how this algorithm works. with respect to the formatting, I've tried to fix everything, but I'll go through it once more.

@mhayter
Copy link
Contributor

mhayter commented Oct 28, 2024

Okay, I've been going through the code more closely.

I've implemented a simple dp (though I probably should have used chatgpt or google) to solve TSP and paired it against this algorithm.

  • As far as the algorithms is concerned, its not clear to me as a novice how I should set T and u.

  • Stylistically, we can use swap() in c++ for the points indices.

  • Using exp() probably makes sense relative to defining e and using pow

  • Choosing the points indices is quite strange and should cause overflow (rand() % points.size(); should roughly work)

  • We need to make it more obvious on how to initialized the points array:
    (Perhaps consider having an copy constructor i.e. state(const vector<pair<int,int>> &points) )?

Removing capitalization of 'state' would be consistent.
I'm American so I'm not sure if we use British neighbour (it's probably fine though.)

Cool article though. I was able to get a prototype working which I haven't done before.

I'd still like @adamant-pwn or @jakobkogler to review.

@Proxihox
Copy link
Author

@mhayter Thanks for suggesting the improvements.

  • I wrote how I'd approach choosing values for T and u.
  • Initially, I didn't use exp() , because I wanted to show that it is possible to modify the base of the exponent. I've explained why this is useful in the further modification section. I still modified the original PAF to use exp().
  • I implemented the copy constructor in the format state(state& s);, to keep up with the definition of the copy constructor.

I also figured out the cause for the double curly braces problem from my first commit : Double curly braces and HTML
and how to fix it : Solution to the double curly braces problem

Let me know if there are any further changes.

Copy link
Member

@adamant-pwn adamant-pwn 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 the PR! I left some comments that I'd like to be addressed before this is merged.

Copy link
Author

@Proxihox Proxihox left a comment

Choose a reason for hiding this comment

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

@adamant-pwn , thank you for your suggestions. To answer your questions:

Decay rate doesn't need to be exponential, but it is the standard implementation, I added this to the further modifications section.

When would someone not want the difference in energies to affect probability? Consider an E(s) which is pretty much constant for most points in its domain, but has very sharp drops for its minima's. In such a case, after finding a particular local minima, the PAF will mostly reject all points which are not inside another minima, as the energy difference is large. Thus the search will never exit a local minima and simulated annealing won't do much better than gradient descent. On the other hand, making the PAF independent of the difference in energies will allow the algorithm to do its magic.

I've tested the implementation with the 3rd problem : AtCoder Contest Scheduling.

Let me know if there is anything else to be done.

@Proxihox Proxihox requested a review from adamant-pwn November 28, 2024 04:25
@Proxihox
Copy link
Author

Proxihox commented Dec 1, 2024

@mhayter @adamant-pwn Any updates in this regard?

@mhayter
Copy link
Contributor

mhayter commented Dec 6, 2024

Thanks for your patience. Unfortunately, for articles where I'm not an expert, I'm leaving a final review to more senior experts like @adamant-pwn and @jakobkogler.

Thank you for creating the article though. I'm sure it will eventually be accepted as it is useful.

PS I think you should respond to the points specifically made by @adamant-pwn in the "conversation" portion or resolve them so the review can be done more easily.

@mhayter
Copy link
Contributor

mhayter commented Jan 23, 2025

Is there any update here? This seemed like a worthwhile article to me.

@Proxihox
Copy link
Author

I was caught up with other commitments and I couldn't work on this. I'll send updates over the weekend.

@Proxihox Proxihox closed this Mar 25, 2025
@Proxihox Proxihox reopened this Mar 25, 2025
github-actions bot added a commit that referenced this pull request Mar 25, 2025
@Proxihox
Copy link
Author

Hi @adamant-pwn @mhayter it shows changes requested but I'm not able to see anything. Is there anything I need to do? I'd also like to apologize, I accidently hit close merge request and the preview is no longer visible.

@mhayter
Copy link
Contributor

mhayter commented Apr 4, 2025

I've generated the new preview. If we can't get a review by @adamant-pwn in a week or two, I'll consider publishing it as the original article was useful for me( I was able to piece together a solution using your template.).

Unfortunately we don't have dedicated enough or, perhaps in my case, experienced enough volunteers, so reviews are difficult for new articles.

The lack of timely responses I imagine must be discouraging for current and future authors.

I'm sorry about that.

Copy link
Member

@adamant-pwn adamant-pwn left a comment

Choose a reason for hiding this comment

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

Hi, thanks for the update! I think we're getting very close here, but there are still some minor suggestion that, I think, should be addressed 🙂

## Further modifications to the algorithm:

- Add a time based exit condition to the while loop to prevent TLE
- The decay implemented above is an exponential decay. You can always replace this with a decay function as per your needs.
Copy link
Member

Choose a reason for hiding this comment

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

Is there any example where non-exponential decay performs better?

Copy link
Author

Choose a reason for hiding this comment

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

Libraries which implement Sim Anneal usually provide options for non-exponential decay such as this one. A linear decay function will motivate the algorithm to explore actively even towards the end. This is useful when there are multiple local minima very close to each other.

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

Successfully merging this pull request may close these issues.

Article on Simulated Annealing?
4 participants