| 47 | } |
| 48 | |
| 49 | func Anneal(state Annealable, maxTemp, minTemp float64, steps int) Annealable { |
| 50 | factor := -math.Log(maxTemp / minTemp) |
| 51 | state = state.Copy() |
| 52 | bestState := state.Copy() |
| 53 | bestEnergy := state.Energy() |
| 54 | previousEnergy := bestEnergy |
| 55 | for step := 0; step < steps; step++ { |
| 56 | pct := float64(step) / float64(steps-1) |
| 57 | temp := maxTemp * math.Exp(factor*pct) |
| 58 | undo := state.DoMove() |
| 59 | energy := state.Energy() |
| 60 | change := energy - previousEnergy |
| 61 | if change > 0 && math.Exp(-change/temp) < rand.Float64() { |
| 62 | state.UndoMove(undo) |
| 63 | } else { |
| 64 | previousEnergy = energy |
| 65 | if energy < bestEnergy { |
| 66 | // pct := float64(step*100) / float64(steps) |
| 67 | // fmt.Printf("step: %d of %d (%.1f%%), temp: %.3f, energy: %.6f\n", |
| 68 | // step, steps, pct, temp, energy) |
| 69 | bestEnergy = energy |
| 70 | bestState = state.Copy() |
| 71 | } |
| 72 | } |
| 73 | } |
| 74 | return bestState |
| 75 | } |