genetic_planner/
genetic_planner.rs1extern crate rand;
2use rand::Rand;
3use rand::Rng;
4
5use std::cmp::PartialEq;
6
7use genetic::*;
8
9pub trait State
10 where Self: Sized + Clone + Send + Sync + 'static
11{
12 fn get_initial_state() -> Self;
14 fn get_random_action() -> Action<Self>;
16 fn is_goal(&self) -> bool;
18 fn get_heuristic(&self) -> i32;
20}
21
22pub struct Plan<T>
24 where T: State + Clone + Send + Sync + 'static
25{
26 pub state: T,
29 pub actions: Vec<Action<T>>,
31}
32
33impl<T> Plan<T>
34 where T: State + Clone
35{
36 pub fn new(state: T) -> Plan<T> {
38 Plan {
39 state: state,
40 actions: Vec::new(),
41 }
42 }
43}
44
45#[derive(Clone)]
47pub struct Action<T>
48 where T: State + Clone + Send + Sync + 'static
49{
50 pub action: fn(state: T) -> Option<T>,
51 pub name: String,
52}
53
54impl<T> Rand for Action<T>
55 where T: State + Clone
56{
57 fn rand<R: Rng>(_: &mut R) -> Action<T> {
58 T::get_random_action()
59 }
60}
61
62impl<T> PartialEq for Action<T>
63 where T: State + Clone + Send + Sync + 'static
64{
65 fn eq(&self, other: &Action<T>) -> bool {
66 self.name != other.name
67 }
68}
69
70pub struct PlannerConfiguration {
72 pub max_actions: usize,
74 pub population_size: usize,
76 pub elitism_size: usize,
78 pub tournmant_size: usize,
80 pub uniform_rate: f32,
82 pub mutation_rate: f32,
84 pub threadpool_size: usize,
86}
87
88fn apply_actions<T>(i: Individual<Action<T>>) -> Plan<T>
90 where T: State + Clone + Send + Sync + 'static
91{
92 let mut state = Some(T::get_initial_state());
93 let mut old_state = state.clone();
94 let mut used_actions: Vec<Action<T>> = Vec::new();
95 let mut actions = i.genes.iter();
96 let mut action = actions.next();
97 while action.is_some() && state.clone().is_some() && !state.clone().unwrap().is_goal() {
98 state = (action.clone().unwrap().action)(state.unwrap());
99 if state.clone().is_some() {
100 old_state = state.clone();
101 let tmp = action.clone().unwrap();
102 let last_action = Action {
103 action: tmp.action,
104 name: tmp.name.to_string(),
105 };
106 used_actions.push(last_action);
107 action = actions.next();
108 }
109 }
110 match state {
111 None => {
112 Plan {
113 state: old_state.unwrap(),
114 actions: used_actions,
115 }
116 }
117 Some(sstate) => {
118 Plan {
119 state: sstate,
120 actions: used_actions,
121 }
122 }
123 }
124}
125
126fn fitness_planner<T>(i: Individual<Action<T>>) -> i32
128 where T: State + Clone + Send + Sync + 'static
129{
130 let node = apply_actions(i);
131 -node.state.get_heuristic()
132}
133
134fn get_population_configuration<T>(c: PlannerConfiguration) -> PopulationConfiguration<Action<T>>
136 where T: State + Clone + Send + Sync + 'static
137{
138 PopulationConfiguration {
139 genenumber: c.max_actions,
140 population_size: c.population_size,
141 elitism_size: c.elitism_size,
142 tournmant_size: c.tournmant_size,
143 uniform_rate: c.uniform_rate,
144 mutation_rate: c.mutation_rate,
145 fitness: fitness_planner,
146 threadpool_size: c.threadpool_size,
147 }
148}
149
150pub fn find_solution_and_population_from_population<T>(pop: Population<Action<T>>)
152 -> (Plan<T>, Population<Action<T>>)
153 where T: State + Clone + Send + Sync + 'static
154{
155 let mut pop = pop.clone();
156 let mut best_actions = pop.get_fittest();
157 let mut node: Plan<T> = apply_actions(best_actions.unwrap().0);
158 while !node.state.is_goal() {
159 pop = pop.evolve();
160 best_actions = pop.get_fittest();
161 node = apply_actions(best_actions.unwrap().0);
162 }
163 (Plan {
164 state: node.state,
165 actions: node.actions,
166 },
167 pop)
168}
169
170pub fn find_solution_and_population<T>(c: PlannerConfiguration) -> (Plan<T>, Population<Action<T>>)
172 where T: State + Clone + Send + Sync + 'static
173{
174 let pc = get_population_configuration(c);
175 let pop = Population::new(pc);
176 find_solution_and_population_from_population(pop)
177}
178
179pub fn find_solution<T>(c: PlannerConfiguration) -> Plan<T>
181 where T: State + Clone + Send + Sync + 'static
182{
183 find_solution_and_population(c).0
184}
185
186pub fn find_solution_from_population<T>(pop: Population<Action<T>>) -> Plan<T>
188 where T: State + Clone + Send + Sync + 'static
189{
190 find_solution_and_population_from_population(pop).0
191}
192
193pub fn find_best_and_population_after_iterations_from_population<T>
195 (pop: Population<Action<T>>,
196 iterations: usize)
197 -> (Plan<T>, Population<Action<T>>)
198 where T: State + Clone + Send + Sync + 'static
199{
200 let mut pop = pop.clone();
201 for _ in 0..iterations {
202 pop = pop.evolve();
203 }
204 let best_actions = pop.get_fittest();
205 let node = apply_actions(best_actions.unwrap().0);
206 (Plan {
207 state: node.state,
208 actions: node.actions,
209 },
210 pop)
211}
212
213pub fn find_best_and_population_after_iterations<T>(c: PlannerConfiguration,
215 iterations: usize)
216 -> (Plan<T>, Population<Action<T>>)
217 where T: State + Clone + Send + Sync + 'static
218{
219 let pc = get_population_configuration(c);
220 let pop = Population::new(pc);
221 find_best_and_population_after_iterations_from_population(pop, iterations)
222}
223
224pub fn find_best_after_iterations<T>(c: PlannerConfiguration, iterations: usize) -> Plan<T>
226 where T: State + Clone + Send + Sync + 'static
227{
228 find_best_and_population_after_iterations(c, iterations).0
229}
230
231pub fn find_best_after_iterations_from_population<T>(pop: Population<Action<T>>,
233 iterations: usize)
234 -> Plan<T>
235 where T: State + Clone + Send + Sync + 'static
236{
237 find_best_and_population_after_iterations_from_population(pop, iterations).0
238}