0
|
4759 Views
|
2 Replies
|
1 Total Likes
View groups...
Share
GROUPS:

# How to output best solution found so far in Simulated Annealing?

Posted 10 years ago
 I have a numerical function with 5 variables that takes about 2 minutes to evaluate each time. Trying to minimize the function with the "SimmulatedAnnealing" method takes several days of calculation. I want Mathematica to print the best solution found so far, each time a new best solution is found while the algorithm is still running. This code outputs the current values of the solution each step, but since the method doesn't always move towards a solution that is better than the previous one at each step, the last solution printed is not always the best solution so far NMinimize[{StressError[p1, p2, p3, p4, p5], p1 > 0, p2 > 0, p3 > 0, p4 > 0, p5 > 0}, {{p1, 0.5, 2}, {p2, 0.5, 2}, {p3, 0.5, 2}, {p4, 0.5, 2}, {p5, 0.5, 2}}, Method -> "SimulatedAnnealing", StepMonitor :> Print[{p1, p2, p3, p4, p5}]]  A way of doing this would be evaluating the function at each step, and only printing if it is the best solution found so far. Example: BestSoFar = Infinity NMinimize[{StressError[p1, p2, p3, p4, p5], p1 > 0, p2 > 0, p3 > 0, p4 > 0, p5 > 0}, {{p1, 0.5, 2}, {p2, 0.5, 2}, {p3, 0.5, 2}, {p4, 0.5, 2}, {p5, 0.5, 2}}, Method -> "SimulatedAnnealing", StepMonitor :> (If[StressError[p1, p2, p3, p4, p5] < BestSoFar, BestSoFar= StressError[p1, p2, p3, p4, p5]; Print[{p1, p2, p3, p4, p5}]])]  The problem with the previous code is that it would evaluate the function again at each step (which, considering that there are several hundreds of steps in the calculation, and evaluating the function takes about 2 minutes, would add a considerable amount of time to the calculation); the algorithm should already evaluate the function at each step, so evaluating it again shouldn't be needed. Do you know a more efficient way to do the same?
2 Replies
Sort By:
Posted 10 years ago
 Thanks, the method described works in making evaluations with repeated parameters of the function much faster StressError[p1_?NumericQ, p2_?NumericQ, p3_?NumericQ, p4_?NumericQ, p5_?NumericQ]:= StressError[p1, p2, p3, p4, p5] = ... By adding "?NumericQ" I define the function to only evaluate with numeric input (that is how I defined the function initially), so numeric evaluation shouldn't take place.
Posted 10 years ago
 Among other possibilities, you might want to memoize that objective. This is done as StressError[p1_, p2_, p3_, p4_, p5_]:= StressError[p1, p2, p3, p4, p5]=... Once computed for a particular {p1,...,p5} it will subsequently be found by lookup.Also it might be useful to define it in such a way that it only evaluates when given explicit numeric input. If symbolic processing is any part of the speed issue, this change will redress that.