Quick actions

cmd+k|ctrl+k

Navigation

Languages

simulated annealing 

Snippet info

Language

C

Visibility

public

Author

sriram

Created

2023-12-10T14:34:14.34414Z

Updated

2023-12-10T14:34:14.34414Z

# simulated annealing search of a one-dimensional objective function
from numpy import asarray
from numpy import exp
from numpy.random import randn
from numpy.random import rand
from numpy.random import seed

# objective function
def objective(x):
  return x[0]**2.0

# simulated annealing algorithm
def simulated_annealing(objective, bounds, n_iterations, step_size, temp):
  # generate an initial point
  best = bounds[:, 0] + rand(len(bounds)) * (bounds[:, 1] - bounds[:, 0])
  # evaluate the initial point
  best_eval = objective(best)
  # current working solution
  curr, curr_eval = best, best_eval
  # run the algorithm
  for i in range(n_iterations):
    # take a step
    candidate = curr + randn(len(bounds)) * step_size
    # evaluate candidate point
    candidate_eval = objective (candidate)
    # check for new best solution
    if candidate_eval < best_eval:
      # store new best point
      best, best_eval = candidate, candidate_eval
      # report progress
      print('>%d f(%s) = %.5f' % (i, best, best_eval))
    # difference between candidate and current point evaluation
    diff = candidate_eval - curr_eval
    # calculate temperature for current epoch
    t = temp / float(i + 1)
    # calculate metropolis acceptance criterion
    metropolis = exp(-diff / t)
    # check if we should keep the new point
    if diff < 0 or rand() < metropolis:
      # store the new current point
      curr, curr_eval = candidate, candidate_eval
  return [best, best_eval]

# seed the pseudorandom number generator
seed(1)
# define range for input
bounds = asarray([[-5.0, 5.0]])
# define the total iterations
n_iterations = 1000
# define the maximum step size
step_size = 0.1
# initial temperature
temp = 10
# perform the simulated annealing search
best, score = simulated_annealing(objective, bounds, n_iterations, step_size, temp)
print('Done!')
print('f(%s) = %f' % (best, score))

Output: 
>34 f([-0.78753544]) = 0.62021
>35 f([-0.76914239]) = 0.59158
>37 f([-0.68574854]) = 0.47025
>39 f([-0.64797564]) = 0.41987
>40 f([-0.58914623]) = 0.34709
>41 f([-0.55446029]) = 0.30743
>42 f([-0.41775702]) = 0.17452
>43 f([-0.35038542]) = 0.12277
>50 f([-0.15799045]) = 0.02496
>66 f([-0.11089772]) = 0.01230
>67 f([-0.09238208]) = 0.00853
>72 f([-0.09145261]) = 0.00836
>75 f([-0.05129162]) = 0.00263
>93 f([-0.02854417]) = 0.00081
>144 f([0.00864136]) = 0.00007
>149 f([0.00753953]) = 0.00006
>167 f([-0.00640394]) = 0.00004
>225 f([-0.00044965]) = 0.00000
>503 f([-0.00036261]) = 0.00000
>512 f([0.00013605]) = 0.00000
Done!
f([0.00013605]) = 0.000000
INFO