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

📄 ptree.c

📁 moealib
💻 C
字号:
#include "PTSGA.h"#include <string.h>#include <iomanip.h>PTree::PTree(PTSGA* pA) : pPTSGA(pA), root(NULL), cur_depth(pA->curDepth()),  ppop(new POP), ppop_valid(false),   list(new PT_NODE* [pA->maxDepth()+1]), list_valid(false),  curOffset(NULL), curLargest(NULL), curRange(NULL) {   Grid_Loc loc; loc.update(cur_depth);}PTree::~PTree() {   delete root; delete[] list;  delete[] curOffset; delete[] curLargest; delete[] curRange;  for(int i = ppop->currentSize()-1; i>=0; i--)    ppop->remove(i);   // individuals already deleted by "delete root".  delete ppop;            }void PTree::invalidate() const {  PTree* This = (PTree*) this;  This->ppop_valid = This->list_valid = false; }void PTree::validate_list() const {  if(list_valid) return;  assert(root);  PTree* This = (PTree*) this;  This->list[0] = root;  for(int i=1; i<=cur_depth; i++) {    This->list[i] = list[i-1]? list[i-1]->leftest_child() : 0;  }  This->list_valid = true;}void PTree::validate_population() const {   if(ppop_valid) return;  for(int i = ppop->currentSize() - 1; i>=0;  i--)     ppop->remove(i);  if(root) {    PT_NODE* leaf = leftest_leaf();    while(leaf) {      leaf->init_iterate();      assert(leaf->curInd());      ppop->append(leaf->curInd());      while(IND* ind=leaf->nextInd()) 	ppop->append(ind);      leaf = leaf->right_node();    }  }  PTree* This = (PTree*) this;  This->ppop_valid = true; }void PTree::init_rangeFrom(const POP& pop) {  assert(!curOffset && !curLargest && !curRange);  curOffset=new double[dimens];curLargest=new double[dimens];curRange=new double[dimens];  curOffset[0] = curOffset[1] = 0;  curLargest[0] = curLargest[1] = pow(2, 15);  curRange[0] = curRange[1] = pow(2, 15);  return;  for(int j=0; j<dimens; j++)    curOffset[j] = LARGE, curLargest[j] = -LARGE;  double tmp;  for(int i=0; i<pop.currentSize(); i++)     for(int j=0; j<dimens; j++) {      if((tmp=pop[i]->objectiveVector()[j]) < curOffset[j])	curOffset[j] = tmp;      if((tmp=pop[i]->objectiveVector()[j]) > curLargest[j])	curLargest[j] = tmp;    }  for(int j=0; j<dimens; j++) {    curOffset[j] *= 0.8;    curLargest[j] *= 1.2;    curRange[j] = curLargest[j] - curOffset[j];  }  }void PTree::update(const POP& pop) {  if(! root) {    root = new PT_NODE(0, 0, 0);    invalidate();    if(!curOffset) init_rangeFrom(pop);  }  int sz = pop.currentSize();   PT_NODE** dad = new (PT_NODE*)[sz];  for(int i=0; i<sz; i++)    dad[i] = root;      Grid_Loc* loc = new Grid_Loc[sz];  double* range = new double[dimens];   double* half_range = new double[dimens];   double** offset = new (double*) [sz];   for(int i=0; i<sz; i++)    offset[i] = new double [dimens];  for(int j=0; j<dimens; j++) {    range[j] = curRange[j];    half_range[j] = range[j]/2;  }  for(int i=0; i<sz; i++)    for(int j=0; j<dimens; j++)       offset[i][j] = curOffset[j];   list[0] = root;  for(int lvl=1; lvl<=cur_depth; lvl++) {     double middle;      for(int i=0; i<sz; i++) {      if(!dad[i]) continue; //this individual discarded in uppler level insertion.      IND * ind = pop[i];      for(int j=0; j<dimens; j++) {	middle = offset[i][j] + half_range[j];	if( ind->objectiveVector()[j] > middle ) {	  loc[i].set(j, lvl);	  offset[i][j] = middle;	}      }      dad[i] = insert(lvl, loc[i], i, dad, lvl==cur_depth?ind:0);    }    for(int j=0; j<dimens; j++) {      range[j] = half_range[j];      half_range[j] /= 2;    }    list[lvl] = list[lvl-1]->leftest_child();  }  delete [] dad;  delete [] loc;  delete [] range;  delete [] half_range;  for(int i=0; i<sz; i++)    delete [] offset[i];  delete [] offset;  invalidate();}/*-------------------------------------   insert()   -------------------------------------------* *                                                                                              * * Compare the idx'th individual(grid location 'loc')to those in nodes of level 'lvl'.          * *   if dorminated, do nothing and return 0.                                                    * *   if equal to some node, insert individual and return that node.                             * *   if dorminating, delete dorminated subtree.                                                 * *   if (dominating or indifferent) create new node and return this new node.                   * * NOTE:                                                                                        * *     the pointer array is also used as flags.  When the inserted one dominates other nodes    * *     already in the same level of the tree, all dad[i<idx] whose value equal to any of the    * *     dominated (and deleted) nodes should be cleared to 0, and consequently such individual   * *     will not be considered for comparison in deeper level.                                   * *----------------------------------------------------------------------------------------------*/PT_NODE* PTree::insert(int lvl, Grid_Loc& loc, int idx, PT_NODE** dad, IND* ind) {  assert(list[lvl-1]);  assert(lvl==cur_depth || ind == 0); // actual insertion of individual only occurs in leaf level.  PT_NODE* cur = list[lvl-1]->leftest_child();    while(cur) {    PT_NODE* next = cur->right_node();    switch( cur->compare(loc) ) {    case DOMINATING: return 0;    case SAME      : if(ind) cur->insert(ind->clone()); return cur;    case DOMINATED : for(int i=0; i<idx; i++) 		       if(dad[i]==cur) dad[i] = 0;		     cur->del_tree(); break;    }    cur = next;  }  return new PT_NODE(loc, dad[idx], ind? ind->clone():0);}  void PTree::assignFitnesses() {#ifdef DEBUG  static int call = 0;  call++;#endif  /*    * iterate upward to count resident of each subtree    */  root->reset();   //clear count in all nodes.  bool deleted = false;   assert((call%50? 0: (void*)(cout<<"\n\nindividuals in each leaf node\n"), 1));  PT_NODE* leaf = leftest_leaf();   while(leaf) {      int leaf_count = leaf->differentInds(deleted);    leaf->count() += leaf_count;    PT_NODE* dad = leaf->parent();    PT_NODE* child  = leaf;    while(dad) {      dad->count() += leaf_count;      child = dad; dad = dad->parent();    }    assert((call%50? 0:(void*)(cout<<leaf_count<<" "), 1));    leaf = leaf->right_node();  }  assert((call%50? 0:(void*)(cout<<endl), 1));  if(deleted) invalidate();  /*    * now recursively iterate downward to accumulate parent 'count' to    * that of child node, and reduce subtree size if too large.   */  int curSz = population().currentSize();  assert(curSz == root->count());  int maxInds = pPTSGA->pop1_maxSize();  int del_Inds = curSz>maxInds? curSz-maxInds : 0;  root->niching_reducing(del_Inds);  if(del_Inds) invalidate();  /*   * finally, assign each individual the following fitness:   * 'count' of its (leaf) node - curSz.   */  curSz = population().currentSize();   leaf = leftest_leaf();  while(leaf) {     int fit = leaf->count() - curSz;    leaf->init_iterate();    assert(leaf->curInd());    leaf->curInd()->fitness(fit);    while(IND* ind=leaf->nextInd())       ind->fitness(fit);    leaf = leaf->right_node();  }  return;}bool PTree::depthChanged() {  int old = cur_depth;  cur_depth = pPTSGA->curDepth();  if(old != cur_depth) {    Grid_Loc loc; loc.update(cur_depth);    return true;  }  return false;}bool PTree::rangeChanged() {   double* offset = new double [dimens];  double* largest = new double [dimens];  for(int j=0; j<dimens; j++)    offset[j] = largest[j] = population()[0]->objectiveVector()[j];  POP& pop = population();  int sz = pop.currentSize();  double current;  for(int i=1; i<sz; i++) {    for(int j=0; j<dimens; j++) {      current = pop[i]->objectiveVector()[j];      if( offset[j] > current) offset[j]  = current;      if(largest[j] < current) largest[j] = current;    }  }  bool changed = false;  for(int j=0; j<dimens; j++) {    if(fabs(curOffset[j] - offset[j]) > 0.1*curOffset[j])      { changed = true;  break; }    if(fabs(curLargest[j] - largest[j]) > 0.1*curLargest[j])      { changed = true;  break; }  }  if(changed) {    for(int j=0; j<dimens; j++) {      curOffset[j]  = (1-0.1) * offset[j];      curLargest[j] = (1+0.1) * largest[j];      curRange[j] = curLargest[j] - curOffset[j];    }  }  delete [] offset; delete [] largest;  return changed;}void PTree::rebuild() {  bool changed = false;  if(rangeChanged()) changed = true;  if(depthChanged()) changed = true;  if(changed) {    PT_NODE* old_root = root;    POP& pop = population();    root = 0; update(pop);    delete old_root;  }  return;}

⌨️ 快捷键说明

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