The Fib multimedia system
Fib is a system for storing multimedia data (like images or films).
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cEnviroment.h
Go to the documentation of this file.
1 /**
2  * @file cEnviroment
3  * file name: cEnviroment.h
4  * @author Betti Oesterholz
5  * @date 15.03.2010
6  * @mail webmaster@BioKom.info
7  *
8  * System: C++
9  *
10  * This header specifies a class for the enviroment.
11  * Copyright (C) @c GPL3 2010 Betti Oesterholz
12  *
13  * This program is free software: you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License (GPL) as
15  * published by the Free Software Foundation, either version 3 of the
16  * License, or any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program. If not, see <http://www.gnu.org/licenses/>.
25  *
26  *
27  * This header specifies a class for the enviroment.
28  * The enviroment is an genetic algorithm for optimizing individuals.
29  * It is generic, so the kind of optimized individuals and what
30  * optimization means is easy changebel.
31  * The enviroment contains a number of individuals (the population).
32  * It calls operations to create new, better individuals. The operators,
33  * from which operations are created, are seperated from the enviroment
34  * and are classes which are descendants of the class @see cOperation .
35  * The enviroment contains a number of methods for the operations, with
36  * which the operations can get the information they need to create a new
37  * individual and insert it into the enviroment.
38  * Beside this the enviroment works with a number of classes /parameters
39  * with wich it's behaviour is changed.
40  * @pattern Singleton
41  *
42  */
43 /*
44 History:
45 15.03.2010 Oesterholz created
46 15.03.2012 Oesterholz changes for windows compatibility
47 */
48 
49 #ifndef ___C_ENVIROMENT_H__
50 #define ___C_ENVIROMENT_H__
51 
52 #include "version.h"
53 
54 #include "cIndividual.h"
55 #include "cIndividualInfo.h"
56 #include "cOperation.h"
57 
58 
59 #include <ctime>
60 #include <list>
61 #include <set>
62 #include <map>
63 
64 #ifdef WINDOWS
65  #include <windows.h>
66 #endif //WINDOWS
67 
68 
69 using namespace std;
70 
71 namespace enviroment{
72 
73 class cInitEnviroment;//cyclic dependencie
74 class cEndConditionCheck;//cyclic dependencie
75 class cResourceCheck;//cyclic dependencie
76 class cIndividualSelection;//cyclic dependencie
77 class cMaximumReached;//cyclic dependencie
78 class cSelectIndividualToDelete;//cyclic dependencie
79 class cOperatorFitnessAlgorithm;//cyclic dependencie
80 class cChoosOperator;//cyclic dependencie
81 
82 /**
83  * Internal class for a better individual handling.
84  */
85 class cIndividualInformation;
86 
87 /**
88  * Internal class for handling the operation information.
89  */
90 class cOperationInformation;
91 
92 
93 /**
94  * Listener interface for listening for new or deleted individuals.
95  *
96  * @see cEnviroment::registerIndividualListener()
97  * @see cEnviroment::unregisterIndividualListener()
98  */
100 public:
101 
102  /**
103  * This method is called if an new individual was added to the enviroment.
104  *
105  * @param pIndividual a pointer to the added individual
106  */
107  virtual void individualAdded( const cIndividual * pIndividual ) = 0;
108 
109  /**
110  * This method is called if an individual was delteted from the enviroment.
111  *
112  * @param pIndividual a pointer to the delteted individual
113  */
114  virtual void individualRemoved( const cIndividual * pIndividual ) = 0;
115 };
116 
117 
119 protected:
120 
121  /**
122  * The identifier for the enviroment/ genetic algorithm.
123  * It should be unique for every enviroment, even on different computers.
124  */
125  static long long lAlgorithmIdentifier;
126 
127  /**
128  * A pointer to the enviroment instance.
129  */
131 
132  /**
133  * The tread for running the enviroment.
134  * @see start()
135  * @see stop()
136  * @see run()
137  */
138 #ifdef WINDOWS
139  static HANDLE pThreadEnviroment;
140 #else //WINDOWS
141  static pthread_t * pThreadEnviroment;
142 #endif //WINDOWS
143 
144  /**
145  * The container for the living individuals in the enviroment.
146  * This field is for better internal handling of individuals.
147  *
148  * initialize with: mapLivingIndividuals( compIndividualFitness )
149  */
150  static map<cIndividualIdentifier, cIndividualInformation > mapLivingIndividuals;
151 
152  /**
153  * A list with pointers to the informations of the living individuals
154  * in the enviroment.
155  */
156  static list<const cIndividualInfo*> liLivingIndividualInfos;
157 
158  /**
159  * If true the list with the living individuals is sorted, else not.
160  */
162 
163  /**
164  * The container for the dead individuals in the enviroment.
165  * This field is for better internal handling of individuals.
166  *
167  * initialize with: mapDeadIndividuals( compIndividualFitness )
168  */
169  static map< cIndividualIdentifier, cIndividualInformation > mapDeadIndividuals;
170 
171  /**
172  * A list with pointers to the informations of the dead individuals
173  * in the enviroment.
174  * This list will allways be sorted with the best individuals (fitness) at the front.
175  */
176  static list<const cIndividualInfo*> liDeadIndividualInfos;
177 
178  /**
179  * If true the list with the living individuals is sorted, else not.
180  */
182 
183  /**
184  * A map with the information for the running operations and the information
185  * for them.
186  */
187  static map< cOperation * , cOperationInformation > mapRunningOperations;
188 
189  /**
190  * A list with the operations which are done and can be deleted.
191  */
192  static list<cOperation*> liOperationsToDelete;
193 
194  /**
195  * The number of operations executed/ called by the enviroment.
196  */
197  static unsigned long long lNumberOfCalledOperations;
198 
199 
200  /**
201  * The time in secounds the enviroment was running.
202  * (@see isRunning() gives back true for this time)
203  */
204  static double dCpuRunTime;
205 
206  /**
207  * The time the the cpu time was evalued the last time.
208  * This variable is for evaluing the cpu time while the enviroemnt runs.
209  */
210  static time_t tmLastCpuRunTime;
211 
212 
213  /**
214  * The time the @see start() method was called the last time.
215  */
216  static time_t tmLastStartTime;
217 
218  /**
219  * The time the @see start() method was called the first time for this
220  * enviroment instance.
221  */
222  static time_t tmFirstStartTime;
223 
224 
225  /**
226  * If true the parameter for the enviroment are set, else not.
227  */
228  static bool bParameterSet;
229 
230  /**
231  * If true the enviroment is running, else not.
232  */
233  static bool bIsRunning;
234 
235  /**
236  * If true the enviroment should be stoped, else not.
237  */
238  static bool bStopFlag;
239 
240 
241  /**
242  * A pointer to the object for initializing the enviroment.
243  */
245 
246  /**
247  * A pointer to the object for evaluing the fitness of individuals
248  * respectively the objects they represents.
249  */
251 
252  /**
253  * A pointer to the object for checking the endcondition of the
254  * enviroment.
255  */
257 
258  /**
259  * A pointer to the object for selecting a good individual.
260  */
262 
263  /**
264  * A pointer to the object for checking if individuals needs to
265  * be deleted befor adding new individuals.
266  */
268 
269  /**
270  * A pointer to the object for selecting a bad individual.
271  */
273 
274  /**
275  * A pointer to the object for evaluing the fitness of operators of
276  * the enviroment and for handling them.
277  */
279 
280  /**
281  * A pointer to the object for selecting a good operator.
282  */
284 
285  /**
286  * A pointer to the object for checking, if more operators could be
287  * started.
288  */
290 
291  /**
292  * This set contains pointers to all objects, which want's to be
293  * notified, if new indeviduals wher inserted into the enviroment or old
294  * wher deleted.
295  * @see clNewIndividualListener
296  */
297  static set<clNewIndividualListener *> setIndividualListener;
298 
299 
300  /**
301  * standardconstructor
302  * This is called in the getInstance() method.
303  */
304  cEnviroment();
305 
306 public:
307 
308  /**
309  * destructor
310  */
311  virtual ~cEnviroment();
312 
313  /**
314  * The type of individuals on which the enviroment will run.
315  */
316  const std::string OPERATION_DOMAIN;
317 
318  /**
319  * This method returns a pointer to an instance of the enviroment/
320  * genetic algorithm, if the parameters are set.
321  *
322  * @see setParameter()
323  * @return pointer to an instance of the enviroment/
324  * genetic algorithm, if the parameters are set, else NULL
325  */
326  static cEnviroment * getInstance();
327 
328  /**
329  * This method sets the parameters for the enviroment.
330  * You can't create an instance of the enviroment, if the parameters
331  * aren't set correctly.
332  * All parameters are copied for the use in the enviroment.
333  *
334  * @see bParameterSet
335  * @see getInstance()
336  * @param pInInit A pointer to the object for initializing the
337  * enviroment. If NULL the initializing object isn't changed.
338  * @see pInitEnviroment
339  * @param pInObjectFitnessAlgorithm A pointer to the object for
340  * evaluing the fitness of individuals (respectively the objects
341  * they represents). If NULL the object for evaluing the fitnes isn't
342  * changed. Make sure this object /algorithm has an original
343  * individual set, else setParameter() will return false.
344  * @see pObjectFitnessAlgorithm
345  * @param pInEndCondition A pointer to the object for checking the
346  * endcondition of the enviroment. If Null (standardvalue)
347  * and no object for checking the endcondition exists an
348  * cEndConditionCheck object is taken to be the endcondition, else,
349  * if an object for checking the endcondition exists, it isn't changed.
350  * @see pEndCondition and @see cEndConditionCheck
351  * @param pInIndividualSelection A pointer to the object for selecting
352  * a good individual. If Null (standardvalue) and no object for
353  * selecting a good individual exists an
354  * @see pInIndividualSelectionWeel object is taken for selection,
355  * else, if an object for selecting a good individual exists, it
356  * isn't changed.
357  * @see pIndividualSelection
358  * @param pInMaximumIndividuals A pointer to the object for checking if
359  * individuals needs to be deleted befor adding new individuals.
360  * If Null (standardvalue) and no object for checking the maximal
361  * individuals exists an @see cMaximumReached object is taken for
362  * checking if the maximum number of individuals wher reached, else,
363  * if an object for checking the maximum number of individuals
364  * exists, it isn't changed.
365  * @see pMaximumIndividuals
366  * @param pInSelectIndividualToDelete A pointer to the object for
367  * selecting a bad individual. If Null (standardvalue) and no object
368  * for selecting a bad individual exists an
369  * @see cSelectIndividualToDeleteWeel object is taken for selection,
370  * else, if an object for selecting a bad individual exists, it
371  * isn't changed.
372  * @see pSelectIndividualToDelete
373  * @param pInOperationFitnessAlgorithmus A pointer to the object for
374  * evaluing the fitness of operators of the enviroment and for
375  * handling them. If Null (standardvalue) and no object
376  * for evaluing the fitness of operators exists an
377  * @see cOperatorFitnessAlgorithmBasic object is taken for handling
378  * the operators, else, if an object for evaluing the fitness of
379  * the operators exists, it isn't changed.
380  * @see pOperationFitnessAlgorithmus
381  * @param pInChoosOperator A pointer to the object for selecting a good
382  * operator. If Null (standardvalue) and no object for selecting a
383  * good operator exists an @see cChoosOperator object is taken for
384  * for selecting an operator, else, if an object for choosing good
385  * operator exists, it isn't changed.
386  * @see pChoosOperator
387  * @param pInResourceCheck A pointer to the object for checking if more
388  * operators could be started. If Null (standardvalue) and no object
389  * for checking if more operators could be started exists an
390  * @see cResourceCheck object is taken for the check, else, if an
391  * object for checking if more operators could be started exists, it
392  * isn't changed.
393  * @see pResourceCheck
394  * @return if all parameter could be set true, else false;
395  * if true was returned, @see getInstance() will return a enviroment
396  * instance, elso it will return NULL
397  */
398  static bool setParameter( const cInitEnviroment * pInInit,
399  const cObjectFitnessAlgorithm * pInObjectFitnessAlgorithm,
400  const cEndConditionCheck * pInEndCondition = NULL ,
401  const cIndividualSelection * pInIndividualSelection = NULL,
402  const cMaximumReached * pInMaximumIndividuals = NULL,
403  const cSelectIndividualToDelete * pInSelectIndividualToDelete = NULL,
404  const cOperatorFitnessAlgorithm * pInOperationFitnessAlgorithmus = NULL,
405  const cChoosOperator * pInChoosOperator = NULL,
406  const cResourceCheck * pInResourceCheck = NULL );
407 
408  /**
409  * This method starts the enviroment and returns, without waiting
410  * that the enviroment halts.
411  * The method run() will do the work of the enviroment. So overwrite
412  * the method run() if you wan't to change the behavour of the
413  * enviroment and not this method.
414  *
415  * @see run()
416  * @see stop()
417  * @see isRunning()
418  * @return true if the enviroment was started, else false
419  */
420  bool start();
421 
422  /**
423  * This method runs the enviroment.
424  * It will wait till the enviroment is ended befor returning.
425  * This method will do the work of the enviroment.
426  *
427  * @see start()
428  * @see stop()
429  * @see setIsRunning()
430  * @return true if the operation was started
431  */
432  virtual bool run();
433 
434  /**
435  * This method stops the enviroment and returns when it halted.
436  *
437  * @see run()
438  * @see start()
439  * @see isRunning()
440  * @return true if the enviroment was stoped, else false
441  */
442  virtual bool stop();
443 
444  /**
445  * @see start()
446  * @see stop()
447  * @return true if the enviroment is running, else false
448  */
449  virtual bool isRunning() const;
450 
451  /**
452  * @see lAlgorithmIdentifier
453  * @return The identifier for the enviroment/ genetic algorithm.
454  */
455  unsigned long long getAlgorithmIdentifier();
456 
457  /**
458  * This method returns the information about individuals in the enviroment.
459  *
460  * @param iLive a number which indicate of which kind the individuals
461  * should be, from which the information is to be returned;
462  * possible values:
463  * 0 : return the informations of all individuals in the
464  * enviroment, regardless if they are living or not
465  * 1 : return the information just of living individuals
466  * -1: return the information just of dead individuals
467  * else: an empty list is to be returned; reserved for future
468  * use, please don't use this
469  * @return a list with pointers to the information about the individuals
470  */
471  list<const cIndividualInfo*> getIndividualInfos( short iLive = 0 ) const;
472 
473  /**
474  * This method returns the information for the individual with the
475  * given identifier.
476  *
477  * @param identifier the identifier for the individual, for which the
478  * information is to be returned
479  * @return a pointer to the information for the individual with the
480  * given identifier or NULL, if non exists
481  */
482  const cIndividualInfo * getIndividualInfo(
483  const cIndividualIdentifier & identifier ) const;
484 
485  /**
486  * This method returns the information for the lNumber'th best
487  * individual.
488  *
489  * @param lNumber the number of the individual to return
490  * @param iLive a number which indicate of which kind the individual
491  * should be, from which the information is to be returned;
492  * possible values:
493  * 0 : search the informations of all individuals in the
494  * enviroment, regardless if they are living or not
495  * 1 : search return the information just of living individuals
496  * -1: search return the information just of dead individuals
497  * else: an empty list is to be returned; reserved for future
498  * use, please don't use this
499  * @return a pointer to the information for the lNumber'th best
500  * individual or NULL, if non such exists
501  */
502  const cIndividualInfo * getBestIndividualInfo( unsigned long lNumber = 1,
503  short iLive = 1 ) const;
504 
505  /**
506  * This method returns a good individual from the enviroment.
507  * The selection is done by the @see pIndividualSelection object.
508  * Beware: You have to care for, that the returned individual gets
509  * deleted after usage.
510  *
511  * @see pIndividualSelection
512  * @see cIndividualSelection
513  * @return a pointer to a good individual
514  */
515  cIndividual * getIndividual() const;
516 
517  /**
518  * This method returns the the individual with the given identifier.
519  * Beware: You have to care for, that the returned individual gets
520  * deleted after usage.
521  *
522  * @param identifier the identifier for the individual which is to be returned
523  * @return a pointer to the individual with the given identifier or
524  * NULL, if non exists
525  */
526  cIndividual * getIndividual( const cIndividualIdentifier & identifier ) const;
527 
528  /**
529  * This method returns the lNumber'th best individual.
530  * Beware: You have to care for, that the returned individual gets
531  * deleted after usage.
532  *
533  * @param lNumber the number for the individual to return
534  * @return a pointer to the lNumber'th best individual or NULL, if non
535  * such exists
536  */
537  cIndividual * getBestIndividual( unsigned long lNumber = 1 ) const;
538 
539  /**
540  * @return A pointer to the object for evaluing the fitness of
541  * individuals (respectively the objects they represents).
542  * @see pObjectFitnessAlgorithm
543  */
544  static const cObjectFitnessAlgorithm * getFitnessAlgorithm();
545 
546  /**
547  * This method inserts a copy of the given living individual into the
548  * enviroment.
549  * The type of the individual has to be correct for this enviroment and
550  * the individual has to be correct for inserting.
551  *
552  * @param pInIndividual a pointer to the individual to insert
553  * @param pProducerOperation the operation which produced the individual,
554  * if NULL (standardvalue) no operation gets credit for creating the
555  * individual
556  * @return true if the individual was inserted, else false
557  */
558  bool insertIndividual( const cIndividual * pInIndividual,
559  const cOperation * pProducerOperation = NULL );
560 
561  /**
562  * This method returns the number of individuals in the enviroment.
563  *
564  * @param iLive a number which indicate of which kind the individuals
565  * should be, which are counted;
566  * possible values:
567  * 0 : return the count of all individuals in the enviroment,
568  * regardless if they are living or not
569  * 1 : return the count just of living individuals
570  * -1: return the count just of dead individuals
571  * else: 0 is to be returned; reserved for future use, please
572  * don't use this
573  * @return the count of the individuals of the given type
574  */
575  unsigned long getNumberOfIndividuals( short iLive = 1 );
576 
577 
578 /*the following methods are not for the operations, but for the help
579 classes/ objects of the enviroment (e.g. cMaximumReached)*/
580 
581  /**
582  * @return the number of operations, which run at the time
583  */
584  unsigned int getNumberOfRunningOperations();
585 
586  /**
587  * @return the number of operations executed /called by the enviroment
588  * @see lNumberOfCalledOperations
589  */
590  unsigned long getNumberOfCalledOperations();
591 
592  /**
593  * @return the time in secounds the enviroment was running;
594  * @see isRunning() gives back true for this time
595  */
596  double getCpuRunTime() const;
597 
598  /**
599  * @return the time the @see start() method was called the last time
600  * or 0, if non such exists
601  */
602  time_t getLastStartTime() const;
603 
604  /**
605  * @return the time the @see start() method was called the first time
606  * for this enviroment or 0, if non such exists
607  */
608  time_t getFirstStartTime() const;
609 
610 
611  /**
612  * @return a pointer to the object for initializing the enviroment
613  * or NULL, if non such exists; @see pInitEnviroment
614  */
615  static const cInitEnviroment * getInitEnviroment();
616 
617  /**
618  * @return a pointer to the object for checking the endcondition of
619  * the enviroment or NULL, if non such exists; @see pEndCondition
620  */
621  static const cEndConditionCheck * getEndConditionCheck();
622 
623  /**
624  * @return a pointer to the object for selecting a good individual or
625  * NULL, if non such exists; @see pIndividualSelection
626  */
627  static const cIndividualSelection * getIndividualSelection();
628 
629  /**
630  * @return a pointer to the object for checking if individuals needs to
631  * be deleted befor adding new individuals or NULL, if non such
632  * exists; @see pMaximumIndividuals
633  */
634  static const cMaximumReached * getMaximumReached();
635 
636  /**
637  * @return a pointer to the object for selecting a bad individual or
638  * NULL, if non such exists; @see pSelectIndividualToDelete
639  */
640  static const cSelectIndividualToDelete * getSelectIndividualToDelete();
641 
642  /**
643  * @return a pointer to the object for evaluing the fitness of
644  * operators of the enviroment and for handling them or NULL, if non
645  * such exists; @see pOperationFitnessAlgorithmus
646  */
647  static cOperatorFitnessAlgorithm * getOperatorFitnessAlgorithm();
648 
649  /**
650  * @return a pointer to the object for selecting a good operator or
651  * NULL, if non such exists; @see pChoosOperator
652  */
653  static const cChoosOperator * getChoosOperator();
654 
655 
656  /**
657  * @return a pointer to the object for checking if more operators could
658  * be started or NULL, if non such exists; @see pResourceCheck
659  */
660  static const cResourceCheck * getResourceCheck();
661 
662 
663  /**
664  * This method adds the given individual listener object to the set
665  * of individual listener objects. Listeners of the set gets notified
666  * if new indeviduals wher inserted into the enviroment or old wher
667  * deleted.
668  *
669  * @see unregisterIndividualListener()
670  * @see setIndividualListener
671  * @see clNewIndividualListener
672  * @param individualListener a pointer to the individual listener
673  * object to add to the set of individual listeners
674  * @return true if the individual listener was added, else false
675  */
676  bool registerIndividualListener( clNewIndividualListener * individualListener );
677 
678  /**
679  * This method removes the given individual listener object from the set
680  * of individual listener objects. Listeners of the set gets notified
681  * if new indeviduals wher inserted into the enviroment or old wher
682  * deleted.
683  *
684  * @see registerIndividualListener()
685  * @see setIndividualListener
686  * @see clNewIndividualListener
687  * @param individualListener a pointer to the individual listener
688  * object to removes from the set of individual listeners
689  * @return true if the individual listener was removed, else false
690  */
691  bool unregisterIndividualListener( clNewIndividualListener * individualListener );
692 
693  /**
694  * This method is called, if the running status of the operation is changed.
695  *
696  * @see cOperation::bIsRunning
697  * @see cOperation::isRunning()
698  * @param pOperation a pointer to the operation, which status has changed
699  * @param isRunning the new running status for the operation
700  */
701  void operationStatusChange( cOperation * pOperation, bool isRunning );
702 
703 #ifndef TEST
704 protected:
705 #endif
706  /**
707  * This method removes the given individual from the enviroment and
708  * delets it.
709  *
710  * @param pInIndividual a pointer to the individual to delete
711  * @return true if the given individual was deleted, else false
712  */
713  bool removeIndividual( const cIndividualIdentifier pInIndividual );
714 
715 
716 private:
717 
718  /**
719  * This method stop the operation for a tread.
720  * It will wait till the operation is stoped befor returning.
721  *
722  * @see stop()
723  * @param inputArg a pointer to the operation to stop
724  */
725  static void * stopOperation( void * inputArg );
726 
727  /**
728  * This method will delete all operations which are done (respectively
729  * stored in the @see liOperationsToDelete ).
730  */
731  void deleteNotRunningOperations();
732 
733  /**
734  * This method runs the enviroment for a tread.
735  * It will wait till the operation is ended befor returning.
736  * It will simply call run().
737  *
738  * @see run()
739  * @see start()
740  * @see stop()
741  */
742  static void * runTread( void * inputArg );
743 
744 #ifdef WINDOWS
745  /**
746  * Wraper function for windows.
747  * Wait till the given mutex is free and than locks it.
748  * @param pMutexHandle pointer to the mutex to lock.
749  */
750  static void pthread_mutex_lock( HANDLE * pMutexHandle );
751 
752  /**
753  * Wraper function for windows.
754  * Unlocks the given mutex.
755  * @param pMutexHandle pointer to the mutex to unlock.
756  */
757  static void pthread_mutex_unlock( HANDLE * pMutexHandle );
758 #endif //WINDOWS
759 
760  /**
761  * This function sleeps for a short period.
762  */
763  static void shortSleep();
764 
765 };//end class cEnviroment
766 
767 
768 };//end namespace enviroment
769 
770 #endif //___C_ENVIROMENT_H__
771 
772 
773 
774 
775 
776 
777