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

📄 classifierlist.c

📁 Simple GA code (Pascal code from Goldberg, D. E. (1989), Genetic Algorithms in Search, Optimization,
💻 C
📖 第 1 页 / 共 4 页
字号:
/** * Calculates the specificity of the classifier */int getSpecificity(struct xClassifier *cl){  return cl->con->size;}/** * Calculates the specificity of each bit in the conditions of the population. * The array specPos is assumed to be set to 0! */void getPosSpecificity(struct xClassifierSet *cll, double *specPos){  struct xCList *l;    for( ; cll!=NULL; cll=cll->next) {    for(l = cll->cl->con->l; l!=NULL; l=l->next)      specPos[l->pos] += cll->cl->num;  }}/** * Apply mutation to classifier 'cl'. * If niche mutation is applied, 'situation' is considered to constrain mutation.  * returns if the condition was changed. */int mutation(struct xClassifier *cl, char *situation, struct XCS *xcs){  int mp, len, mttr=0;  struct xCondition *con;  struct xCList *l, *ll=NULL, *newl;  len = getConditionLength();  con = cl->con;  l = con->l;  for(mp=0; mp<len; mp++) {    if(urand() < xcs->muGA) {      for(; l!=NULL && l->pos < mp; l=l->next) /* move to position */	ll=l;      if(l!=NULL && l->pos==mp) { /* mutate specified position */	if(mutate(&(l->c), situation[l->pos], xcs->doGeneralizationMutation, xcs->doNicheMutation)) {	  mttr = 1;	  if(l->c == DONT_CARE) {/* remove don't care entry!!! */	    con->size --; /* generalizing */	    if(ll==NULL) {/* remove first */	      con->l = con->l->next;	    }else{	      ll->next=ll->next->next;	    }	    l->next=NULL;	    free(l);	    if(ll==NULL) {	      l = con->l;	    }else{	      l = ll->next;	    }	  }	}      }else{ /* add position */	assert((newl=(struct xCList *)calloc(1,sizeof(struct xCList)))!=0);	newl->c = DONT_CARE;	newl->pos = mp;	newl->next = l;	if( ! mutate(&(newl->c), situation[mp], xcs->doGeneralizationMutation, xcs->doNicheMutation) ) {	  /* still a don't care symbol -> delete it! */	  free(newl);	}else{	  con->size++;	  mttr=1;	  if(ll==NULL) { /* add before first one */	    con->l=newl;	  }else{	    ll->next=newl;	  }	  ll = newl;	}      }    }  }  len = con->size;    /* possibly mutate action */  if( urand() < xcs->muGA ) {    mttr=1;    mutateAction(&(cl->act));  }    /* return if the condition or action of the classifier changed */  return mttr;}/** * Mutates one position in the condition of a classifier. * returns if the position really changed (for the GERERALIZATION_MUTATION)  */int mutate(char *c, char s, int doGeneralizationMutation, int doNicheMutation){  int changed=1;  /* mutate condition -> 0, 1, or DONT_CARE */  switch(*c) {  case '0':    if(doGeneralizationMutation || doNicheMutation ) {      /* generalize */      (*c)=DONT_CARE;    }else{      if(urand()<0.5)	(*c)='1';      else	(*c)=DONT_CARE;    }    break;  case '1':    if(doGeneralizationMutation || doNicheMutation ) {      (*c)=DONT_CARE;      /* generalize */    }else{      if(urand()<0.5)	(*c)='0';      else	(*c)=DONT_CARE;    }    break;  case DONT_CARE:    if(!doGeneralizationMutation) {      /* specialize */      if(doNicheMutation){	(*c)=s;      }else{	if(urand()<0.5)	  (*c)='0';	else	  (*c)='1';      }    }else{      changed=0;    }    break;  default:    printf("Mistake during mutation! condition:%c char:%c\n",*c ,s);    break;  }  return changed;}/** * Mutates the action to another action uniformly randomly chosen. */void mutateAction(int *action){  int i;  do{    i = (int)(urand() * getNumberOfActions());  }while(*action == i);  *action = i;}/*############################ offspring insertion #####################################*//** * Insert a discovered classifier into the population and respects the population size. */void insertDiscoveredClassifier(struct xClassifier **cl, struct xClassifier **parents, 				struct xClassifierSet **set, struct xClassifierSet **pop, 				struct xClassifierSet **killset, int len, struct XCS *xcs){  struct xClassifier *killedp;  len+=2;  if(xcs->doGASubsumption){    subsumeClassifier(cl[0], parents, *set, pop, xcs->maxPopSize, xcs->thetaSub);    subsumeClassifier(cl[1], parents, *set, pop, xcs->maxPopSize, xcs->thetaSub);  }else{    addClassifierToSet(cl[0], pop);    addClassifierToSet(cl[1], pop);  }    while(len > xcs->maxPopSize) {    len--;    killedp=deleteClassifier(pop, xcs);        /* record the deleted classifier to update other sets */    if(killedp!=NULL) {      addClassifierToPointerSet(killedp,killset);      /* update the set */      updateSet(set, *killset);    }  }}/*######################## subsumption deletion ########################################*//** * Action set subsumption as described in the algorithmic describtion of XCS  */void doActionSetSubsumption(struct xClassifierSet **aset, struct xClassifierSet **pop, struct xClassifierSet **killset, int thetaSub){  struct xClassifier *subsumer=NULL;  struct xClassifierSet *setp, *setpl;    /* Find the most general subsumer */  for(setp=*aset; setp!=NULL; setp=setp->next) {    if(isSubsumer(setp->cl, thetaSub)) {      if(subsumer==NULL || isMoreGeneral(setp->cl->con, subsumer->con)) {	subsumer = setp->cl;      }    }  }  /* If a subsumer was found, subsume all classifiers that are more specific. */  if(subsumer!=NULL) {    for(setp=*aset, setpl=*aset; setp!=NULL; setp=setp->next) {      while(isMoreGeneral(subsumer->con, setp->cl->con)) {	subsumer->num += setp->cl->num;	if(setpl==setp) {	  *aset=setp->next;	  deleteClassifierPointerFromSet(pop, setp->cl);	  freeClassifier(setp->cl);	  addClassifierToPointerSet(setp->cl, killset);	  free(setp);	  setp=*aset;	  setpl=*aset;	}else{	  setpl->next=setp->next;	  deleteClassifierPointerFromSet(pop, setp->cl);	  freeClassifier(setp->cl);	  addClassifierToPointerSet(setp->cl, killset);	  free(setp);	  setp=setpl;	}      }      setpl=setp;    }  }}/** * Tries to subsume the parents. */void subsumeClassifier(struct xClassifier *cl, struct xClassifier **parents, struct xClassifierSet *locset, struct xClassifierSet **pop, int maxPopSize, int thetaSub){  /*Try first to subsume in parents */  int i;  for(i=0; i<2; i++) {    if(parents[i]!=NULL && subsumes(parents[i],cl, thetaSub)){      parents[i]->num++;      freeClassifier(cl);      return;    }  }    if(subsumeClassifierToSet(cl, locset, maxPopSize, thetaSub))    return;  addClassifierToSet(cl,pop);}/** * Try to subsume in the specified set.  */int subsumeClassifierToSet(struct xClassifier *cl, struct xClassifierSet *set, int maxPopSize, int thetaSub){  struct xClassifierSet * setp;  struct xClassifier *subCl[maxPopSize];  int numSub=0, spec=0;    spec = getConditionLength();  /*Try to subsume in the set*/  for(setp=set; setp!=NULL; setp=setp->next) {    if(subsumes(setp->cl,cl, thetaSub)) {      if(spec > getSpecificity(setp->cl)) {	spec = getSpecificity(setp->cl);	numSub = 0;      }      subCl[numSub]=setp->cl;      numSub++;    }  }  /* if there were classifiers found to subsume, then choose randomly one and subsume */  if(numSub>0) {    numSub = (double)numSub * urand();    subCl[numSub]->num++;    freeClassifier(cl);    return 1;  }  return 0;}/**  * Check if classifier cl1 subsumes cl2  */int subsumes(struct xClassifier *cl1, struct xClassifier * cl2, int thetaSub){  int ret=0;  ret= cl1->act==cl2->act && isSubsumer(cl1, thetaSub) && isMoreGeneral( cl1->con, cl2->con);  return ret;}/**  * Returns if the classifier satisfies the criteria for being a subsumer. */int isSubsumer(struct xClassifier *cl, int thetaSub){  return cl->exp > thetaSub && cl->acc == 1.;}/** * Check if the first condition is more general than the second. */int isMoreGeneral (struct xCondition *first, struct xCondition *second){  struct xCList *l1, *l2;  int ret=0;  for(l1=first->l, l2=second->l; l1!=NULL && l2!=NULL; l1=l1->next, l2=l2->next) {    while(l2->pos < l1->pos) {      ret = 1; /* definitely more specific */      l2=l2->next;      if(l2==NULL) /* since l1 still specifies we know that the first condition is not more general! */	return 0;    }    if(l1->pos < l2->pos || l1->c != l2->c)      return 0;    /* if we came here, both pointers must point to the same position in the condition */  }  if(l1!=NULL) /* since l1 still specifies we know that the first condition is not more general!*/    return 0;  return ret;}/*###################### adding classifiers to a set ###################################*//** * Adds only the pointers to the pointerset, ensures that no pointer is added twice, * returns if the pointer was added  */int addClassifierToPointerSet(struct xClassifier *cl,struct xClassifierSet **pointerset){  struct xClassifierSet *setp;    for(setp=*pointerset; setp!=NULL; setp=setp->next) {    if(setp->cl == cl){      /* Classifier is already in Set */      return 0;    }  }  /* add the classifier, as it is not already in the pointerset */  assert((setp=( struct xClassifierSet *)calloc(1,sizeof(struct xClassifierSet)))!=NULL);  setp->cl=cl;  setp->next=*pointerset;  *pointerset=setp;  return 1;}/** * Adds the classifier cl to the population, makes sure that the same classifier  * does not exist, yet.  * returns if inserted classifier was deleted  */int addClassifierToSet(struct xClassifier *cl,struct xClassifierSet **clSet){  struct xClassifierSet *setp;    /* Check if classifier exists already. If so, just increase the numerosity    * and free the space of the new classifier */  for(setp=*clSet;setp!=NULL;setp=setp->next) {    if(isEqualXC(setp->cl->con,cl->con) && setp->cl->act==cl->act) {      setp->cl->num++;      freeClassifier(cl);      return 1;    }  }  /* classifier does not exist, yet-> add new classifier */  assert((setp=( struct xClassifierSet *)calloc(1,sizeof(struct xClassifierSet)))!=NULL);  setp->cl=cl;  setp->next=*clSet;  *clSet=setp;  return 0;}/** * Adds the new Clasifier cl to the xClassifierSet 'clSet'.  */void addNewClassifierToSet(struct xClassifier *cl,struct xClassifierSet **clSet){  struct xClassifierSet *setp;  /* classifier does not exist, yet-> add new classifier */  assert((setp=( struct xClassifierSet *)calloc(1,sizeof(struct xClassifierSet)))!=NULL);  setp->cl=cl;  setp->next=*clSet;  *clSet=setp;}/*############################### deletion #############################################*//** * Deletes a classifier from the population and returns the pointer to the deleted classifier. */struct xClassifier * deleteClassifier(struct xClassifierSet **pop, struct XCS *xcs) {  struct xClassifier *killedp = NULL;  killedp=deleteStochClassifier(pop, xcs->delta, xcs->thetaDel, xcs->deletionType);  return killedp;}/** * Deletes one Classifier at Random considering the delection type chosen (random, action-set-size estimate * based, fitness based, or both).  */struct xClassifier * deleteStochClassifier(struct xClassifierSet **pop, double delta, int thetaDel, int delType){  struct xClassifierSet *setp,*setpl;  struct xClassifier *killedp=NULL;  double sum=0., choicep, meanf=0., meane=0.;  int size=0;  /* get the sum of the fitness and the numerosity */  for(setp=*pop; setp!=NULL; setp=setp->next){    meanf+=setp->cl->fit;    meane+= setp->cl->preer*setp->cl->num;    size+=setp->cl->num;  }  meanf/=(double)size;  meane/=(double)size;

⌨️ 快捷键说明

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