;;; Simulated annealing ;;; John David Stone ;;; Department of Mathematics and Computer Science ;;; Grinnell College ;;; stone@cs.grinnell.edu ;;; created December 5, 1999 ;;; last revised December 8, 2010 ;;; When no efficient algorithm for solving an optimization problem is ;;; available, simulated annealing can often be used to find a near-optimal ;;; solution. (However, it is not guaranteed to work; the justification ;;; for using it is entirely pragmatic.) ;;; The metaphor underlying this approach is the physical process of making ;;; a metal less brittle by annealing it -- heating it up and then cooling ;;; it very slowly, waiting at each cooling step for the atoms in the metal ;;; to find optimal positions and orientations, achieving the state of ;;; minimum energy for the system. ;;; The SIMULATED-ANNEALING procedure encapsulates the control structure ;;; for such a simulation. Initially, one possible solution is constructed ;;; arbitrarily, perhaps randomly. It is expected that this initial ;;; solution is far from optimal, so the solution is then repeatedly ;;; modified. The successive modifications are also chosen randomly, but ;;; not all of the modifications are actually made. Instead, the effect of ;;; each proposed modification on the quantity to be optimized is ;;; evaluated. The proposed modification is actually made whenever it ;;; increases the value of the solution, but also sometimes when it ;;; decreases it by a sufficiently small amount. ;;; In early stages, even modifications that considerably decrease the ;;; value of the solution are sometimes approved, just as in early stages ;;; of annealing the atoms are relatively free to shift their positions and ;;; orientations. But as the simulated temperature is lowered, the ;;; probability of a large decrease in the value of a solution is also ;;; gradually lowered and the pieces of the solution are therefore ;;; increasingly locked into place. ;;; The SIMULATED-ANNEALING procedure takes five arguments: ;;; INITIAL-SOLUTION is an arbitrarily constructed initial solution. ;;; The TRIAL-LIMIT parameter puts an upper bound on the number of ;;; modifications that will be proposed at any single temperature level. ;;; When this limit is reached, the temperature is lowered and the next ;;; phase of annealing begins. ;;; The CHANGE-LIMIT parameter puts an upper bound on the number of ;;; modifications that will actually be made at any single temperature ;;; level. Reaching this limit also causes a transition to the next phase ;;; of annealing, at a lower temperature. ;;; The CHANGE procedure takes a possible solution and returns two values: ;;; (1) a procedure that, if applied to that solution, would modify it ;;; slightly, and (2) an exact real number indicating the difference ;;; between the value of the modified solution and the value of the ;;; original one. ;;; The COOL procedure takes an inexact real number and returns another such ;;; inexact real number. The result should be less than the argument. This ;;; procedure will be applied to decrease the simulated temperature (which ;;; is initially set to be much greater than the expected value of a ;;; proposed modification to the initial solution) from one annealing phase ;;; to the next. (define simulated-annealing (lambda (initial-solution trial-limit change-limit change cool) ;; The initial temperature is computed by finding the greatest of the ;; values of TRIAL-LIMIT modifications that might be made to the ;; initial solution and doubling it. This is supposed to ensure that ;; even modifications that would result in a large negative change in ;; value are occasionally approved during the initial annealing phases. (let ((initial-temperature (let loop ((trials 0) (so-far -inf.0)) (if (= trials trial-limit) (* 2 so-far) (call-with-values (lambda () (change initial-solution)) (lambda (ignored delta) (loop (+ trials 1) (max delta so-far))))))) ;; One step in the annealing process is completed when either the ;; number of proposed modifications or the number of ;; modifications actually performed reaches its upper bound (step-finished? (lambda (trials changes) (or (= trials trial-limit) (= changes change-limit))))) ;; The ANNEALING-STEP procedure carries the process through all of ;; the proposed modifications that will be considered at one ;; particular temperature, then decreases the temperature for the ;; next step. (let ((annealing-step (lambda (old-solution temperature) (let loop ((solution old-solution) (trials 0) (changes 0)) (if (step-finished? trials changes) (begin (report-step-result temperature solution trials changes) (values solution (cool temperature) (zero? changes))) (call-with-values (lambda () (change solution)) (lambda (changer delta) (if (change-approved? delta temperature) (loop (changer solution) (+ trials 1) (+ changes 1)) (loop solution (+ trials 1) changes))))))))) ;; We repeatedly invoke ANNEALING-STEP until some temperature is ;; reached at which none of the proposed modifications is approved. (let main-loop ((solution initial-solution) (temperature initial-temperature)) (call-with-values (lambda () (annealing-step solution temperature)) (lambda (new-solution new-temperature unchanged) (if unchanged new-solution (main-loop new-solution new-temperature))))))))) ;;; The REPORT-STEP-RESULT procedure gives a progress report at the end of ;;; each annealing step. (define report-step-result (lambda (temperature solution trials changes) (display "At temperature ") (display temperature) (display ",") (newline) (display "after ") (display trials) (display " proposed modifications,") (newline) (display "of which ") (display changes) (display (if (= changes 1) " was" " were")) (display " approved,") (newline) (display "the value of the solution was ") (display (solution-value solution)) (display ".") (newline) (newline))) ;;; The CHANGE-APPROVED? procedure determines whether one possible solution ;;; should be replaced by another, given the amount by which the value of the ;;; new solution exceeds the value of the old one (DELTA) and the current ;;; simulated temperature. ;;; If the new solution's value is greater than or equal to the old one's (so ;;; that DELTA is non-negative), the modification is always approved. ;;; Otherwise, the probability that a modification is approved is the value of ;;; an exponential function with an exponent whose magnitude is directly ;;; proportional to DELTA (so that solutions that would greatly decrease the ;;; value are seldom approved) and inversely proportional to the simulated ;;; TEMPERATURE (so that new solutions are often approved at high temperatures, ;;; even when they decrease the value, but seldom approved at low ;;; temperatures). (define (change-approved? delta temperature) (or (<= 0.0 delta) (< (random 1.0) (exp (/ delta temperature)))))