📄 gpkernel_1.html
字号:
<HTML><HEAD><!-- This HTML file has been created by texi2html 1.51 from gpkernel.texi on 3 July 1997 --><TITLE>Genetic Programming Kernel Version 0.5.2 - 1 The Genetic Programming Kernel</TITLE></HEAD><BODY>Go to the first, previous, <A HREF="gpkernel_2.html">next</A>, <A HREF="gpkernel_3.html">last</A> section, <A HREF="gpkernel_toc.html">table of contents</A>.<P><HR><P><P>Copyright (C) 1997 Thomas Weinbrenner (thomasw@emk.e-technik.th-darmstadt.de)Copyright Licence: GNU General Public Licence</P><H1><A NAME="SEC1" HREF="gpkernel_toc.html#TOC1">1 The Genetic Programming Kernel</A></H1><P><A NAME="IDX1"></A></P><P>This section documents the Genetic Programming kernel. It is written inC++ and based upon version 0.4 of gpc++ by Adam Fraser. The GP kernelis a C++ class library that can be used to apply genetic programmingtechniques to all kinds of problems. An integral component is theability to produce automatically defined functions as found in Koza's"Genetic Programming II". It has been extensively modified and is now asafe and widely usable tool for a wide range of problems that make useof the Genetic Programming technique.</P><P>The software package comes as a library and defines several classeswith a certain hierarchy. The software makes use of the objectoriented programming scheme, therefore it need not be modified toadapt the system to a specific problem. This is done by inheritingclasses and providing the appropriate virtual functions. These arethe features:</P><UL><LI>Automatically defined functions (ADFs).<LI>Tournament and fitness proportionate selection.<LI>Demetic grouping, independent of the selection type.<LI>Optional steady state Genetic Programming kernel (like the Adam Fraser code).<LI>Subtree crossover.<LI>Swap and shrink mutation.<LI>Multiple populations possible.<LI>System parameters can be changed without recompilation.<LI>Improved random number generator. Population sizes of over 250000 are possible now.<LI>Loading and saving of a population.</UL><P>To understand how the library works, it is important for the user toread Section section <A HREF="gpkernel_1.html#SEC3">1.2 The Class Hierarchy</A> and section <A HREF="gpkernel_1.html#SEC4">1.3 Underlying Class definitions</A>. The first deals with the hierarchy of all definedclasses, and the second with the two important base classes<EM>GPObject</EM> and <EM>GPContainer</EM>.</P><H2><A NAME="SEC2" HREF="gpkernel_toc.html#TOC2">1.1 License</A></H2><A HREF="http://www.emk.e-technik.th-darmstadt.de/~thomasw"> (C) Thomas Weinbrenner </A> <P><P>This library is free software; you can redistribute it and/or modify itunder the terms of the GNU General Public License as published by theFree Software Foundation; either version 1, or (at your option) anylater version.</P><P>This library is distributed in the hope that it will be useful, but<STRONG>without any warranty</STRONG>; without even the implied warranty of<STRONG>merchantability or fitness for a particular purpose</STRONG>. See theGNU General Public License for more details.</P><P>You should have received a copy of the GNU General Public License alongwith this software; if not, write to the Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.</P><H2><A NAME="SEC3" HREF="gpkernel_toc.html#TOC3">1.2 The Class Hierarchy</A></H2><P>The class hierarchy used for the Genetic Programming system is basedupon the abstract class <EM>GPObject</EM>. All classes inherit directlyor indirectly from this class. A very important class is<EM>GPContainer</EM> as it implements a container that is used for nearlyall other classes. The classes <EM>GPNode</EM>, <EM>GPNodeSet</EM> and<EM>GPAdfNodeSet</EM> are used to describe the functions and terminals forthe population. The classes <EM>GPGene</EM>, <EM>GP</EM> and<EM>GPPopulation</EM> implement the genetic tree structure, thedescription of a genetic program and of a whole population. The class<EM>GPVariables</EM> is separate; it is used to hold importantconfiguration variables for the population.</P><P>The figure illustrates inheritance hierarchy and shows the type ofobject the classes contain. For example: <EM>GPNode</EM>,<EM>GPContainer</EM> and <EM>GPVariables</EM> inherit from class<EM>GPObject</EM>, all other classes inherit from <EM>GPContainer</EM>. Apopulation contains genetic programs, a genetic program contains one ormore genetic trees (the main tree and the ADFs) represented by the rootgene, and a gene contains its children, if any.</P><IMG SRC="images/hierarchy.gif" ALT="Class hierarchy"ALIGN="CENTER"> <BR> Figure: Class hierarchy </A><P><P>The classes <EM>GPNode</EM>, <EM>GPNodeSet</EM> and <EM>GPAdfNodeSet</EM>describe a single node, e.g. a function or terminal, a set of nodes thatis used to collect all nodes used for a genetic tree (for example themain genetic program or any ADF), and a set of node sets for eachgenetic tree respectively. The user creates one object of type<EM>GPAdfNodeSet</EM> and puts all the necessary node sets in it before hecreates the initial population. This object should not be alteredduring the evolution process. This is not really a restriction. If theuser alters the object, he must make sure that those nodes (functionsand terminals) still needed by the population object are not deleted.</P><H2><A NAME="SEC4" HREF="gpkernel_toc.html#TOC4">1.3 Underlying Class definitions</A></H2><H3><A NAME="SEC5" HREF="gpkernel_toc.html#TOC5">1.3.1 The Base Class GPObject</A></H3><P><A NAME="IDX2"></A><A NAME="IDX3"></A></P><P>The base class for all classes is <EM>GPObject</EM>. It is an abstractclass, e.g. an object of type <EM>GPObject</EM> cannot be created. </P><BLOCKQUOTE><PRE>class GPObject{public: GPObject () {} virtual ~GPObject () {} ...};</PRE></BLOCKQUOTE><P><A NAME="IDX4"></A><A NAME="IDX5"></A></P><P>The container class <EM>GPContainer</EM> holds objects of type<EM>GPObject</EM> or of an inherited class. The class "owns" otherobjects and is responsible for deleting them if the container itself isdeleted. Therefore, the destructor defined in <EM>GPObject</EM> isvirtual. This enables the container to call the correct destructorfunction on deleting any object in the container.</P><BLOCKQUOTE><PRE> GPObject (const GPObject&) {} virtual GPObject& duplicate ()=0;</PRE></BLOCKQUOTE><P><A NAME="IDX6"></A></P><P>If a container must make a copy of itself (for example if the copyconstructor of class <EM>GPContainer</EM> is invoked), the container needsto copy all members that are in the container. This again is achievedby a virtual function called <EM>duplicate()</EM>. Every class inheritingfrom <EM>GPObject</EM> has to define this function. Usually the functioncode simply calls the copy constructor of the own class.</P><P><A NAME="IDX7"></A></P><BLOCKQUOTE><PRE> virtual void printOn (ostream& os)=0;</PRE></BLOCKQUOTE><P>Each object should be able to print itself on a stream. This is done bythe virtual function <EM>printOn()</EM>. By doing this, the outputoperator <CODE><<</CODE> is defined only once for all objects inheriting inany way from <EM>GPObject</EM>.</P><H3><A NAME="SEC6" HREF="gpkernel_toc.html#TOC6">1.3.2 The Container Class GPContainer</A></H3><P><A NAME="IDX8"></A><A NAME="IDX9"></A></P><P>The container class <EM>GPContainer</EM> holds objects of type<EM>GPObject</EM> or of an inherited class. It is a very simpleimplementation of a set. The class is supposed to provide for handlingof other objects and is needed as base class by nearly all other classesas they are almost all containers. Each container manages the objectsit owns by allocating an array of pointers that point to these objects.This array is of fixed length which turned out to be quite sufficient.</P><BLOCKQUOTE><PRE>class GPContainer : public GPObject{public: GPContainer (); GPContainer (int numObjects); virtual ~GPContainer (); ...};</PRE></BLOCKQUOTE><P>The constructor without parameters sets the object's variables to adefault value. The constructor with the number of objects that are tofit in the container as a parameter allocates the array of pointers andsets each pointer to NULL. The destructor deletes all objects thecontainer owns and then the array of pointers.</P><P><A NAME="IDX10"></A></P><BLOCKQUOTE><PRE> GPContainer (const GPContainer& gpc); virtual GPObject& duplicate () { return *(new GPContainer(*this)); }</PRE></BLOCKQUOTE><P>The copy constructor makes a copy of another container. First itallocates the array of pointers, if there are any, and then all objectsin the original container are duplicated by means of the virtualfunction <EM>duplicate()</EM> declared in class <EM>GPObject</EM>. This isthe reason why every class has to implement the function<EM>duplicate()</EM>, because the container must be able to make a copy ofeach object. Usually, the function <EM>duplicate()</EM> makes a copy (inthis case, of a complete container) by allocating a new object with thecopy constructor.</P><P>Note: the copy constructors of inheriting classes have not only to copythe elements of the own class, but also have to call the copyconstructor of the container class. The copy constructor of class Xinheriting from <EM>GPContainer</EM> should look like this:</P><BLOCKQUOTE><PRE> X (const X& x) : GPContainer(x) { ... }</PRE></BLOCKQUOTE><P>This ensures that the copy constructor of class <EM>GPContainer</EM> isinvoked which is necessary to copy all the container objects of aninstantiated class X object.</P><P><A NAME="IDX11"></A><A NAME="IDX12"></A></P><BLOCKQUOTE><PRE> void reserveSpace (int numObjects); int containerSize() const { return contSize; }</PRE></BLOCKQUOTE><P>If a <EM>GPContainer</EM> object was created with the parameterlessconstructor, there must be a way to set up the actual container size andallocate the array of pointers. The function <EM>reserveSpace()</EM> canbe called in this case. It should not be called to resize the containerwhich is in any case not possible.</P><P>The container size is returned by the function <EM>containerSize()</EM>.This function is very important and widely used. Nearly every class ofthe Genetic Programming system is inherited from <EM>GPContainer</EM>.The class that represents the tree structure (<EM>GPGene</EM>), forexample, uses <EM>containerSize()</EM> to determine the number ofchildren.</P><P><A NAME="IDX13"></A></P><BLOCKQUOTE><PRE> GPObject* Nth (int n) const;</PRE></BLOCKQUOTE><P>There are a few functions that serve as means of modifying thecontainer's content or obtaining information. All functions that existwithin the container class check for the range of any arguments and stopthe program if this is out of range. One of the benefits of objectoriented programming is that it can save a lot of code. Classes thatinherit from <EM>GPContainer</EM> do not need to check for this kind oferror.</P><P><EM>Nth()</EM> returns the n-th object in the container. The classes thatinherit from <EM>GPContainer</EM> also need a function that returnselements from the container, but they certainly want the function toreturn a type of the inherited class and not <EM>GPObject</EM>. Somecompilers do not allow for virtual functions returning different typesyet. Therefore, different function names are used in the inheritingclasses. Those functions invoke <EM>GPContainer::Nth()</EM> and do thenecessary type conversion.</P><P><A NAME="IDX14"></A><A NAME="IDX15"></A><A NAME="IDX16"></A></P><BLOCKQUOTE><PRE> void put (int n, GPObject& gpo); GPObject& get (int n); GPObject** getPointerAddress (int n) const;</PRE></BLOCKQUOTE><P>The functions <EM>put()</EM> and <EM>get()</EM> change the responsibilityfor an object's destruction. If the container owns an object, it willdestroy it whenever the container is destroyed. The figure explainswhat happens when a container is created, space is reserved, and anyobject is put into the container.</P><IMG SRC="images/gpcontainer.gif" ALT="Picture of object being placed into the container."ALIGN="CENTER"> <BR> <P>Figure: A <EM>GPContainer</EM> object (<EM>a</EM>) after creation with theparameterless constructor, (<EM>b</EM>) after calling<EM>reserveSpace(2)</EM>, and (<EM>c</EM>) after putting another object intothe container at position 1</A></P><P><A NAME="IDX17"></A></P><BLOCKQUOTE><PRE> virtual void printOn (ostream& os);</PRE></BLOCKQUOTE><P><EM>getPointerAdress()</EM> returns a pointer to the pointer within thearray of pointers. This way it is possible to modify, for example, thestructure of a genetic tree by merely changing the pointers. Thefunction makes crossover as well as shrink mutation very fast and easy.However, care has to be taken not to leave objects undeleted (theso-called memory leaks) nor to disrupt internal structures.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -