⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gatreegenome.cpp

📁 遗传算法工具箱C++
💻 CPP
字号:
// $Header$/* ----------------------------------------------------------------------------  tree.C  mbwall 25feb95  Copyright (c) 1995 Massachusetts Institute of Technology                     all rights reserved DESCRIPTION:  Source file for the tree genome.---------------------------------------------------------------------------- */#ifndef _ga_tree_C_#define _ga_tree_C_#include <stdio.h>#include <stdlib.h>#include "GATreeGenome.h"#include "garandom.h"extern int _GATreeCompare(GANodeBASE * anode, GANodeBASE * bnode);template <class T> const char *GATreeGenome<T>::className() const {return "GATreeGenome";}template <class T> intGATreeGenome<T>::classID() const {return GAID::TreeGenome;}template <class T>GATreeGenome<T>::GATreeGenome(GAGenome::Evaluator f, void * u) : GATree<T>(),GAGenome(DEFAULT_TREE_INITIALIZER,	 DEFAULT_TREE_MUTATOR,	 DEFAULT_TREE_COMPARATOR) {  evaluator(f);  userData(u);  crossover(DEFAULT_TREE_CROSSOVER);}template <class T>GATreeGenome<T>::GATreeGenome(const GATreeGenome<T> & orig) : GATree<T>(),GAGenome() {  GATreeGenome<T>::copy(orig);}template <class T>GATreeGenome<T>::~GATreeGenome() { }template <class T> GAGenome *GATreeGenome<T>::clone(GAGenome::CloneMethod flag) const {  GATreeGenome<T> *cpy = new GATreeGenome<T>();  if(flag == (int)CONTENTS){cpy->copy(*this);} // cast is for metrowerks...  else{cpy->GAGenome::copy(*this);}  return cpy;}template <class T> voidGATreeGenome<T>::copy(const GAGenome & orig) {  if(&orig == this) return;  const GATreeGenome<T>* c = DYN_CAST(const GATreeGenome<T>*, &orig);  if(c) {    GAGenome::copy(*c);    GATree<T>::copy(*c);  }}#ifdef GALIB_USE_STREAMS// Traverse the tree (breadth-first) and dump the contents as best we can to// the stream.  We don't try to write the contents of the nodes - we simply // write a . for each node in the tree.//   We allocate space for x,y coord pair for each node in the tree.  Then we// do a depth-first traversal of the tree and assign coords to the nodes in the// order we get them in the traversal.  Each coord pair is measured relative to// the parent of the node.template <class T> void_tt(STD_OSTREAM & os, GANode<T> * n){  if(!n) return;  GANodeBASE * node = DYN_CAST(GANodeBASE*, n);  os.width(10); os << node << " ";  os.width(10); os << node->parent << " ";  os.width(10); os << node->child << " ";  os.width(10); os << node->next << " ";  os.width(10); os << node->prev << " ";  os.width(10); os << &(n->contents) << "\n";  _tt(os, DYN_CAST(GANode<T>*, node->child));  for(GANodeBASE * tmp=node->next; tmp && tmp != node; tmp=tmp->next){    os.width(10); os << tmp << " ";    os.width(10); os << tmp->parent << " ";    os.width(10); os << tmp->child << " ";    os.width(10); os << tmp->next << " ";    os.width(10); os << tmp->prev << " ";    os.width(10); os << &(DYN_CAST(GANode<T>*, tmp)->contents) << "\n";    _tt(os, DYN_CAST(GANode<T>*, tmp->child));  }}template <class T> intGATreeGenome<T>::write(STD_OSTREAM & os) const {  os << "node       parent     child      next       prev       contents\n";  _tt(os, (GANode<T> *)(this->rt));  return 0;}#endiftemplate <class T> int  GATreeGenome<T>::equal(const GAGenome & c) const{  if(this == &c) return 1;  const GATreeGenome<T>& b = DYN_CAST(const GATreeGenome<T>&, c);  return _GATreeCompare(this->rt, b.rt) ? 0 : 1;}/* ----------------------------------------------------------------------------   Operator definitions---------------------------------------------------------------------------- *///  This mutation method is destructive.  We randomly pick a node in the tree// then delete the subtree and node at that point.  Each node in the tree has// a pmut probability of getting nuked.//  After the mutation the iterator is left at the root of the tree.template <class T> intGATreeGenome<T>::DestructiveMutator(GAGenome & c, float pmut){  GATreeGenome<T> &child=DYN_CAST(GATreeGenome<T> &, c);  register int n, i;  if(pmut <= 0.0) return 0;  n = child.size();  float nMut = pmut * STA_CAST(float,n);  if(nMut < 1.0){		// we have to do a flip test for each node    nMut = 0;    for(i=0; i<n; i++){      if(GAFlipCoin(pmut) && child.warp(i)){	child.destroy();	nMut++;      }    }  }  else{				// only nuke the number of nodes we need to    for(i=0; i<nMut; i++){      if(child.warp(GARandomInt(0, n-1)))	child.destroy();    }  }  child.root();		// set iterator to root node  return(STA_CAST(int,nMut));}// This is a rearranging mutation operator.  It randomly picks two nodes in the// tree and swaps them.  Any node has a pmut chance of getting// swapped, and the swap could happen to any other node.  And in the case of// nMut < 1, the swap may generate a swap partner that is the same node, in // which case no swap occurs (we don't check).//   After the mutation the iterator is left at the root of the tree.template <class T> intGATreeGenome<T>::SwapNodeMutator(GAGenome & c, float pmut){  GATreeGenome<T> &child=DYN_CAST(GATreeGenome<T> &, c);  register int n, i;  if(pmut <= 0.0) return 0;  n = child.size();  float nMut = pmut * STA_CAST(float,n);  nMut *= 0.5;			// swapping one node swaps another as well  if(nMut < 1.0){		// we have to do a flip test for each node    nMut = 0;    for(i=0; i<n; i++){      if(GAFlipCoin(pmut)){	child.swap(i,GARandomInt(0,n-1));	nMut++;      }    }  }  else{				// only nuke the number of nodes we need to    for(i=0; i<nMut; i++)      child.swap(GARandomInt(0,n-1),GARandomInt(0,n-1));  }  child.root();		// set iterator to root node  return(STA_CAST(int,nMut*2));}// This is a rearranging mutation operator with subtree swap.  It does the same// thing as the rearranging mutator above, but swaps subtrees as well as the// nodes that are selected.//   After the mutation the iterator is left at the root of the tree.//   We check to make sure that we don't try to swap ancestral nodes.  If it is// an ancestral swap, we give up and don't do anything to the tree.  This could// result in mutation rates that are lower than the specified rate!// *** mutation rates are not exact!template <class T> intGATreeGenome<T>::SwapSubtreeMutator(GAGenome & c, float pmut){  GATreeGenome<T> &child=DYN_CAST(GATreeGenome<T> &, c);  register int n, i;  int a, b;  if(pmut <= 0.0) return 0;  n = child.size();  float nMut = pmut * STA_CAST(float,n);  nMut *= 0.5;			// swapping one node swaps another as well  if(nMut < 1.0){		// we have to do a flip test for each node    nMut = 0;    for(i=0; i<n; i++){      if(GAFlipCoin(pmut)){	b = GARandomInt(0,n-1);	if(!child.ancestral(i,b)) child.swaptree(i,b);	nMut++;      }    }  }  else{				// only nuke the number of nodes we need to    for(i=0; i<nMut; i++){      a = GARandomInt(0,n-1);      b = GARandomInt(0,n-1);      if(!child.ancestral(a,b)) child.swaptree(a,b);    }  }  child.root();		// set iterator to root node  return(STA_CAST(int, nMut*2));}// We use the recursive tree function to compare the tree structures.  This// does not compare the contents of the nodes.template <class T> floatGATreeGenome<T>::TopologyComparator(const GAGenome& a, const GAGenome& b) {  if(&a == &b) return 0;  const GATreeGenome<T>& sis=DYN_CAST(const GATreeGenome<T>&, a);  const GATreeGenome<T>& bro=DYN_CAST(const GATreeGenome<T>&, b);  return STA_CAST(float, _GATreeCompare(sis.rt, bro.rt));}// The default crossover operator takes a node from parent a (with its entire// sub-tree) and replaces it with a node from parent b (with its entire sub-// tree).  If the crossover site is not set, then we pick a random site based// on the trees in the genomes we're going to cross.  Once we have a valid// crossover site, we copy the trees from the two genomes.//   If the crossover site is out of bounds (ie refers to a node not in the// tree) then we don't do anything to the child.//   We allow crossover at ANY site in the genomes (including at the root// node).// *** we should be able to speed this up.  there is an extra traversal when we//     do the check to see if the crossover site is valid.template <class T> intGATreeGenome<T>::OnePointCrossover(const GAGenome& p1, const GAGenome& p2, 		  GAGenome* c1, GAGenome* c2){  const GATreeGenome<T> &mom=DYN_CAST(const GATreeGenome<T> &, p1);  const GATreeGenome<T> &dad=DYN_CAST(const GATreeGenome<T> &, p2);  int nc=0;  unsigned int a = GARandomInt(0, mom.size()-1);  unsigned int b = GARandomInt(0, dad.size()-1);  GATreeIter<T> momiter(mom), daditer(dad);  GATree<T> * tree;  if(c1 && c2){    GATreeGenome<T> &sis=DYN_CAST(GATreeGenome<T> &, *c1);    GATreeGenome<T> &bro=DYN_CAST(GATreeGenome<T> &, *c2);// first do the sister...    if(momiter.warp(a) && daditer.warp(b)){      sis.GATree<T>::copy(mom);      tree = dad.GATree<T>::clone(b);      sis.warp(a);      sis.swaptree(tree);      delete tree;      sis.warp(0);    }// ...now do the brother.    if(momiter.warp(a) && daditer.warp(b)){      bro.GATree<T>::copy(dad);      tree = mom.GATree<T>::clone(a);      bro.warp(b);      bro.swaptree(tree);      delete tree;      bro.warp(0);    }    nc = 2;  }  else if(c1){    GATreeGenome<T> &sis=DYN_CAST(GATreeGenome<T> &, *c1);    if(GARandomBit()){      if(momiter.warp(a) && daditer.warp(b)){	sis.GATree<T>::copy(mom);	tree = dad.GATree<T>::clone(b);	sis.warp(a);	sis.swaptree(tree);	delete tree;	sis.warp(0);      }    }    else{      if(momiter.warp(a) && daditer.warp(b)){	sis.GATree<T>::copy(dad);	tree = mom.GATree<T>::clone(a);	sis.warp(b);	sis.swaptree(tree);	delete tree;	sis.warp(0);      }    }    nc = 1;  }  return nc;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -