R

时间:2017-06-07 12:52:41

标签: r genetic-algorithm

我有一个多目标最小化函数。我想在R中使用NSGA-II。有这样的软件包:nsga2R和mco。但是这些包不支持二进制编码的染色体。在我的健身功能中,由于我的问题结构,我需要二进制染色体来实现最佳解决方案。有没有办法在nsga2中使用二进制编码染色体(或者可能使用不同的算法)?感谢。

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题所以我决定自己解决这个问题。但是,如果这是正确的方式,就没有保证。

以下部分适用于包' mco'
我将部分nsga2实现中的部分复制到了' mco'包。 此解决方法仅适用于二进制(0-1)变量。

1。在/src/nsga2.c中重写函数如下:



static void mutate_ind (nsga2_ctx *ctx, individual *ind) {
  int j;
  double prob;
  GetRNGstate();
  for (j = 0; j < ctx->input_dim; j++)
    {
    //for (k=0; k < ctx[j]->input_dim; k++)
    //{
      //prob = randomperc();
      prob = unif_rand();
      if (prob <= ctx->mutation_probability) {
        if (ind->input[j] == 0)
        {
          ind->input[j] = 1;
        }
        else
        {
          ind->input[j] = 0;
        }
        ctx->input_mutations+=1;
      }
    //}
  }
  PutRNGstate();
&#13;
&#13;
&#13;

然后

&#13;
&#13;
static void crossover (nsga2_ctx *ctx,
                       individual *parent1, individual *parent2,
                       individual *child1, individual *child2) {

  
  int i;
  int nbits=1;
  double rand;
  int temp, site1, site2, temp2, temp3;
  
  GetRNGstate();
  
    rand=unif_rand();
    if (rand <= ctx->crossing_probability)
    {
      ctx->input_crossings++;
      //site1 = rnd(0,ctx->input_dim);
      //site2 = rnd(0,ctx->input_dim);
      if(unif_rand()<=0.5){
        temp2=0;
      }else{
        temp2=1;
      }
      
      if(unif_rand()<=0.5){
        temp3=0;
      }else{
        temp3=1;
      }
      
      site1=temp2;
      site2=temp3;
      
      if (site1 > site2)
      {
        temp = site1;
        site1 = site2;
        site2 = temp;
      }
      for (i=0; i<site1; i++)
      {
        child1->input[i] = parent1->input[i];
        child2->input[i] = parent2->input[i];
      }
      for (i=site1; i<site2; i++)
      {
        child1->input[i] = parent2->input[i];
        child2->input[i] = parent1->input[i];
      }
      for (i=site2; i<nbits; i++)
      {
        child1->input[i] = parent1->input[i];
        child2->input[i] = parent2->input[i];
      }
    }
    else
    {
      for (i=0; i<nbits; i++)
      {
        child1->input[i] = parent1->input[i];
        child2->input[i] = parent2->input[i];
      }
    }

  PutRNGstate();
}
&#13;
&#13;
&#13;

&#13;
&#13;
static void population_initialize(nsga2_ctx *ctx, population *pop) {
  GetRNGstate();
  int i, j;
  for (i = 0; i < pop->size; ++i)  {
    for (j=0; j<ctx->input_dim; ++j) {
      /* Generate random value between lower and upper bound */
      //double delta = ctx->upper_input_bound[j] - ctx->lower_input_bound[j];
      //pop->ind[i].input[j] = ctx->lower_input_bound[j] + delta*unif_rand();
	  if(unif_rand() <= 0.5){
		  pop->ind[i].input[j] = 0;
	  }
	  else{
		  pop->ind[i].input[j] = 1;
	  }
    }
  }
  PutRNGstate();
}
&#13;
&#13;
&#13;

2。定义函数randomperc(),如下所示

&#13;
&#13;
double seed;
double oldrand[55];
int jrand;

/* Create next batch of 55 random numbers */
void advance_random ()
{
  int j1;
  double new_random;
  for(j1=0; j1<24; j1++)
  {
    new_random = oldrand[j1]-oldrand[j1+31];
    if(new_random<0.0)
    {
      new_random = new_random+1.0;
    }
    oldrand[j1] = new_random;
  }
  for(j1=24; j1<55; j1++)
  {
    new_random = oldrand[j1]-oldrand[j1-24];
    if(new_random<0.0)
    {
      new_random = new_random+1.0;
    }
    oldrand[j1] = new_random;
  }
}

/* Fetch a single random number between 0.0 and 1.0 */
double randomperc()
{
  jrand++;
  if(jrand>=55)
  {
    jrand = 1;
    advance_random();
  }
  return((double)oldrand[jrand]);
}
&#13;
&#13;
&#13;

3。在&#39; nsga2.c&#39;

中用randomperc()替换每个unif_rand()

4. 在R

中构建软件包