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

📄 bfagent.m

📁 人工智能的matlab程序
💻 M
📖 第 1 页 / 共 5 页
字号:
  [to setSpecfactor: [from getSpecfactor]];
  [to setLastactive: [from getLastactive]];
  [to setSpecificity: [from getSpecificity]];
  [to setConditions: [from getConditions]];
  [to setCnt: [from getCnt]];
  if ( [from getCnt] ==0)
    [to setStrength: minstrength];
  return to;
}


/*"Given a list of forecasts, find the worst ones and put them into a
pool of rejects. This method requires 2 inputs, the name of the reject
list (actually, a Swarm Array) and the Array of forecasts. "*/
- (void)MakePool: (id <List>)rejects From: (id <Array>)list
{
  register int top;
  int i,j = 0 ;
  BFCast * aForecast;
  BFCast * aReject;
  
  top = -1;
  //pj: why not just start at 1 so we never worry about putting forecast 0 into the mix?
  for ( i=1; i < getInt(privateParams,"npool" ); i++ )
    {
      aForecast=[list atOffset: i];
      for ( j=top;  j >= 0 && (aReject=[rejects atOffset:j])&& ([aForecast getStrength] < [aReject  getStrength] ); j--)
	{
	  [rejects atOffset: j+1 put: aReject ];
	}  //note j decrements at the end of this loop
      [rejects atOffset: j+1 put: aForecast];
      top++;
    }
	  
  for ( ; i < getInt(privateParams,"numfcasts"); i++)
    {
      aForecast=[list atOffset: i];
      if ( [aForecast  getStrength]  < [[ rejects atOffset: top] getStrength ] ) 
	{
	  for ( j = top-1; j >= 0 && (aReject=[rejects atOffset:j]) && [aForecast getStrength] < [aReject  getStrength]; j--)
	    {
	      [rejects atOffset: j+1 put: aReject];
	    }
	}
      [rejects atOffset: j+1 put: aForecast];
    }
  //pj:note: we are not checking to see if forecast 0 is in here
}




/*------------------------------------------------------*/
/*	Tournament					*/
/*------------------------------------------------------*/
- (BFCast *) Tournament: (id <Array>) list
{
  
  int  numfcasts=[list getCount];
  BFCast * candidate1 = [list atOffset: irand(numfcasts)];
  BFCast *  candidate2;
    
  do
    candidate2 = [list atOffset: irand(numfcasts)];
  while (candidate2 == candidate1);

  if ([candidate1 getStrength] > [candidate2 getStrength])
    return candidate1;
  else
    return candidate2;
}




/*------------------------------------------------------*/
/*	Mutate						*/
/*------------------------------------------------------*/
- (BOOL)Mutate: (BFCast *)new Status: (BOOL)changed
  /*
     * For the condition bits, Mutate() looks at each bit with
     * probability pmutation.  If chosen, a bit is changed as follows:
     *    0  ->  * with probability 2/3, 1 with probability 1/3
     *    1  ->  * with probability 2/3, 0 with probability 1/3
     *    *  ->  0 with probability 1/3, 1 with probability 1/3,
     *           unchanged with probability 1/3
     * This maintains specificity on average.
     *VERY CONFUSING, because the values are actually 0,1, and 2
     CONVERTED LIKE SO

     0      1    1/3          2       1/3
     1      0    2/3          2       1/3
     2      0    2/3          1       1/3

     *
     * For the forecasting parameters, Mutate() may do one of two things,
     * independently for each parameter.
     * 1. "Long jump": the parameter is chosen randomly from its min-max
     *    range.
     * 2. "Short jump": the parameter is chosen randomly from a uniform
     *    distribution from oldvalue-nhood*range to oldvalue+nhood*range,
     *    where range = max-min.  Values outside the min-max range are
     *    mapped to the endpoint.
     * Method 1 is used with probability plong, method 2 is used with
     * probability pshort, and the parameter is left unchanged with
     * probability 1-plong-pshort.
     *
     * Returns YES if it actually changed anything, otherwise NO.
     */
{
  register int bit;
  double choice, temp;
  BOOL bitchanged = NO;
  int * bitlist= NULL;
  
  bitlist= [privateParams getBitListPtr];
  //pj: dont know why BFagents introduced bitchanged.??
  bitchanged = changed;
  if (privateParams->pmutation > 0) 
    {
      for (bit = 0; bit < privateParams->condbits; bit++) 
	{
	  if (bitlist[bit] < 0) continue;
	  if (drand() < privateParams->pmutation) 
	    {
	      //cond = cond0 + WORD(bit);
	      //if (*cond & MASK[bit])
	      if ([new getConditionsbit: bit] > 0 ) 
		{
		  if (irand(3) > 0) 
		    {
		      // *cond &= NMASK[bit];
		      //nr->specificity--;
		      [new maskConditionsbit: bit];
		      [new decrSpecificity];
		    }
		  else
		    //   *cond ^= MASK[bit];
		    [new switchConditionsbit: bit];
		    
		  bitchanged = changed = YES;
		}
	      else if (irand(3) > 0) 
		{
		 
		  //  *cond |= (irand(2)+1) << SHIFT[bit];
		  //  nr->specificity++;
		  [new setConditionsbit: bit FromZeroTo: (irand(2)+1)];
		  [new incrSpecificity];
		  bitchanged = changed = YES;
		}
	    }
	}
    }

  /* mutate p+d coefficient */
  choice = drand();
  if (choice < privateParams->plong) 
    {
      /* long jump = uniform distribution between min and max */
      [new setAval:   privateParams->a_min + privateParams->a_range*drand()] ;
      changed = YES;
    }
  else if (choice < privateParams->plong + privateParams->pshort) 
    {
      /* short jump  = uniform within fraction nhood of range */
      temp = [new getAval] + privateParams->a_range*privateParams->nhood*urand();
      [new setAval: (temp > privateParams->a_max? privateParams->a_max:
		     (temp < privateParams->a_min? privateParams->a_min: temp))];
      changed = YES;
    }
  /* else leave alone */

  /* mutate dividend coefficient */
  choice = drand();
  if (choice < privateParams->plong) 
    {
      /* long jump = uniform distribution between min and max */
      [new setBval:  privateParams->b_min + privateParams->b_range*drand() ];
      changed = YES;
    }
  else if (choice < privateParams->plong + privateParams->pshort) 
    {
      /* short jump  = uniform within fraction nhood of range */
      temp = [new getBval] + privateParams->b_range*privateParams->nhood*urand();
      [new setBval: (temp > privateParams->b_max? privateParams->b_max:
		     (temp < privateParams->b_min? privateParams->b_min: temp))];
      changed = YES;
    }
  /* else leave alone */

  /* mutate constant term */
  choice = drand();
  if (choice < privateParams->plong) 
    {
      /* long jump = uniform distribution between min and max */
      [new setCval:  privateParams->c_min + privateParams->c_range*drand()];
      changed = YES;
    }
  else if (choice < privateParams->plong + privateParams->pshort) 
    {
      /* short jump  = uniform within fraction nhood of range */
      temp = [new getCval] + privateParams->c_range*privateParams->nhood*urand();
      [new setCval: (temp > privateParams->c_max? privateParams->c_max:
		     (temp < privateParams->c_min? privateParams->c_min: temp))];
      changed = YES;
    }
  /* else leave alone */

  [new setCnt: 0];

  if (changed) 
    { 
      [new updateSpecfactor];
    }
  return(changed);
}



/*------------------------------------------------------*/
/*	Crossover					*/
/*------------------------------------------------------*/
- (BFCast *)Crossover: (BFCast *)newForecast Parent1: (BFCast *)parent1 Parent2: (BFCast *)parent2
  /*
     * On the condition bits, Crossover() uses uniform crossover -- each
     * bit is chosen randomly from one parent or the other.
     * For the real-valued forecasting parameters, Crossover() does
     * one of three things:
     * 1. Choose a linear combination of the parents' parameters,
     *    weighted by strength.
     * 2. Choose each parameter randomly from each parent.
     * 3. Choose one of the parents' parameters (all from one or all
     *    from the other).
     * Method 1 is chosen with probability plinear, method 2 with
     * probability prandom, method 3 with probability 1-plinear-prandom.
     */
{
  /* Uniform crossover of condition bits */
  register int bit;
  // unsigned int *cond1, *cond2, *newcond;
  int word;
  double weight1, weight2, choice;
      
  [newForecast setSpecificity: 0];

  for (word = 0; word <privateParams->condwords; word++)
    [newForecast setConditionsWord: word To: 0];

  for (bit = 0; bit < privateParams->condbits; bit++)
    {
     if ( irand(2) == 0)
	{
	  int value=[parent1 getConditionsbit: bit];
	  [newForecast setConditionsbit: bit FromZeroTo: value];
	  if (value > 0) [newForecast incrSpecificity]; 
	}
      else
	{
	  int value= [parent2 getConditionsbit: bit];
	  [newForecast setConditionsbit: bit FromZeroTo: value ];
	  if (value > 0) [newForecast incrSpecificity]; 
	}
    }

  /* Select one crossover method for the forecasting parameters */
  choice = drand();
  if (choice < privateParams->plinear) 
    {
      /* Crossover method 1 -- linear combination */
      weight1 = [parent1 getStrength] / ([parent1 getStrength] +
					 [parent2 getStrength]);
      weight2 = 1.0-weight1;
      [ newForecast setAval:  weight1*[parent1 getAval] + weight2*[parent2 getAval] ]; 
      [ newForecast setBval:  weight1*[parent1 getBval] + weight2*[parent2 getBval] ];
      [ newForecast setCval:  weight1*[parent1 getCval] + weight2*[parent2 getCval]] ;
    }
  else if (choice < privateParams->plinear + privateParams->prandom) 
    {
      /* Crossover method 2 -- randomly from each parent */
      if(irand(2))
	[newForecast setAval: [parent1 getAval]] ; else [newForecast setAval: [parent2 getAval]];
      if(irand(2))
	[newForecast setBval: [parent1 getBval]] ; else [newForecast setBval: [parent2 getBval]];   
      if(irand(2))
	[newForecast setCval: [parent1 getCval]] ; else [newForecast setCval: [parent2 getCval]];
    }
  else 
    {
      /* Crossover method 3 -- all from one parent */
      if (irand(2))
	{
	  [newForecast setAval: [parent1 getAval]] ;  
	  [newForecast setBval: [parent1 getBval]] ;    
	  [newForecast setCval: [parent1 getCval]] ;
	}
      else
	{
	  [newForecast setAval: [parent2 getAval]] ;  
	  [newForecast setBval: [parent2 getBval]] ;    
	  [newForecast setCval: [parent2 getCval]] ;
	}
    }

  {  //This is just error checking!
    BitVector * newcond;
    int specificity=0;
    [newForecast setCnt: 0 ];	// call it new in any case
    
  [newForecast updateSpecfactor];

  [newForecast setStrength :  0.5*([parent1 getStrength] + [parent2 getStrength])];


 //pj: next steps are purely diagnostic!
   newcond = [newForecast getConditionsObject];

    for (bit = 0; bit < privateParams->condbits; bit++)
 
    //if ((newcond[WORD(bit)]& ( 3 << ((bit%16)*2))) != 0)
    if ( [newcond getConditionsbit: bit] != 0 )
	{
	  specificity++;
	}
    //printf("CrossoverDiagnostic: newforecast Specificity %d should equal %d \n", [newForecast getSpecificity],specificity);
  }
   return newForecast;
}


/*------------------------------------------------------*/
/*	TransferFcasts					*/
/*------------------------------------------------------*/
- (void)TransferFcastsFrom: newlist To: forecastList Replace: rejects 
{
  id ind;
  BFCast * aForecast;
  BFCast * toDieForecast;

      //nnew = pp->nnew;
 
  ind = [newlist begin: [self getZone]];
  for ( aForecast = [ind next]; [ind getLoc]==Member; aForecast=[ind next] )
    {
      //toDieForecast = GetMort(aForecast, rejects);
      toDieForecast = [self GetMort: aForecast Rejects: rejects];
      toDieForecast = [self CopyRule: toDieForecast From: aForecast];
    }
  [ind drop];
}



/*------------------------------------------------------*/
/*	GetMort						*/
/*------------------------------------------------------*/
- (BFCast *)GetMort: (BFCast *)new Rejects: (id <List>)rejects
  /* GetMort() selects one of the npool weak old fcasts to replace
     * with a newly generated rule.  It pays no attention to strength,
     * but looks at similarity of the condition bits -- like tournament
     * selection, we pick two candidates at random and choose the one
     * with the MORE similar bitstring to be replaced.  This maintains
     * more diversity.
     */
{
  //register int bit, temp1, temp2, different1, different2;
  // struct BF_fcast *fptr;
  //unsigned int *cond1, *cond2, *newcond;
  //int npool, r1, r2, word, bitmax;

  unsigned int *cond1; unsigned int *cond2; uns

⌨️ 快捷键说明

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