patterncsharpMinor
Linq version of the simulated annealing algorithm
Viewed 0 times
linqtheversionalgorithmsimulatedannealing
Problem
I decided to try and implement (a version of) the simulated annealing algorithm using just LINQ, just to see if I could.
I'd love it if anybody could see any ways to improve it, or give advice on any cool tricks for doing this kind of thing.
I'd love it if anybody could see any ways to improve it, or give advice on any cool tricks for doing this kind of thing.
var result = (from res in Enumerable.Range(0, 1)
let R = new Random()
let initial = Enumerable.Range(0, 10).Select(i => R.Next(-10, 10))
let iterations = Enumerable.Range(0, 100)
let Schedule = (Func)
(X => 4 + (float)Math.Sin(X))
from iteration in iterations
let temperature = Schedule(iteration)
let state = Enumerable.Range(0, 10).Select(i => R.Next(-10, 10))
let DeltaE = state.Sum() - initial.Sum()
where DeltaE > 0 ||
Math.Pow(Math.E, DeltaE / temperature) > R.NextDouble()
select state.ToList()
).OrderBy(S => S.Sum()).First();Solution
You have a lot of small errors here.
- What is the purpose of
from res in Enumerable.Range(0, 1)? It looks like you did it to force some local variables into 'let' queries, which makes no sense to me.
- Instead of using
OrderBy(X).First()you should useMinBy(X)(write it yourself if it doesn't exist). There's a significant performance difference.
- The value of
initialchanges every time it is enumerated. Confusing. (You can cache the results withToArrayorToListto prevent re-enumerating from running moreRandom.Nextcalls)
- Ensure
new Random()is only performed once (do it outside the query). The default seed is the current time, which is highly correlated between calls. You're likely to end up with two instances ofRandomwith the exact same seed.
Random.Next(-10, 10)returns values in[-10, +9]. You probably wanted[-10, +10].
Context
StackExchange Code Review Q#5677, answer score: 6
Revisions (0)
No revisions yet.