2017-06-07 163 views
1

我有一個多目標最小化函數。我想在R中使用NSGA-II。這裏有一些軟件包:nsga2R和mco。但是這些軟件包不支持二進制編碼的染色體。在我的健身功能中,我需要二元染色體來達到最佳解決方案,因爲我的問題的結構。有沒有什麼辦法可以在nsga2中使用二進制編碼的染色體(或者用不同的算法)來處理R?謝謝。在R中使用NSGA-II的二進制編碼遺傳算法

回答

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();

然後

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(); 
 
}

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(); 
 
\t if(unif_rand() <= 0.5){ 
 
\t \t pop->ind[i].input[j] = 0; 
 
\t } 
 
\t else{ 
 
\t \t pop->ind[i].input[j] = 1; 
 
\t } 
 
    } 
 
    } 
 
    PutRNGstate(); 
 
}

2.定義函數randomperc()如下

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]); 
 
}

3.替代每unif_rand()與 'nsga2.c'

4.建立R中

包randomperc()