using System; using CenterSpace.NMath.Core; namespace CenterSpace.NMath.Examples.CSharp { class SimulatedAnnealingExample { /// <summary> /// A .NET example in C# showing how to find the minimum of a function using simulated annealing. /// </summary> static void Main( string[] args ) { // The function 0.25x^4 - 0.1x^3 - 20x^2 + 10x + 0.25y^4 - 0.1y^3 - 20y^2 + 10y // has a global minimum near (-6.3, -6.3) and three local minima. // Using Powells Method starting at (-1, -1), we always find the global minimum. var powell = new PowellMinimizer(); var minimum = powell.Minimize( bumpyFunction, new DoubleVector( -1.0, -1.0 ) ); string formatString = "G5"; Console.WriteLine(); Console.WriteLine( "PowellMinimizer starting at (-1, -1) found global minimum: " + bumpyFunction.Evaluate( minimum ).ToString( formatString ) ); Console.WriteLine(); // However, if youre not sure what a good starting point is, you might start // at (0, 0 ). In this case, Powells Method always finds a local minimum. minimum = powell.Minimize( bumpyFunction, new DoubleVector( 0.0, 0.0 ) ); Console.WriteLine( "But PowellMinimizer starting at (0, 0) found local minimum: " + bumpyFunction.Evaluate( minimum ).ToString( formatString ) ); Console.WriteLine(); // Using simulated annealing, with 10 steps of 100 iterations each, a // starting temperature of 10, and a starting point of (0, 0), we sometimes find // the global minimum. AnnealingScheduleBase schedule = new LinearAnnealingSchedule( 3, 100, 3 ); var annealing = new AnnealingMinimizer( schedule ); // Set keep history flag to true in order to get enough data to improve our annealing schedule. annealing.KeepHistory = true; int global = 0; int reps = 100; for ( int i = 0; i < reps; i++ ) { minimum = annealing.Minimize( bumpyFunction, new DoubleVector( -1.0, -1.0 ) ); if ( bumpyFunction.Evaluate( minimum ) < -874 ) { global++; } } Console.WriteLine( "AnnealingMinimizer starting at (0, 0) found global minimum " + global + " times " ); Console.WriteLine( "in " + reps + " repetitions." ); Console.WriteLine(); Console.WriteLine( "Annealing history... " ); Console.WriteLine(); Console.WriteLine( annealing.History.ToString( formatString ) ); Console.WriteLine(); // After analysis of the annealing history (annealing.History), we can improve the schedule // with a higher starting temperature to try and get us over the hump between the local and // global minima. annealing.Schedule = new LinearAnnealingSchedule( 100, 20, 30 ); // Lets increase the steps to 100, the iterations to 20 and the starting // temperature to 30. global = 0; for ( int i = 0; i < reps; i++ ) { minimum = annealing.Minimize( bumpyFunction, new DoubleVector( -1.0, -1.0 ) ); if ( bumpyFunction.Evaluate( minimum ) < -874 ) { global++; } } Console.WriteLine( "AnnealingMinimizer starting at (0, 0) found global minimum " + global + " times " ); Console.WriteLine( "in " + reps + " repetitions." ); Console.WriteLine(); Console.WriteLine( "Press Enter Key" ); Console.Read(); } private static MultiVariableFunction bumpyFunction = new MultiVariableFunction( new Func<DoubleVector, double>( Bumpy ) ); private static double Bumpy( DoubleVector v ) { double x = v[0]; double y = v[1]; double xTerm = 0.25 * Math.Pow( x, 4 ) - 0.1 * Math.Pow( x, 3 ) - 20 * Math.Pow( x, 2 ) + 10 * x; double yTerm = 0.25 * Math.Pow( y, 4 ) - 0.1 * Math.Pow( y, 3 ) - 20 * Math.Pow( y, 2 ) + 10 * y; return xTerm + yTerm; } } // class } // namespace← All NMath Code Examples