
Genetic Algorithms Digest   Thursday, July 30 1992   Volume 6 : Issue 27

 - Send submissions to GA-List@AIC.NRL.NAVY.MIL
 - Send administrative requests to GA-List-Request@AIC.NRL.NAVY.MIL
 - anonymous ftp archive: FTP.AIC.NRL.NAVY.MIL (see v6n5 for details)

Today's Topics:
	- Re: Object-oriented GA (2 messages)
	- TR on Coevolving Representations
	- graph problems and GA
	- Machine Learning 9:1
	- how to map expression to genome?

****************************************************************************

CALENDAR OF GA-RELATED ACTIVITIES: (with GA-List issue reference)

 FOGA-92, Foundations of Genetic Algorithms, Colorado (v5n32)   Jul 26-29, 92
 COG SCI 92, Cognitive Science Conf., Indiana, (v5n39, v6n22)   Jul 29-1,  92
 ECAI 92, 10th European Conference on AI (v5n13)                Aug  3-7,  92
 Parallel Problem Solving from Nature, Brussels, (v5n29)        Sep 28-30, 92
 SAB92, From Animals to Animats, Honolulu (v6n6)                Dec  7-11, 92
 ICNN93, IEEE Intl. Conf. on Neural Networks, Calif (v6n24)     Mar 28-1,  93
 ECML-93, European Conf. on Machine Learning, Vienna (v6n26)	Apr  5-7,  93
 Intl. Conf. on Neural Networks and GAs, Innsbruck (v6n22)      Apr 13-16, 93
 ICGA-93, Fifth Intl. Conf. on GAs, Urbana-Champaign (v6n26)    Jul 17-22, 93


 (Send announcements of other activities to GA-List@aic.nrl.navy.mil)

****************************************************************************
----------------------------------------------------------------------

From: jrs@santafe.edu (Joshua R. Smith)
Date: Fri, 24 Jul 92 12:58:48 MDT
Subject: Re: Object-oriented GA

   On implementing the GA in C++, Tang Yiu Cheung writes (v6n26):
   >              ... I tried to write a virtual crossover function one
   >   for class Haploid and one for class Diploid, hoping that the derived
   >   classes can reuse the code.  But it seems that this cannot be done,
   >   and I would be very grateful if someone can tell me if there's a way
   >   to write this crossover function.


   I ran into similar problems when writing GAdget, a C++ GA toolkit.
   Unfortunately, I don't think there's an efficient way to write a generic
   crossover operator in C++, because the language does not support
   abstract data typing.  As you probably realize, you can't allocate an
   array (your chromosome, for example) without specifying the type of its
   elements (your genes).  Therefore you can't easily define a crossover
   operator that will work on, say, both *double* and *int* chromosomes.

   An inefficient but workable technique would be to define your
   chromosome as a list of objects of type gene, or as an array of
   pointers to genes.  Then crossover would always operate on the same
   type, an array (say) of pointers to genes.  The gene class would have
   a member function called exchange, which would swap information with
   another gene.  This function would have to be rewritten for each
   derived gene class (i.e. Binary, Real, Haploid, Diploid) because of
   the lack of abstract typing, but you could use the same crossover
   operator for all.  (However, you would probably still want a different
   crossover operator for haploid and diploid.)  Crossover (a member of
   the chromosome class) would decide which genes should exchange.

   The solution I settled on in GAdget was to split the GTYPE
   (implemented in a class called Nucleus) from the PTYPE (class
   Organism).  The genetic operators work on the GTYPE; the fitness
   function is applied to the PTYPE.  A decoding function translates the
   GTYPE into the PTYPE.  There is only one sort of PTYPE, so you never
   have to rewrite your fitness function when you change representations.
   However, you must write a special crossover operator for each GTYPE
   (Nucleus).  A further disadvantage is that the
   BinaryNucleus/RealNucleus split meant that I had to implement separate
   BinaryPopulation and RealPopulation (I couldn't use a generic
   Population with a generic Nucleus, ultimately because of the lack of
   abstract typing in C++).

   This solution is good if you are interested in using the GA to solve
   problems: you can quickly try a bunch of different solution techniques
   without recoding the problem.  If one were interested in doing
   research on different sorts of crossover operators, but wanted them to
   work on a variety of chromosome types, the first technique would
   probably be better.

   (If anyone is interested in seeing a desciption of GAdget, I can
   provide that.  I have not made the code publicly available, but may
   later in the summer.)

------------------------------

From: jpalmucc@BBN.COM
Date: Mon, 27 Jul 92 15:43:19 -0400
Subject: Re: Object-oriented GA

   In response to Tang Yiu Cheung's message:

   I have implemented a GA toolkit in C++ that we use here at BBN. Like
   Davis and Cerys' OOGA, operations are implemented as objects. I think
   this is cleaner than operations as member functions because you can
   store information on the operation's class (number of parents needed,
   number of children created, mutation rates, etc.)

   Here is an except from the GA++ manual that describes the operation base
   class:


   >  \subsection{Operations}
   >  
   >  The GA++ base clase \verb'Operation' is used to implement reproduction
   >  in GA++. Operations request a certain number of parents, and return a
   >  number of children that are based on those parents. Figure
   >  \ref{operdef} shows the definition of operation class.
   >  
   >  \begin{figure}
   >  
   >  \begin{verbatim}
   >  class Operation : public Describable
   >  {
   >    public:
   >       virtual int needed() = 0;
   >       virtual int created() = 0;
   >       virtual void apply( Ga &ga_instance, Chrom **parents,
   >  	Chrom **children ) = 0; };
   >  \end{verbatim}
   >  \caption{\label{operdef} Class declaration of {\tt Operation}.}
   >  \end{figure}
   >  
   >  The \verb'needed' member function returns the number of parents that
   >  an operation will require. For example, a typical mutation operation
   >  will require one parent, while a typical crossover operation will
   >  require two. The \verb'created' member function returns the number of
   >  children that are created from a given parent. The results of both of
   >  these functions are expected to hold for the next application, but can
   >  change between successive applications.
   >  
   >  The \verb'apply' member function creates the children from the given
   >  parents.  The apply function should assume that the \verb'parents'
   >  argument is an array of pointers to the parents that will be used for
   >  this application. The length of this array is equal to the value
   >  returned by the last call to the \verb'needed' member function. All
   >  elements of this array are guaranteed to be members of the same
   >  chromosome class.
   >  
   >  The \verb'children' argument is also an array of pointers.  Initially,
   >  the pointers don't point anywhere. The operation is required to fill
   >  the children array with valid pointers retrieved from the \verb'Chrom'
   >  member function \verb'Chrom_get'. It must fill the array with exactly
   >  the number of children that the last call to \verb'created' specified.
   >  Also, the elements in the children array must be the same type as the
   >  elements in the parent array.
   >  
   >  Finally, the operation should modify the children based on the
   >  semantics of the operation class and the value of the parents.
   >  
   >  For example, the \verb'Place_mutation' operation needs one parent, and
   >  creates one child. After creating the child, it steps through the
   >  contents of that parent and copies them to the child. For each
   >  position, there is a certain probability that the position will be
   >  flipped and copied, instead of just copied.
   >  
   >  \subsubsection{Double Polymorphism and Operations}
   >  
   >  Unlike the Lisp based object system, CLOS, C++ can accomplish runtime
   >  polymorphism on only one object at a time. For operation method
   >  selection this means that we can either select a method based on the
   >  type of operation, or the type of chromosome, but not both at the same
   >  time. GA++ gets around this restriction through a technique called
   >  {\em double polymorphism}. We will use the definition of the
   >  \verb'Place_mutation' class as an example.
   >  
   >  \begin{figure}
   >  
   >  \begin{verbatim}
   >  class Place_mutation : public Operation
   >  {
   >    private:
   >       float mutation_rate;
   >    public:
   >       Place_mutation( float new_mutation_rate )
   >            { mutation_rate = new_mutation_rate; };
   >       virtual int needed() { return 1; };
   >       virtual int created() { return 1; };
   >       virtual void apply( Ga &ga_instance, Chrom **parents, Chrom
   >  		**children ) 
   >       {
   >           parents[0]->do_place_mutation( mutation_rate, parents,
   >                                          children ); 
   >       };
   >  
   >  };
   >  \end{verbatim}
   >  
   >  \caption{\label{pmutdef} Complete definition of {\tt Place\_mutation}.} 
   >  \end{figure}
   >  
   >  Figure \ref{pmutdef} shows the class declaration for place mutation.
   >  Notice that the \verb'apply' member function is virtual.
   >  
   >  This guarantees that the operation we are trying to apply is place
   >  mutation. However, note the type of the parents and children
   >  arguments. All we know about them is that they are chromosomes. In
   >  reality, they could be bitstrings, float\_vectors, ordered lists, or
   >  any other kind of representation that has been coded with GA++. In
   >  order to determine that actual type, we call the virtual member
   >  function \verb'do_place_mutation' based in \verb'Chrom'.  Figure
   >  \ref{dpmdef} shows an excerpt of the code that will be called if the
   >  arguments are bitstrings.
   >  
   >  \begin{figure}
   >  \begin{verbatim}
   >  void Bitstring::do_place_mutation( float mutation_rate,
   >  		Chrom **base_parents, Chrom **base_children )
   >  {
   >        base_children[0] = base_parents[0]->Chrom_get();
   >       // cast to derived, OK
   >       Bitstring **parents = (Bitstring **)base_parents; 
   >       Bitstring **children = (Bitstring **)base_children;
   >  
   >      // do the place mutation
   >       . . .
   >  }
   >  \end{verbatim}
   >  \caption{\label{dpmdef}
   >      Excerpt from {\tt Bitstring::do\_place\_mutation}.} 
   >  \end{figure}
   >  
   >  Because of the virtual function dispatch, we know that the parents are
   >  at least derived from \verb'Bitstring'. Therefore, we can cast from
   >  the base \verb'Chrom' to the derived \verb'Bitstring'.\footnote{This
   >  is not in general true.  However, in the class heirachies that
   >  chromosomes will be constructed from, we can assume it is so.} At this
   >  point, we used one virtual dispatch to discover that we are doing
   >  place mutations, and another to discover that we are working with
   >  bitstrings. With this information, we can go on and twiddle the
   >  private members of \verb'parents' and \verb'children' appropriately.

   As for the previous message on OODB capabilities:

   In general, I don't see a great need for a persistant store in a GA
   toolkit. However, you may want to think about using an OODB as an
   experimentation tool.

   When I run an experiment, I record the population best at specific
   intervals during the run of the GA for several runs. Then I dump the
   numbers to Splus, where I can compare population averages and
   variance, etc. 

   This works well, but it may be more useful to store this information
   as the actual population members, rather than a fitness score.

   Then you can go back at look at your run to get a clearer idea of what
   is going on (hmmm.. is my crossover operator *really* working, or am I
   just hillclimbing).

   Then again, you can probably just watch the GA as it is running. 

------------------------------

From: Peter J Angeline <pja@cis.ohio-state.edu>
Date: Wed, 22 Jul 92 20:45:46 -0400
Subject: TR on Coevolving Representations

   The technical report described below is available from the Ohio State
   University's Laboratory for Artificial Intelligence Research (LAIR) by
   anonymous ftp or snail mail.  To ftp use the following:

		   unix> ftp nervous.cis.ohio-state.edu
		   Name: anonymous
		   Password: <your userid@net.address>
		   ftp> cd pub/papers
		   ftp> get 92-pa-coevolve.ps.Z
		   ftp> quit
		   unix> uncompress 92-pa-coevolve.ps.Z

   This produces a postscript version of the paper in the file
   92-pa-coevolve.ps which can be printed on most laser printers.

   To receive a hard copy through snail mail, send a request for technical
   report number 92-pa-coevolve to pja@cis.ohio-state.edu with your name and
   snail mail address.

   Comments, problems and questions emailed to the first author are
   encouraged and appreciated.

		 ==================================================

			Coevolving High-Level Representations

		       Peter J. Angeline and Jordan B. Pollack

		   Laboratory for Artificial Intelligence Research
		     Computer and Information Science Department
			      The Ohio State University
				Columbus, Ohio 43210
			       pja@cis.ohio-state.edu
			     pollack@cis.ohio-state.edu



				      Abstract

	    Several genetic algorithms allow a genotype's size to change
	    during  evolution.  This  is  an  important   alternative to
	    limiting  the genotype's maximum  size and  complexity since
	    such limitation is undesirable  for an evolutionary process.
	    In  this paper, we  add  an  additional dynamic to simulated
	    evolution  with the description  of a genetic algorithm that
	    coevolves its representation language with the genotypes. We
	    introduce two mutation operators that help to acquire useful
	    modules  from the genotypes  during evolution. These modules
	    form  an  increasingly   high-level  representation language
	    specific to the developmental  environment. We also  provide
	    experimental results  illustrating interesting properties of
	    the acquired modules and the evolved languages.


		 Submitted to the Proceedings of Artificial Life III



   Peter J. Angeline            ! Laboratory for AI Research (LAIR)
   Graduate Research Assistant  ! Ohio State University, Columbus, Ohio 43210
   ARPA: pja@cis.ohio-state.edu ! "Nature is more ingenious than we are."

------------------------------

From: me@cicb.fr
Date: Fri, 24 Jul 92 08:38:31 +0200
Subject: graph problems and GA

   Hi,

   I'm a french PhD student. I work on computer security area. I have a
   problem to solve with GA. To do this, I must solve a graph contractibility
   problem:

      Can a graph isomorphic to G1 be obtained from G2 by a sequence of edge
      contractions, i.e. a sequence in which each step replace two vertices
      by one vertex according to the adjacent constraints.

   Is there anybody knowing information that can help me in that work?
   Thanks in advance ...

   -- LUDOVIC --

------------------------------

From: tgd@ICSI.Berkeley.EDU (Tom Dietterich)
Date: Fri, 24 Jul 92 09:21:09 PDT
Subject: Machine Learning 9:1

   MACHINE LEARNING Volume 9, Number 1, June 1992

   Editorial:
     Machine Learning: A Maturing Field
	   Jaime Carbonell

   Papers:
     Dynamic Parameter Encoding for Genetic Algorithms
	   N. N. Schraudolph and R. K. Belew

     Higher-Order and Model Logic as a Framework for Explanation-Based
     Generalization 
	   S. Dietzen and F. Pfenning

     The Utility of Knowledge in Inductive Learning
	   M. Pazzani and D. Kibler

   Book Review:
     Judd: Neural Network Design and the Complexity of Learning
	   V. Honavar
     A Reply to Honavar's Book Review
	   J. Stephen Judd

   -----
   Subscriptions - Volumes 8 and 9 (8 issues)

   ----  $88.00   Individual, member of AAAI
   ---- $140.00   Individual
   ---- $301.00   Institutional

   Kluwer Academic Publishers, P.O. Box 358, Accord Station, Hingham, MA
   02018-0358 (AAAI members please include membership number).
   ----

------------------------------

From: mlevin@cs.tufts.edu (Mike Levin)
Date: Sat, 25 Jul 92 15:15:38 EDT
Subject: how to map expression to genome?

      I want to use genetic algorithms to find an optimal expression. This
   expression is to be in string form, in LISP-like notation, and is defined
   recursively as: S is a real number, or the letter Z, or "(f S' S'')" where
   f is one of a small set of function names (like "sin", "add", etc.) and S'
   and S'' are other strings (possibly containing further nested
   parentheses). So, this is an example of a legal string: "(add (mult (add z
   5) 8) (sin 4))".  I want to find optimal strings of this form, where each
   string's "goodness" is evaluated by a special routine of mine (I am not
   simply evaluating the strings, or trying to maximize them etc.).  My
   question is, how do I map strings of this form onto a genome with discrete
   loci, since each string can be nested to any number of levels? My other
   question is this: I can mutate the strings symbolically, without mapping
   them to discrete loci (by drawing a parse tree of the expression, and
   performing operations like snipping or replacing leaves or nodes,
   rejoining, etc.). What effect is this likely to have on the usefullness of
   the algorithm (i.e., are there any prescedents for using GA's where the
   genome is not discretely mapped)? Please reply to
   mlevin@presto.cs.tufts.edu.

   Mike Levin

------------------------------
End of Genetic Algorithms Digest
******************************
