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

📄 classifierlist.c

📁 XCS is a new algorithm for artificial intelligent
💻 C
📖 第 1 页 / 共 2 页
字号:
void subsumeClassifier(struct xClassifier *cl,struct xClassifier **parents,struct xClassifierSet *locset,struct xClassifierSet **pop)
{
  int i,j;
  /*Try first to subsume in parents */
  for(i=2*frand(),j=0; j<2; i=(i+1)%2, j++){ 
    if(parents[i]!=NULL && subsumes(parents[i],cl)){
      parents[i]->num++;
      freeClassifier(cl);
      return;
    }
  }
  
  if(subsumeClassifierToSet(cl, locset))
    return;

  if(subsumeClassifierToSet(cl, *pop))
    return;
 
  addClassifierToSet(cl,pop);
}

/* try to subsume in one set */
int subsumeClassifierToSet(struct xClassifier *cl, struct xClassifierSet *set)
{
  struct xClassifierSet * setp;
  struct xClassifier *subCl[MAX_POP_SIZE];
  int numSub  ;
  
  /*Try to subsume in the set*/
  for(setp=set,numSub=0; setp!=NULL; setp=setp->next){
    if(subsumes(setp->cl,cl)){
      subCl[numSub]=setp->cl;
      numSub++;
    }
  }
  /* if there were classifiers found to subsume, then choose randomly one and subsume */
  if(numSub>0){
    numSub=numSub*frand();
    subCl[numSub]->num++;
    freeClassifier(cl);
    return 1;
  }
  return 0;
}

/* check if classifier cl1 subsumes cl2 */
int subsumes (struct xClassifier *cl1, struct xClassifier * cl2)
{
  int ret=0;

  ret= (cl1->exp >= SUBSUME_EXPERIENCE) && (cl1->acc >= 0.99) && (strcmp(cl1->act,cl2->act)==0)
    && subsumesConditions ((cl1->con), (cl2->con));

  return ret;
}

/* check if the first condition subsumes the second */
int subsumesConditions (char * first, char * second)
{
  int result = (strlen (first) == strlen (second));
  int i = 0;  
  
  while (result && (first[i] != '\0'))
  {
    result &= ((first[i] == '#') || (first[i] == second[i]));
    i++;
  }
  
  return result;
}

/*######################################## crossover & mutation ##############################################*/

/* crosses the two received classifiers (right now: one-point crossover), return if the strings were changed */
int crossover(struct xClassifier **cl)
{
  int sep,len,i,ret=0;
  char ch;
  
  if(frand()<CROSSPX){
    /* crossover will be applied */
    /* get crossing site */
    len=strlen(cl[0]->con);
    sep=frand()*(len-1);
    /* do the cross */
    for(i=sep+1; i<len; i++){
      if((cl[0]->con)[i]!=(cl[1]->con)[i]){
	ret=1;
	ch=(cl[0]->con)[i];
	(cl[0]->con)[i]=(cl[1]->con)[i];
	(cl[1]->con)[i]=ch;
      }
    }
  }
  /* return if the conditions of the classifiers changed */
  return ret;
}

/* mutate one classifier */
int mutation(struct xClassifier *cl)
{
  int mp,len,mttr=0;
  
  len = strlen(cl->con) + strlen(cl->act);
  for(mp=0; mp<len; mp++){
    if(frand()<MUTPMUE){
      mttr=1;
      if(mp<(signed int)strlen(cl->con)){
	mutate(cl->con,mp,0);
      }else{
	mutate(cl->act,mp-strlen(cl->con),1);
      }
    }
  }
  /* return if the condition or action  of the classifier changed */
  return mttr;
}

/* do one mutation (either in the condition (type 0) or in the action (type 1) */
void mutate(char *string,int pos,int type)
{
  if(type==0){
    /* mutate condition -> 0, 1, or DONT_CARE */
    switch(string[pos]){
    case '0':
      if(frand()<0.5)
	string[pos]='1';
      else
	string[pos]=DONT_CARE;
      break;
    case '1':
      if(frand()<0.5)
	string[pos]='0';
      else
	string[pos]=DONT_CARE;
      break;
    case DONT_CARE:
      if(frand()<0.5)
	string[pos]='0';
      else
	string[pos]='1';
      break;
    default:
      printf("Mistake during mutation! string:%s pos:%d\n",string ,pos);
      break;
    }
  }else{
    /* mutate action -> 0, or 1 */
    if(string[pos]=='0')
      string[pos]='1';
    else
      string[pos]='0';
  }
}

/*####################################### adding classifiers to a set ###########################################*/

/* adds only the pointers to the killset, ensures that no pointer is added twice */
void addClassifierToKillSet(struct xClassifier *cl,struct xClassifierSet **killset)
{
  struct xClassifierSet *setp;
  
  for(setp=*killset; setp!=NULL; setp=setp->next){
    if(setp->cl == cl){
      /* Classifier is already in KillSet */
      return;
    }
  }
  /* add the classifier, as it is not already inthe killset */
  assert((setp=( struct xClassifierSet *)calloc(1,sizeof(struct xClassifierSet)))!=NULL);
  setp->cl=cl;
  setp->next=*killset;
  *killset=setp;
}

/* adds the classifier cl to the population, make 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 numeriosity and free the space of the new classifier */
  for(setp=*clSet;setp!=NULL;setp=setp->next){
    if(strcmp(setp->cl->con,cl->con)==0&&strcmp(setp->cl->act,cl->act)==0){
      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 a new Clasifier to the xClassifierSet */
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 ##################################################################*/

struct xClassifier * deleteStochClassifier(struct xClassifierSet **pop)
{
  struct xClassifierSet *setp,*setpl;
  struct xClassifier *killedp=NULL;
  double sum=0.,asum,meanf=0.;
  int size=0;  
  
  /* get the sum of the fitness and the numeriosity */
  for(setp=*pop; setp!=NULL; setp=setp->next){
    meanf+=setp->cl->fit;
    size+=setp->cl->num;
  }
  meanf/=(double)size;
  
  /* get the delete proportion, which depends on the average fitness */
  for(setp=*pop;setp!=NULL;setp=setp->next){
    sum+=getDelProp(setp->cl,meanf);
    if(sum<0.)
      printf("Sum overflow in deleteStochclassifier!!!\n");
  }

  /* choose the classifier that will be deleted */
  sum=frand()*sum;
  
  /* look for the classifier */
  setp=*pop;
  setpl=*pop;
  asum=getDelProp(setp->cl,meanf);
  while(asum<sum){
    setpl=setp;
    setp=setp->next;
    asum+=getDelProp(setp->cl,meanf);
  }
  
  /* delete the classifier */
  killedp=deleteTypeOfClassifier(setp,setpl,pop);
  
  /* return the pointer to the deleted classifier, to be able to update other sets */
  return killedp;
}

/* deletes the classifier setp from the population pop, setpl points to the classifier that is before setp in the list */
struct xClassifier * deleteTypeOfClassifier(struct xClassifierSet *setp,struct xClassifierSet *setpl,struct xClassifierSet **pop)
{
  struct xClassifier *killedp=NULL;

  /* setp must point to some classifier! */
  assert(setp!=NULL);

  if(setp->cl->num>1){
    /* if the numeriosity is greater than one -> just decrease it */
    setp->cl->num--;
  }else{
    /* if not, delete it and record it in killedp */
    if(setp==setpl){
      *pop=setp->next;
    }else{
      setpl->next=setp->next;
    }
    killedp=setp->cl;
    freeClassifier(setp->cl);
    free(setp);
  }
  /* return a pointer ot a deleted classifier (NULL if the numeriosity was just decreased) */
  return killedp;
}

/* return the delete proportion of one classifier, meanf is the average fitness in the population */
double getDelProp(struct xClassifier *cl, double meanf)
{
  double ret;
  if((cl->fit/cl->num) >= DELTA*meanf || cl->exp <= DELETION_EXPERIENCE)
    /* First case */
    ret=cl->peerssest*(double)cl->num;
  else
    /* Second case: Take the fitness of the classifier into account */
    ret=((cl->peerssest*cl->num*meanf)/(cl->fit/cl->num));
  return ret;
}



/* check if the classifier pointers that are in killset are in uset - delete the pointers if they are inside 
 * the classifiers in killset are already deleted, so do not read their values or try to delete tehm again*/
int updateSet(struct xClassifierSet **uset,struct xClassifierSet *killset)
{
  struct xClassifierSet *setp,*setpl,*killp,*usetp;
  int updated=1;
  
  /* If one of the sets is emoty -> do not do anything */
  if(*uset==NULL || killset==NULL)
    return 0;
  /* check all classifiers in uset */
  setp=*uset;
  while(updated && setp!=NULL){
    setp=*uset;
    setpl=*uset;
    updated=0;
    while(setp!=NULL && !updated){
      for(killp=killset;killp!=NULL;killp=killp->next){
	if(killp->cl == setp->cl){
	  /* If killed classifier found, delete the struct classifier set in uset */
	  updated=1;
	  if(setp==setpl){
	    usetp=*uset;
	    *uset=usetp->next;
	    free(usetp);
	    break;
	  }else{
	    setpl->next=setp->next;
	    free(setp);
	    break;
	  }
	}
      }
      /* check the whole uset again, if one pointer was deleted */
      if(updated)
	break;
      setpl=setp;
      setp=setp->next;
    }
  }
  /* return if the set was updated */
  return updated;
}

/*################################### concrete deletion of a classifier or a whole classifier set #################################*/

/* Frees only the complete xClassifierSet (not the xClassifiers itself)! */
void freeSet(struct xClassifierSet **cls)
{
  struct xClassifierSet *clp;
  
  while(*cls!=NULL)
    {
      clp=(*cls)->next;
      free(*cls);
      *cls=clp;
    }
}

/* Frees the complete xClassifierSet with the corresponding xClassifiers */
void freeClassifierSet(struct xClassifierSet **cls)
{
  struct xClassifierSet *clp;

  while(*cls!=NULL)
    {
      freeClassifier((*cls)->cl);
      clp=(*cls)->next;
      free(*cls);
      *cls=clp;
    }
}

/* Frees one classifier */
void freeClassifier(struct xClassifier *cl)
{
  free(cl->con);
  free(cl->act);
  free(cl);
}


/*############################################### output operations ##################################################*/

/* print the classifiers in a xClassifierSet */
void printClassifierSet(struct xClassifierSet *head)
{
  for(;head!=NULL;head=head->next)
    printClassifier(head->cl);
}

/* print the classifier in a xClassifierSet to the file fp */
void fprintClassifierSet(FILE *fp,struct xClassifierSet *head)
{
  fprintf(fp,"Cond.\tAction\tPredediction\tPredictionError\tFitness  \tNum Experience ActionSetSizeEst. LastGAIteration\n");
  for(;head!=NULL;head=head->next)
    fprintClassifier(fp, head->cl);
}

/* print a single classifier */
void printClassifier(struct xClassifier *c)
{
  printf("%s\t",c->con);
  printf("%s\t",c->act);  
  printf("%f\t%f\t%f\t%f\t", c->pre, c->preer/PAYMENT_RANGE, c->acc, PAYMENT_RANGE*c->fit);
  printf("%d %d %f %d\n", c->num, c->exp, c->peerssest, c->gaIterationTime);
}

/* print a single classifier to the file fp */
void fprintClassifier(FILE *fp,struct xClassifier *c)
{
  fprintf(fp,"%s\t",c->con);
  fprintf(fp,"%s\t",c->act);
  fprintf(fp,"%f\t%f\t%f\t%f\t", c->pre, c->preer/PAYMENT_RANGE, c->acc, PAYMENT_RANGE* c->fit);
  fprintf(fp,"%d %d %f %d\n", c->num, c->exp, c->peerssest, c->gaIterationTime);
}


/*########################################### sorting the classifier list ###################################################*/

/* sort the classifier set cls in numeriosity order or in prdiction order 
 * type 0 = numeriosity order, type 1 = prediction order */
struct xClassifierSet * sortClassifierSet(struct xClassifierSet **cls,int type)
{
  struct xClassifierSet *clsp, *maxcl, *newcls, *newclshead;
  double max;

  max=0.;
  assert((newclshead=( struct xClassifierSet *)calloc(1,sizeof(struct xClassifierSet)))!=NULL);
  newcls=newclshead;
  do{
    max=-100;
    /* check the classifier set cls for the next maximum -> already inserted classifier are referenced by the NULL pointer */
    for( clsp=*cls, maxcl=*cls; clsp->next!=NULL; clsp=clsp->next ) {
      if(clsp->cl!=NULL && ((type==0 && clsp->cl->num>max) || (type==1 && clsp->cl->pre>max))){
	if(type==0)
	  max=clsp->cl->num;
	else if (type==1)
	  max=clsp->cl->pre;
	maxcl=clsp;
      }
    }
    if(max>-100){
      assert((newcls->next=( struct xClassifierSet *)calloc(1,sizeof(struct xClassifierSet)))!=NULL);
      newcls=newcls->next;
      newcls->next=NULL;
      newcls->cl=maxcl->cl;
      /* do not delete the classifier itself, as it will be present in the new, sorted classifier list */
      maxcl->cl=NULL;
    }
  }while(max>-100);
  
  /* set the new xClassifierSet pointer and free the old stuff */
  newcls=newclshead->next;
  free(newclshead);
  freeSet(cls);
  /* return the pointer to the new xClassifierSet */
  return newcls;
}

/*################################## Utilitiy ################################################*/

/* get the abs value of value */
double absDouble(double value)
{
  if(value>=0.)
    return value;
  else
    return value*(-1.);
}

⌨️ 快捷键说明

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