[TOC]
using System;
using CenterSpace.NMath.Core;
using CenterSpace.NMath.Analysis;
namespace CenterSpace.NMath.Analysis.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)
{
Console.WriteLine();
// 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 Powell's Method starting at (-1, -1), we always find the global minimum.
PowellMinimizer powell = new PowellMinimizer();
DoubleVector minimum = powell.Minimize(bumpyFunction, new DoubleVector(-1.0, -1.0));
Console.WriteLine("PowellMinimizer starting at (-1, -1) found global minimum: " + bumpyFunction.Evaluate(minimum));
Console.WriteLine();
// However, if you're not sure what a good starting point is, you might start
// at (0, 0 ). In this case, Powell's 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));
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);
AnnealingMinimizer 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);
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);
// Let's 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 NMathFunctions.DoubleVectorDoubleFunction(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
[TOC]