VB Simulated Annealing Example

← All NMath Code Examples

 

Imports System

Imports CenterSpace.NMath.Core
Imports CenterSpace.NMath.Analysis

Namespace CenterSpace.NMath.Analysis.Examples.VisualBasic

  ' A .NET example in Visual Basic showing how to find the minimum of a function using simulated annealing.
  Module SimulatedAnnealingExample

    Private Function Bumpy(ByVal V As DoubleVector) As Double
      Dim X As Double = V(0)
      Dim y As Double = V(1)
      Dim XTerm As Double = 0.25 * Math.Pow(X, 4) - 0.1 * Math.Pow(X, 3) - 20 * Math.Pow(X, 2) + 10 * X
      Dim YTerm As Double = 0.25 * Math.Pow(y, 4) - 0.1 * Math.Pow(y, 3) - 20 * Math.Pow(y, 2) + 10 * y
      Return XTerm + YTerm
    End Function

    Sub Main()

      Dim D As New Func(Of DoubleVector, Double)(AddressOf Bumpy)
      Dim BumpyFunction As New MultiVariableFunction(D)

      ' 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.
      Dim Powell As PowellMinimizer = New PowellMinimizer
      Dim Minimum As DoubleVector = Powell.Minimize(BumpyFunction, New DoubleVector(-1.0, -1.0))

      Dim formatString As String = "G5"
      Console.WriteLine()

      Console.WriteLine("PowellMinimizer starting at (-1, -1) found global minimum: " & BumpyFunction.Evaluate(Minimum).ToString(formatString))
      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).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.
      Dim Schedule As AnnealingScheduleBase = New LinearAnnealingSchedule(3, 100, 3)
      Dim Annealing As New AnnealingMinimizer(Schedule)

      ' Set keep history flag to true in order to get enough data to improve our annealing schedule.
      Annealing.KeepHistory = True

      Dim [Global] As Integer = 0
      Dim Reps As Integer = 100
      Dim I As Integer
      For I = 0 To (Reps - 1)
        Minimum = Annealing.Minimize(BumpyFunction, New DoubleVector(-1.0, -1.0))
        If (BumpyFunction.Evaluate(Minimum) < -874) Then
          [Global] = [Global] + 1
        End If
      Next

      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)

      ' Let's increase the steps to 100, the iterations to 20 and the starting
      ' temperature to 30.
      [Global] = 0
      For I = 0 To (Reps - 1)
        Minimum = Annealing.Minimize(BumpyFunction, New DoubleVector(-1.0, -1.0))
        If (BumpyFunction.Evaluate(Minimum) < -874) Then
          [Global] = [Global] + 1
        End If
      Next
      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()

    End Sub

  End Module

End Namespace

← All NMath Code Examples
Top