← All NMath Code Examples
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