e2rcore/implement/math/
sim_anneal.rs1extern crate rand;
2
3use std::f32;
4use self::rand::distributions::{IndependentSample, Range};
5
6pub fn compute_discrete< F0, F1, F2 >( domain: &[ f32 ], candidate_generator: F0, temperature_function: F1, energy_function: F2, max_iter: usize, initial: usize ) -> usize
7 where F0: Fn( &[ f32 ], usize ) -> ( usize ), F1: Fn( f32 ) -> f32, F2: Fn( &[ f32 ], usize )-> f32
8
9{
10 assert!( initial < domain.len() );
11
12 let between = Range::new(0f32, 1f32);
13 let mut rng = rand::thread_rng();
14
15 let mut state = initial; for i in 0..max_iter {
18 let k = i as f32/ max_iter as f32;
20 let t = temperature_function( k ); let candidate = candidate_generator( &domain[..], i ); let r = between.ind_sample(&mut rng); let e_current = energy_function( &domain[..], state );
24 let e_candidate = energy_function( &domain[..], candidate );
25 let e_diff = e_candidate - e_current; if e_diff < 0f32 { state = candidate;
28 } else { let a = t * e_diff;
30 if a > r {
31 state = candidate;
32 }
33 }
34 }
35 state
36}
37
38pub fn temperature_function_default( fraction: f32 ) -> f32 {
39 assert!( fraction >= 0f32 && fraction <= 1f32 );
40 f32::consts::E.powf( -fraction * 7f32 )
41}
42
43pub fn candidate_generator_default( input: &[f32], _index_current: usize ) -> usize {
44 let between = Range::new(0usize, input.len() );
45 let mut rng = rand::thread_rng();
46 between.ind_sample(&mut rng)
47}
48
49pub fn energy_function_default( input: &[f32], index_current: usize ) -> f32 {
50 let e = input[index_current];
51 assert!( e >= 0f32 );
52 assert!( e <= 1f32 );
53 e
54}