Blame doc/siman.rst

Packit 67cb25
.. index::
Packit 67cb25
   single: simulated annealing
Packit 67cb25
   single: combinatorial optimization
Packit 67cb25
   single: optimization, combinatorial
Packit 67cb25
   single: energy function
Packit 67cb25
   single: cost function
Packit 67cb25
Packit 67cb25
*******************
Packit 67cb25
Simulated Annealing
Packit 67cb25
*******************
Packit 67cb25
Packit 67cb25
Stochastic search techniques are used when the structure of a space is
Packit 67cb25
not well understood or is not smooth, so that techniques like Newton's
Packit 67cb25
method (which requires calculating Jacobian derivative matrices) cannot
Packit 67cb25
be used. In particular, these techniques are frequently used to solve
Packit 67cb25
combinatorial optimization problems, such as the traveling salesman
Packit 67cb25
problem.
Packit 67cb25
Packit 67cb25
The goal is to find a point in the space at which a real valued
Packit 67cb25
*energy function* (or *cost function*) is minimized.  Simulated
Packit 67cb25
annealing is a minimization technique which has given good results in
Packit 67cb25
avoiding local minima; it is based on the idea of taking a random walk
Packit 67cb25
through the space at successively lower temperatures, where the
Packit 67cb25
probability of taking a step is given by a Boltzmann distribution.
Packit 67cb25
Packit 67cb25
The functions described in this chapter are declared in the header file
Packit 67cb25
:file:`gsl_siman.h`.
Packit 67cb25
Packit 67cb25
Simulated Annealing algorithm
Packit 67cb25
=============================
Packit 67cb25
Packit 67cb25
The simulated annealing algorithm takes random walks through the problem
Packit 67cb25
space, looking for points with low energies; in these random walks, the
Packit 67cb25
probability of taking a step is determined by the Boltzmann distribution,
Packit 67cb25
Packit 67cb25
.. math:: p = e^{-(E_{i+1} - E_i)/(kT)}
Packit 67cb25
Packit 67cb25
if 
Packit 67cb25
:math:`E_{i+1} > E_i`, and
Packit 67cb25
:math:`p = 1` when 
Packit 67cb25
:math:`E_{i+1} \le E_i`.
Packit 67cb25
Packit 67cb25
In other words, a step will occur if the new energy is lower.  If
Packit 67cb25
the new energy is higher, the transition can still occur, and its
Packit 67cb25
likelihood is proportional to the temperature :math:`T` and inversely
Packit 67cb25
proportional to the energy difference 
Packit 67cb25
:math:`E_{i+1} - E_i`.
Packit 67cb25
Packit 67cb25
.. index::
Packit 67cb25
   single: cooling schedule
Packit 67cb25
   single: schedule, cooling
Packit 67cb25
Packit 67cb25
The temperature :math:`T` is initially set to a high value, and a random
Packit 67cb25
walk is carried out at that temperature.  Then the temperature is
Packit 67cb25
lowered very slightly according to a *cooling schedule*, for
Packit 67cb25
example: :math:`T \rightarrow T/\mu_T`
Packit 67cb25
where :math:`\mu_T` is slightly greater than 1. 
Packit 67cb25
Packit 67cb25
The slight probability of taking a step that gives higher energy is what
Packit 67cb25
allows simulated annealing to frequently get out of local minima.
Packit 67cb25
Packit 67cb25
Simulated Annealing functions
Packit 67cb25
=============================
Packit 67cb25
Packit 67cb25
.. function:: void gsl_siman_solve (const gsl_rng * r, void * x0_p, gsl_siman_Efunc_t Ef, gsl_siman_step_t take_step, gsl_siman_metric_t distance, gsl_siman_print_t print_position, gsl_siman_copy_t copyfunc, gsl_siman_copy_construct_t copy_constructor, gsl_siman_destroy_t destructor, size_t element_size, gsl_siman_params_t params)
Packit 67cb25
Packit 67cb25
   This function performs a simulated annealing search through a given
Packit 67cb25
   space.  The space is specified by providing the functions :data:`Ef` and
Packit 67cb25
   :data:`distance`.  The simulated annealing steps are generated using the
Packit 67cb25
   random number generator :data:`r` and the function :data:`take_step`.
Packit 67cb25
Packit 67cb25
   The starting configuration of the system should be given by :data:`x0_p`.
Packit 67cb25
   The routine offers two modes for updating configurations, a fixed-size
Packit 67cb25
   mode and a variable-size mode.  In the fixed-size mode the configuration
Packit 67cb25
   is stored as a single block of memory of size :data:`element_size`.
Packit 67cb25
   Copies of this configuration are created, copied and destroyed
Packit 67cb25
   internally using the standard library functions :func:`malloc`,
Packit 67cb25
   :func:`memcpy` and :func:`free`.  The function pointers :data:`copyfunc`,
Packit 67cb25
   :data:`copy_constructor` and :data:`destructor` should be null pointers in
Packit 67cb25
   fixed-size mode.  In the variable-size mode the functions
Packit 67cb25
   :data:`copyfunc`, :data:`copy_constructor` and :data:`destructor` are used to
Packit 67cb25
   create, copy and destroy configurations internally.  The variable
Packit 67cb25
   :data:`element_size` should be zero in the variable-size mode.
Packit 67cb25
Packit 67cb25
   The :data:`params` structure (described below) controls the run by
Packit 67cb25
   providing the temperature schedule and other tunable parameters to the
Packit 67cb25
   algorithm.
Packit 67cb25
Packit 67cb25
   On exit the best result achieved during the search is placed in
Packit 67cb25
   :data:`x0_p`.  If the annealing process has been successful this
Packit 67cb25
   should be a good approximation to the optimal point in the space.
Packit 67cb25
Packit 67cb25
   If the function pointer :data:`print_position` is not null, a debugging
Packit 67cb25
   log will be printed to :code:`stdout` with the following columns::
Packit 67cb25
Packit 67cb25
      #-iter  #-evals  temperature  position  energy  best_energy
Packit 67cb25
Packit 67cb25
   and the output of the function :data:`print_position` itself.  If
Packit 67cb25
   :data:`print_position` is null then no information is printed.
Packit 67cb25
Packit 67cb25
The simulated annealing routines require several user-specified
Packit 67cb25
functions to define the configuration space and energy function.  The
Packit 67cb25
prototypes for these functions are given below.
Packit 67cb25
Packit 67cb25
.. type:: gsl_siman_Efunc_t
Packit 67cb25
Packit 67cb25
   This function type should return the energy of a configuration :data:`xp`::
Packit 67cb25
Packit 67cb25
      double (*gsl_siman_Efunc_t) (void *xp)
Packit 67cb25
Packit 67cb25
.. type:: gsl_siman_step_t
Packit 67cb25
Packit 67cb25
   This function type should modify the configuration :data:`xp` using a random step
Packit 67cb25
   taken from the generator :data:`r`, up to a maximum distance of
Packit 67cb25
   :data:`step_size`::
Packit 67cb25
Packit 67cb25
      void (*gsl_siman_step_t) (const gsl_rng *r, void *xp, 
Packit 67cb25
                                double step_size)
Packit 67cb25
Packit 67cb25
.. type:: gsl_siman_metric_t
Packit 67cb25
Packit 67cb25
   This function type should return the distance between two configurations
Packit 67cb25
   :data:`xp` and :data:`yp`::
Packit 67cb25
Packit 67cb25
      double (*gsl_siman_metric_t) (void *xp, void *yp)
Packit 67cb25
Packit 67cb25
.. type:: gsl_siman_print_t
Packit 67cb25
Packit 67cb25
   This function type should print the contents of the configuration :data:`xp`::
Packit 67cb25
Packit 67cb25
      void (*gsl_siman_print_t) (void *xp)
Packit 67cb25
Packit 67cb25
.. type:: gsl_siman_copy_t
Packit 67cb25
Packit 67cb25
   This function type should copy the configuration :data:`source` into :data:`dest`::
Packit 67cb25
Packit 67cb25
      void (*gsl_siman_copy_t) (void *source, void *dest)
Packit 67cb25
Packit 67cb25
.. type:: gsl_siman_copy_construct_t
Packit 67cb25
Packit 67cb25
   This function type should create a new copy of the configuration :data:`xp`::
Packit 67cb25
Packit 67cb25
      void * (*gsl_siman_copy_construct_t) (void *xp)
Packit 67cb25
Packit 67cb25
.. type:: gsl_siman_destroy_t
Packit 67cb25
Packit 67cb25
   This function type should destroy the configuration :data:`xp`, freeing its
Packit 67cb25
   memory::
Packit 67cb25
Packit 67cb25
      void (*gsl_siman_destroy_t) (void *xp)
Packit 67cb25
Packit 67cb25
.. type:: gsl_siman_params_t
Packit 67cb25
Packit 67cb25
   These are the parameters that control a run of :func:`gsl_siman_solve`.
Packit 67cb25
   This structure contains all the information needed to control the
Packit 67cb25
   search, beyond the energy function, the step function and the initial
Packit 67cb25
   guess.
Packit 67cb25
Packit 67cb25
   ========================================= ============================================================
Packit 67cb25
   :code:`int n_tries`                       The number of points to try for each step.
Packit 67cb25
   :code:`int iters_fixed_T`                 The number of iterations at each temperature.
Packit 67cb25
   :code:`double step_size`                  The maximum step size in the random walk.
Packit 67cb25
   :code:`double k, t_initial, mu_t, t_min`  The parameters of the Boltzmann distribution and cooling
Packit 67cb25
                                             schedule.
Packit 67cb25
   ========================================= ============================================================
Packit 67cb25
Packit 67cb25
Examples
Packit 67cb25
========
Packit 67cb25
Packit 67cb25
The simulated annealing package is clumsy, and it has to be because it
Packit 67cb25
is written in C, for C callers, and tries to be polymorphic at the same
Packit 67cb25
time.  But here we provide some examples which can be pasted into your
Packit 67cb25
application with little change and should make things easier.
Packit 67cb25
Packit 67cb25
Trivial example
Packit 67cb25
---------------
Packit 67cb25
Packit 67cb25
The first example, in one dimensional Cartesian space, sets up an energy
Packit 67cb25
function which is a damped sine wave; this has many local minima, but
Packit 67cb25
only one global minimum, somewhere between 1.0 and 1.5.  The initial
Packit 67cb25
guess given is 15.5, which is several local minima away from the global
Packit 67cb25
minimum.
Packit 67cb25
Packit 67cb25
.. include:: examples/siman.c
Packit 67cb25
   :code:
Packit 67cb25
Packit 67cb25
:numref:`fig_siman-test` is generated by running
Packit 67cb25
:code:`siman_test` in the following way::
Packit 67cb25
Packit 67cb25
  $ ./siman_test | awk '!/^#/ {print $1, $4}' 
Packit 67cb25
   | graph -y 1.34 1.4 -W0 -X generation -Y position 
Packit 67cb25
   | plot -Tps > siman-test.eps
Packit 67cb25
Packit 67cb25
:numref:`fig_siman-energy` is generated by running
Packit 67cb25
:code:`siman_test` in the following way::
Packit 67cb25
Packit 67cb25
  $ ./siman_test | awk '!/^#/ {print $1, $5}' 
Packit 67cb25
   | graph -y -0.88 -0.83 -W0 -X generation -Y energy 
Packit 67cb25
   | plot -Tps > siman-energy.eps
Packit 67cb25
Packit 67cb25
.. _fig_siman-test:
Packit 67cb25
Packit 67cb25
.. figure:: /images/siman-test.png
Packit 67cb25
   :scale: 60%
Packit 67cb25
Packit 67cb25
   Example of a simulated annealing run: at higher temperatures (early in
Packit 67cb25
   the plot) you see that the solution can fluctuate, but at lower
Packit 67cb25
   temperatures it converges.
Packit 67cb25
Packit 67cb25
.. _fig_siman-energy:
Packit 67cb25
Packit 67cb25
.. figure:: /images/siman-energy.png
Packit 67cb25
   :scale: 60%
Packit 67cb25
Packit 67cb25
   Simulated annealing energy vs generation
Packit 67cb25
Packit 67cb25
.. index::
Packit 67cb25
   single: TSP
Packit 67cb25
   single: traveling salesman problem
Packit 67cb25
Packit 67cb25
Traveling Salesman Problem
Packit 67cb25
--------------------------
Packit 67cb25
Packit 67cb25
The TSP (*Traveling Salesman Problem*) is the classic combinatorial
Packit 67cb25
optimization problem.  I have provided a very simple version of it,
Packit 67cb25
based on the coordinates of twelve cities in the southwestern United
Packit 67cb25
States.  This should maybe be called the *Flying Salesman Problem*,
Packit 67cb25
since I am using the great-circle distance between cities, rather than
Packit 67cb25
the driving distance.  Also: I assume the earth is a sphere, so I don't
Packit 67cb25
use geoid distances.
Packit 67cb25
Packit 67cb25
The :func:`gsl_siman_solve` routine finds a route which is 3490.62
Packit 67cb25
Kilometers long; this is confirmed by an exhaustive search of all
Packit 67cb25
possible routes with the same initial city.
Packit 67cb25
Packit 67cb25
The full code is given below.
Packit 67cb25
Packit 67cb25
.. include:: examples/siman_tsp.c
Packit 67cb25
   :code:
Packit 67cb25
Packit 67cb25
Below are some plots generated in the following way::
Packit 67cb25
Packit 67cb25
  $ ./siman_tsp > tsp.output
Packit 67cb25
  $ grep -v "^#" tsp.output  
Packit 67cb25
   | awk '{print $1, $NF}'
Packit 67cb25
   | graph -y 3300 6500 -W0 -X generation -Y distance 
Packit 67cb25
      -L "TSP - 12 southwest cities"
Packit 67cb25
   | plot -Tps > 12-cities.eps
Packit 67cb25
  $ grep initial_city_coord tsp.output 
Packit 67cb25
    | awk '{print $2, $3}' 
Packit 67cb25
    | graph -X "longitude (- means west)" -Y "latitude" 
Packit 67cb25
       -L "TSP - initial-order" -f 0.03 -S 1 0.1 
Packit 67cb25
    | plot -Tps > initial-route.eps
Packit 67cb25
  $ grep final_city_coord tsp.output 
Packit 67cb25
    | awk '{print $2, $3}' 
Packit 67cb25
    | graph -X "longitude (- means west)" -Y "latitude" 
Packit 67cb25
       -L "TSP - final-order" -f 0.03 -S 1 0.1 
Packit 67cb25
    | plot -Tps > final-route.eps
Packit 67cb25
Packit 67cb25
This is the output showing the initial order of the cities; longitude is
Packit 67cb25
negative, since it is west and I want the plot to look like a map::
Packit 67cb25
Packit 67cb25
  # initial coordinates of cities (longitude and latitude)
Packit 67cb25
  ###initial_city_coord: -105.95 35.68 Santa Fe
Packit 67cb25
  ###initial_city_coord: -112.07 33.54 Phoenix
Packit 67cb25
  ###initial_city_coord: -106.62 35.12 Albuquerque
Packit 67cb25
  ###initial_city_coord: -103.2 34.41 Clovis
Packit 67cb25
  ###initial_city_coord: -107.87 37.29 Durango
Packit 67cb25
  ###initial_city_coord: -96.77 32.79 Dallas
Packit 67cb25
  ###initial_city_coord: -105.92 35.77 Tesuque
Packit 67cb25
  ###initial_city_coord: -107.84 35.15 Grants
Packit 67cb25
  ###initial_city_coord: -106.28 35.89 Los Alamos
Packit 67cb25
  ###initial_city_coord: -106.76 32.34 Las Cruces
Packit 67cb25
  ###initial_city_coord: -108.58 37.35 Cortez
Packit 67cb25
  ###initial_city_coord: -108.74 35.52 Gallup
Packit 67cb25
  ###initial_city_coord: -105.95 35.68 Santa Fe
Packit 67cb25
Packit 67cb25
The optimal route turns out to be::
Packit 67cb25
Packit 67cb25
  # final coordinates of cities (longitude and latitude)
Packit 67cb25
  ###final_city_coord: -105.95 35.68 Santa Fe
Packit 67cb25
  ###final_city_coord: -103.2 34.41 Clovis
Packit 67cb25
  ###final_city_coord: -96.77 32.79 Dallas
Packit 67cb25
  ###final_city_coord: -106.76 32.34 Las Cruces
Packit 67cb25
  ###final_city_coord: -112.07 33.54 Phoenix
Packit 67cb25
  ###final_city_coord: -108.74 35.52 Gallup
Packit 67cb25
  ###final_city_coord: -108.58 37.35 Cortez
Packit 67cb25
  ###final_city_coord: -107.87 37.29 Durango
Packit 67cb25
  ###final_city_coord: -107.84 35.15 Grants
Packit 67cb25
  ###final_city_coord: -106.62 35.12 Albuquerque
Packit 67cb25
  ###final_city_coord: -106.28 35.89 Los Alamos
Packit 67cb25
  ###final_city_coord: -105.92 35.77 Tesuque
Packit 67cb25
  ###final_city_coord: -105.95 35.68 Santa Fe
Packit 67cb25
Packit 67cb25
.. figure:: /images/siman-initial-route.png
Packit 67cb25
   :scale: 60%
Packit 67cb25
Packit 67cb25
   Initial route for the 12 southwestern cities Flying Salesman Problem.
Packit 67cb25
Packit 67cb25
.. figure:: /images/siman-final-route.png
Packit 67cb25
   :scale: 60%
Packit 67cb25
Packit 67cb25
   Final (optimal) route for the 12 southwestern cities Flying Salesman Problem.
Packit 67cb25
Packit 67cb25
Here's a plot of the cost function (energy) versus generation (point in
Packit 67cb25
the calculation at which a new temperature is set) for this problem:
Packit 67cb25
Packit 67cb25
.. figure:: /images/siman-12-cities.png
Packit 67cb25
   :scale: 60%
Packit 67cb25
Packit 67cb25
   Example of a simulated annealing run for the 12 southwestern cities
Packit 67cb25
   Flying Salesman Problem.
Packit 67cb25
Packit 67cb25
References and Further Reading
Packit 67cb25
==============================
Packit 67cb25
Packit 67cb25
Further information is available in the following book,
Packit 67cb25
Packit 67cb25
* *Modern Heuristic Techniques for Combinatorial Problems*, Colin R. Reeves
Packit 67cb25
  (ed.), McGraw-Hill, 1995 (ISBN 0-07-709239-2).