Evocosm - A C++ Framework for Evolutionary Computing

Main Index

Created by Scott Robert Ladd at Coyote Gulch Productions.


fsm.h
1 //---------------------------------------------------------------------
2 // Algorithmic Conjurings @ http://www.coyotegulch.com
3 // Evocosm -- An Object-Oriented Framework for Evolutionary Algorithms
4 //
5 // fsm.h
6 //---------------------------------------------------------------------
7 //
8 // Copyright 1996, 1999, 2002, 2003, 2004, 2005, 2006, 2007 Scott Robert Ladd
9 //
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
14 //
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the
22 // Free Software Foundation, Inc.
23 // 59 Temple Place - Suite 330
24 // Boston, MA 02111-1307, USA.
25 //
26 //-----------------------------------------------------------------------
27 //
28 // For more information on this software package, please visit
29 // Scott's web site, Coyote Gulch Productions, at:
30 //
31 // http://www.coyotegulch.com
32 //
33 //-----------------------------------------------------------------------
34 
35 #if !defined(LIBEVOCOSM_FSM_H)
36 #define LIBEVOCOSM_FSM_H
37 
38 // Standard C++ Library
39 #include <cstddef>
40 #include <vector>
41 #include <map>
42 #include <stack>
43 #include <stdexcept>
44 using namespace std;
45 
46 // libevocosm
47 #include "evocommon.h"
48 #include "roulette.h"
49 #include "fsm_tools.h"
50 
51 namespace libevocosm
52 {
54 
68  template <typename InputT, typename OutputT>
69  class fsm : protected globals, protected fsm_tools
70  {
71  public:
73  typedef InputT t_input;
74 
76  typedef OutputT t_output;
77 
79  typedef typename std::pair<t_output, size_t> t_transition;
80 
82  typedef typename std::map<t_input, t_transition> t_input_map;
83 
85  typedef typename std::vector<t_input_map> t_state_table;
86 
88 
95  fsm(size_t a_size, const std::vector<t_input> & a_inputs, const std::vector<t_output> & a_outputs);
96 
98 
107  fsm(const fsm<InputT,OutputT> & a_parent1, const fsm<InputT,OutputT> & a_parent2);
108 
110 
114  fsm(const fsm<InputT,OutputT> & a_source);
115 
117 
121  virtual ~fsm();
122 
123  // Assignment
128  fsm & operator = (const fsm<InputT,OutputT> & a_source);
129 
131 
146  void mutate(double a_rate, const std::vector<t_input> & a_inputs, const std::vector<t_output> & a_outputs, mutation_selector & a_selector = g_default_selector);
147 
149 
154  t_output transition(const fsm<InputT,OutputT>::t_input & a_input);
155 
157 
160  void reset();
161 
163 
168  t_state_table get_table() const;
169 
171 
175  size_t get_init_state() const;
176 
178 
182  size_t get_current_state() const;
183 
184  protected:
186  t_state_table m_state_table;
187 
189  size_t m_size;
190 
192  size_t m_init_state;
193 
196 
199 
200  private:
201  // create a state map
202  t_input_map create_input_map(const std::vector<t_input> & a_inputs, const std::vector<t_output> & a_outputs);
203  };
204 
205  // Static initializer
206  template <typename InputT, typename OutputT>
208 
209  // Creation constructor
210  template <typename InputT, typename OutputT>
211  fsm<InputT,OutputT>::fsm(size_t a_size, const std::vector<t_input> & a_inputs, const std::vector<t_output> & a_outputs)
212  : m_state_table(),
213  m_init_state(0),
214  m_current_state(0),
215  m_size(a_size)
216  {
217  // verify parameters
218  if ((a_size < 2) || (a_inputs.size() < 1) || (a_outputs.size() < 1))
219  throw std::runtime_error("invalid fsm creation parameters");
220 
221  for (size_t n = 0; n < m_size; ++n)
222  {
223  // add input map to state table
224  m_state_table.push_back(create_input_map(a_inputs,a_outputs));
225  }
226 
227  // set initial state and start there
228  m_init_state = rand_index(m_size);
230  }
231 
232  // Construct via bisexual crossover
233  template <typename InputT, typename OutputT>
235  : m_state_table(a_parent1.m_state_table),
236  m_init_state(0),
237  m_current_state(0),
238  m_size(0)
239  {
240  size_t n;
241 
242  // don't do anything else if fsms differ is size
243  if (a_parent1.m_size != a_parent2.m_size)
244  return;
245 
246  // replace states from those in second parent 50/50 chance
247  for (size_t n = 0; n < m_size; ++n)
248  {
249  if (g_random.get_real() > 0.5)
250  m_state_table[n] = a_parent2.m_state_table[n];
251  }
252 
253  // calculate the size
254  m_size = m_state_table.size();
255 
256  // randomize the initial state (looks like mom and dad but may act like either one!)
257  if (g_random.get_real() < 0.5)
258  m_init_state = a_parent1.m_init_state;
259  else
260  m_init_state = a_parent2.m_init_state;
261 
262  // reset for start
264  }
265 
266  // Copy constructor
267  template <typename InputT, typename OutputT>
269  : m_state_table(a_source.m_state_table),
270  m_init_state(a_source.m_init_state),
271  m_current_state(a_source.m_current_state),
272  m_size(a_source.m_size)
273  {
274  // nada
275  }
276 
277  // Virtual destructor
278  template <typename InputT, typename OutputT>
280  {
281  // nada
282  }
283 
284  // Assignment
285  template <typename InputT, typename OutputT>
287  {
288  if (this != &a_source)
289  {
290  m_state_table = a_source.m_state_table;
291  m_init_state = a_source.m_init_state;
292  m_current_state = a_source.m_current_state;
293  m_size = a_source.m_size;
294  }
295 
296  return *this;
297  }
298 
299  // Mutation
300  template <typename InputT, typename OutputT>
301  void fsm<InputT,OutputT>::mutate(double a_rate,
302  const std::vector<t_input> & a_inputs,
303  const std::vector<t_output> & a_outputs,
304  mutation_selector & a_selector)
305  {
306  if (g_random.get_real() < a_rate)
307  {
308  // pick a mutation
309  switch (a_selector.get_index())
310  {
311  case MUTATE_OUTPUT_SYMBOL:
312  {
313  // mutate output symbol
314  size_t state = rand_index(m_size);
315  size_t input = rand_index(a_inputs.size());
316  size_t output = rand_index(a_outputs.size());
317  m_state_table[state][a_inputs[input]].first = a_outputs[output];
318  break;
319  }
320  case MUTATE_TRANSITION:
321  {
322  // mutate state transition
323  size_t state = rand_index(m_size);
324  size_t input = rand_index(a_inputs.size());
325  size_t new_state = rand_index(m_size);
326  m_state_table[state][a_inputs[input]].second = new_state;
327  break;
328  }
329  case MUTATE_REPLACE_STATE:
330  {
331  // select state
332  size_t state = rand_index(m_size);
333  m_state_table[state] = create_input_map(a_inputs,a_outputs);
334  }
335  case MUTATE_SWAP_STATES:
336  {
337  // swap two states
338  size_t state1 = rand_index(m_size);
339  size_t state2;
340 
341  do
342  state2 = rand_index(m_size);
343  while (state2 == state1);
344 
345  t_input_map temp = m_state_table[state1];
346  m_state_table[state1] = m_state_table[state2];
347  m_state_table[state2] = temp;
348  break;
349  }
350  case MUTATE_INIT_STATE:
351  {
352  // change initial state
353  m_init_state = rand_index(m_size);
354  break;
355  }
356  }
357  }
358 
359  // reset current state because init state may have changed
360  m_current_state = m_init_state;
361  }
362 
363  // Cause state transition
364  template <typename InputT, typename OutputT>
366  {
367  // get transition state
368  t_transition & trans = m_state_table[m_current_state][a_input];
369 
370  // change to new state
371  m_current_state = trans.second;
372 
373  // return output symbol
374  return trans.first;
375  }
376 
377  // Reset to start-up state
378  template <typename InputT, typename OutputT>
380  {
381  m_current_state = m_init_state;
382  }
383 
384  // Get a copy of the internal table
385  template <typename InputT, typename OutputT>
387  {
388  return m_state_table;
389  }
390 
391  // Get initial state
392  template <typename InputT, typename OutputT>
394  {
395  return m_init_state;
396  }
397 
398  // Get current state
399  template <typename InputT, typename OutputT>
401  {
402  return m_current_state;
403  }
404 
405  // create a state map
406  template <typename InputT, typename OutputT>
407  typename fsm<InputT,OutputT>::t_input_map fsm<InputT,OutputT>::create_input_map(const std::vector<t_input> & a_inputs, const std::vector<t_output> & a_outputs)
408  {
409  // maximum output index
410  size_t max_output = a_outputs.size();
411 
412  // create an input map for this state
413  t_input_map input_map;
414 
415  // for each input, define an output and a state transition
416  for (typename std::vector<t_input>::const_iterator input = a_inputs.begin(); input != a_inputs.end(); ++input)
417  {
418  // pick a random output symbol and new state
419  t_output out_symbol = a_outputs[rand_index(max_output)];
420  size_t new_state = rand_index(m_size);
421 
422  // add transition data to map
423  input_map[*input] = std::make_pair(out_symbol,new_state);
424  }
425 
426  return input_map;
427  }
428 };
429 
430 #endif
void reset()
Reset to start-up state.
Definition: fsm.h:379
Wraps a roulette wheel for selecting mutations.
Definition: fsm_tools.h:77
std::vector< t_input_map > t_state_table
State table (the machine)
Definition: fsm.h:85
std::pair< t_output, size_t > t_transition
Type of a transition.
Definition: fsm.h:79
fsm(size_t a_size, const std::vector< t_input > &a_inputs, const std::vector< t_output > &a_outputs)
Creation constructor.
Definition: fsm.h:211
size_t m_current_state
Current state.
Definition: fsm.h:195
virtual ~fsm()
Virtual destructor.
Definition: fsm.h:279
static size_t rand_index(size_t n)
Static function to allow use of g_random function pointer in random_shuffle.
Definition: evocommon.h:119
A set of common tools for finite state machines.
Definition: fsm_tools.h:47
size_t get_current_state() const
Get current state.
Definition: fsm.h:400
double get_real()
get the next value in the range [0,1)
Definition: evocommon.h:104
static mutation_selector g_default_selector
A static, default mutation selector.
Definition: fsm.h:198
static prng g_random
A shared random number generator.
Definition: evocommon.h:125
A finite state machine.
Definition: fsm.h:69
size_t get_init_state() const
Get initial state.
Definition: fsm.h:393
A toolkit and framework for implementing evolutionary algorithms.
Definition: evocommon.h:60
t_output transition(const fsm< InputT, OutputT >::t_input &a_input)
Cause state transition.
Definition: fsm.h:365
std::map< t_input, t_transition > t_input_map
Mapping inputs to outputs and state transitions.
Definition: fsm.h:82
fsm & operator=(const fsm< InputT, OutputT > &a_source)
Definition: fsm.h:286
InputT t_input
Exported input type.
Definition: fsm.h:73
size_t m_size
Number of states.
Definition: fsm.h:189
Elements shared by all classes in Evocosm.
Definition: evocommon.h:115
t_state_table m_state_table
State table (the machine definition)
Definition: fsm.h:186
OutputT t_output
Exported output type.
Definition: fsm.h:76
t_state_table get_table() const
Get a copy of the internal table.
Definition: fsm.h:386
size_t m_init_state
Initial state.
Definition: fsm.h:192
size_t get_index() const
Get a mutation index.
Definition: fsm_tools.h:141
void mutate(double a_rate, const std::vector< t_input > &a_inputs, const std::vector< t_output > &a_outputs, mutation_selector &a_selector=g_default_selector)
Mutation.
Definition: fsm.h:301

© 1996-2005 Scott Robert Ladd. All rights reserved.
HTML documentation generated by Dimitri van Heesch's excellent Doxygen tool.