Member 14074021 Ответов: 2

Я написал эту программу, которая является генетическим алгоритмом, но она возвращает те же значения.


Я написал программу ниже, но когда я ее запускаю, программа возвращает те же значения. Я пытался отладить его, но не могу сказать, в чем проблема.

Что я уже пробовал:

#include <bits/stdc++.h>
using namespace std;
#define CROSSOVER_RATE            0.3
#define MUTATION_RATE             0.01
#define POP_SIZE                  50          
#define CHROMO_LENGTH             50
#define GENE_LENGTH               10
#define MAXGENES                  1000

struct chromo_typ
{    //the binary bit string is held in a std::string
  string    bits;  
  double    fitness;
  double    rfitness;
  double    cfitness;
   
};
 int generation;
 int cur_best;

  //storage for our population of chromosomes.
 chromo_typ Population[POP_SIZE+1];
 chromo_typ NewPopulation[POP_SIZE+1];

//return random 0 or 1     
int random_num(int start, int end)
{
    int range = (end-start)+1;
    int random_int = start+(rand()%range);
    return random_int;
}

//return random a number in (0,1)
double doubleRand() {  return double(rand()) / (double(RAND_MAX) + 1.0);}

//create the chromosome
string  GetRandomBits(int length)
{    string bits;
        for (int i=0; i<length; i++)
    {
        if (random_num(0,1) == 1)
             bits += "1";
         else
 
            bits += "0";
    }
    return bits;
}

//the function return the decimal value for the binary string
int BinToDec(string bits)
{   int val = 0;
    int p=1;
    for (int i = bits.length(); i > 0; i--)
    { if (bits.at(i-1) == '1')
        { val += p;}
        p *= 2;
    }
    return val;
}

//the function return the value in the interval [a,b] for the bynari string
double nr_interval(int valoare, double a, double b)
{
    double result;
    result=0.0;
    result=a+valoare*((b-a)/(pow(2,30)-1));
    return result;
}

//find the minimum value for this function
//we calculate the minimum value for 5 dimension
double De_Jong(string bits){
    double x=0.0;
    double nr=0.0;
     for(size_t i=0; i<sizeof(bits); i=i+GENE_LENGTH)
     {  double nr = nr_interval(BinToDec(bits.substr(0,i+GENE_LENGTH)),-5.12,5.12);
       x=x+nr*nr;   
     }
 return x;   
}

//the mutation
void mutate()
{  for(int i=0; i<POP_SIZE; i++)
    for (int j=0; j<CHROMO_LENGTH; j++)
    {
        if (doubleRand() < MUTATION_RATE)
        {
            if (Population[i].bits[j] == '1')
 
                Population[i].bits[j] = '0';
 
            else
 
            Population[i].bits[j] = '1';
        }
    }
}

void Xover(string &offspring1, string &offspring2)
{
    //create a random crossover point
    int crossover = (int) (doubleRand() * CHROMO_LENGTH);
 
    string t1 = offspring1.substr(0, crossover) + offspring2.substr(crossover, CHROMO_LENGTH);
    string t2 = offspring2.substr(0, crossover) + offspring1.substr(crossover, CHROMO_LENGTH);
 
    offspring1 = t1; offspring2 = t2;                 
  
}

//the function choose two strings and applied the Xover
void crossover(void){
    int i, m, one;
    int first=0;
    double x;
    for(m=0; m<POP_SIZE; m++)
    {  x=doubleRand();
     //dependent on the crossover rate
     if (x < CROSSOVER_RATE)
     {
         ++first;
         if(first%2 == 0)
         Xover(Population[one].bits, Population[m].bits);
         else
         one=m;
     }
  
    }
}

//roulette wheel  selection
void select (void)
{
    int m, i ,j;
    double sum=0.0;
    double p;
    

for(m=0; m<POP_SIZE; m++)
{
    sum +=Population[m].fitness;
}

for(m=0; m<POP_SIZE; m++)
{
    Population[m].rfitness=Population[m].fitness/sum;
}

Population[0].cfitness=Population[0].rfitness;

for(m=1; m<POP_SIZE ;m++)
{
    Population[m].cfitness=Population[m-1].cfitness-Population[m].rfitness;
}
for(i=0; i<POP_SIZE;i++){
    p=doubleRand();
    if(p< Population[0].cfitness)
     NewPopulation[i]=Population[0];
     else
     {
         for(j=0; j<POP_SIZE; j++)
           if(p>= Population[j].cfitness && p<Population[j+1].cfitness)
           NewPopulation[i]=Population[j+1];
     }
}

for(i=0;i<POP_SIZE;i++)
   Population[i]=NewPopulation[i];
}
void keep_the_best()
{ int m;
 int i;
 cur_best=0; 
 for(m=0;m<POP_SIZE;m++)
 {
     if(Population[m].fitness<Population[POP_SIZE].fitness)
     cur_best=m;
     Population[POP_SIZE].fitness=Population[m].fitness;
  }
 for(i=0;i<=CHROMO_LENGTH;i++)
 Population[POP_SIZE].bits[i]=Population[cur_best].bits[i];
}

//initialization
void initializare()
{    int i;
for(i=0; i<=POP_SIZE; i++)
     Population[i].bits=GetRandomBits(CHROMO_LENGTH);
     Population[i].fitness=0.0;
     Population[i].rfitness=0.0;
     Population[i].cfitness=0.0;
}

//calculate the function value for every string
void eval(void)
{
    int jj;
    for(jj=0; jj< POP_SIZE; jj++)
      Population[jj].fitness=De_Jong(Population[jj].bits);
}

 int main(){
     int i;
     generation=0;
     initializare();
     eval();
     keep_the_best();
     while(generation < MAXGENES) //the number of iteration
     { generation++;
       select();
       mutate();
       cout<< "GENERATION: "<< generation;
       cout<<endl;
       cout<< "BEST VALUE: " << Population[POP_SIZE].fitness;
       cout<<endl;
       eval();
       
     }
     cout<<endl;
 for( i=0; i<CHROMO_LENGTH; i++)
 {
     cout<<Population[POP_SIZE].bits[i];
 }
 cout<<endl;
 cout<< Population[POP_SIZE].fitness;

return 0;
} 

2 Ответов

Рейтинг:
19

Rick York

Я думаю, что вам не хватает некоторых фигурных скобок в инициализаторе. Так и должно быть:

//initialization
void initializare()
{
    int i;
    for( i = 0; i <= POP_SIZE; i++ )
    {
        Population[i].bits=GetRandomBits(CHROMO_LENGTH);
        Population[i].fitness=0.0;
        Population[i].rfitness=0.0;
        Population[i].cfitness=0.0;
    }
}
Без фигурных скобок инициализировалось только поле bits для всех элементов.

Еще одна вещь - вы можете захотеть запустить генератор случайных чисел. Обычно это делается с помощью вызова функции srand() и передачи ей начального значения. Если вам нужна повторяющаяся последовательность, выберите простое число. В противном случае time(NULL) % RAND_MAX-это хорошее значение для заполнения уникальной последовательности значений при каждом запуске программы.


Рейтинг:
0

Patrice T

Цитата:
Я пытался отладить его, но не могу сказать, в чем проблема.

Похоже, тебе нужно отточить свое отладочное фу.
Если вы используете отладчик правильно, вы не можете быть в этой ситуации.
Цитата:
Я написал программу ниже, но когда я ее запускаю, программа возвращает те же значения.

Вы знаете, что одно и то же значение каждый раз неверно, вы знаете, как строится результат, вы знаете, какие значения должны меняться между запусками и причиной.
С помощью отладчика проверьте все эти значения, когда что-то ведет себя не так, как ожидалось, исследуйте, что неправильно в том, как оно построено ...