1extern crate aristeia;
16extern crate rand;
17
18use self::Gene::{
19 MovePointerLeft,
20 MovePointerRight,
21 IncreaseValueByOne,
22 DecreaseValueByOne,
23 CopyValueFromLeft,
24 CopyValueFromRight
25};
26use rand::{
27 distributions::{Distribution, Standard},
28 Rng,
29};
30use std::time::Instant;
31use aristeia::agent::{Agent};
32
33use aristeia::manager::create_manager;
34use aristeia::fitness::ScoreError;
35
36
37#[derive(Clone, PartialEq, Hash)]
38enum Gene {
39 MovePointerLeft,
40 MovePointerRight,
41 IncreaseValueByOne,
42 DecreaseValueByOne,
43 CopyValueFromLeft,
44 CopyValueFromRight
45}
46
47pub fn main() {
48 let now = Instant::now();
49
50 let data = vec![0; 10];
51
52 let mut manager = create_manager(fitness_function, data.clone());
53 manager.set_number_of_genes(30, false);
54 manager.run(9999);
55 let agents = manager.get_population().get_agents();
56
57 println!("Duration: {}", now.elapsed().as_secs() as f64 + now.elapsed().subsec_nanos() as f64 * 1e-9);
58 println!("Population: {}", agents.len());
59
60 let mut first = true;
61 let mut first_score = 0;
62
63 for (score_index, agent) in agents.iter().rev() {
64 if first {
65 first = false;
66 first_score = *score_index;
67 }
68 if score_index < &(first_score - 20) {
69 break;
70 }
71 println!("{}", score_index);
72 println!("{:?}", get_processed_data(agent.get_genes(), &data));
73 }
74}
75
76fn get_processed_data(genes: &Vec<Gene>, data: &Vec<u8>) -> Vec<u8> {
77 let mut copy = data.clone();
78 let mut pointer = 0;
79 for gene in genes {
80 match gene {
81 MovePointerLeft => move_pointer_left(&mut pointer, &mut copy),
82 MovePointerRight => move_pointer_right(&mut pointer, &mut copy),
83 IncreaseValueByOne => increase_value_by_one(&mut pointer, &mut copy),
84 DecreaseValueByOne => decrease_value_by_one(&mut pointer, &mut copy),
85 CopyValueFromLeft => copy_value_from_left(&mut pointer, &mut copy),
86 CopyValueFromRight => copy_value_from_right(&mut pointer, &mut copy),
87 }
88 }
89
90 return copy;
91}
92
93fn move_pointer_left(pointer: &mut usize, _data: &mut Vec<u8>) {
94 if *pointer == 0 {
95 return;
96 }
97
98 *pointer -= 1;
99}
100
101fn move_pointer_right(pointer: &mut usize, data: &mut Vec<u8>) {
102 if *pointer == data.len() - 1 {
103 return;
104 }
105
106 *pointer += 1;
107}
108
109fn increase_value_by_one(pointer: &mut usize, data: &mut Vec<u8>) {
110 data[*pointer] += 1;
111}
112
113fn decrease_value_by_one(pointer: &mut usize, data: &mut Vec<u8>) {
114 if data[*pointer] == 0 {
115 return;
116 }
117 data[*pointer] -= 1;
118}
119
120fn copy_value_from_left(pointer: &mut usize, data: &mut Vec<u8>) {
121 if *pointer == 0 {
122 return;
123 }
124
125 data[*pointer] = data[*pointer-1];
126}
127
128fn copy_value_from_right(pointer: &mut usize, data: &mut Vec<u8>) {
129 if *pointer == data.len() - 1 {
130 return;
131 }
132
133 data[*pointer] = data[*pointer+1];
134}
135
136impl Distribution<Gene> for Standard {
137 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Gene {
138 match rng.gen_range(0, 6) {
139 0 => MovePointerLeft,
140 1 => MovePointerRight,
141 2 => IncreaseValueByOne,
142 3 => DecreaseValueByOne,
143 4 => CopyValueFromLeft,
144 _ => CopyValueFromRight
145 }
146 }
147}
148
149fn score_data(candidate: &Vec<u8>) -> u64 {
150 let mut score = 1.0;
151 let candidate_length_squared = candidate.len().pow(2) as f64;
152 let max_loss = 1.0 / candidate_length_squared;
153
154 for i in 1..candidate.len() {
155 let previous = candidate[i - 1];
156 let expected = previous + 1;
157 let value = candidate[i];
158 if value == 0 {
159 score = score - max_loss;
160 continue;
161 }
162
163 let diff = value as f64 - expected as f64;
164 score = score - (diff.abs() / candidate_length_squared);
165
166 if score < 0.0 {
167 score = 0.0;
168 break;
169 }
170 }
171
172 (score * 10000.0) as u64
173}
174
175fn fitness_function(agent: &Agent<Gene>, data: &Vec<u8>) -> Result<u64, ScoreError> {
176 let processed = get_processed_data(agent.get_genes(), data);
177 Ok(score_data(&processed))
178}