|
ru.algorithms- RU.ALGORITHMS ---------------------------------------------------------------- From : Yuri Burger 2:468/85.3 11 May 2001 14:10:05 To : All Subject : FAQ: 3/4 -------------------------------------------------------------------------------- Q9. А на исходник простого ГА посмотреть можно? A. (Yuri Burger [2:468/85.3]) Вот. Собирал на Watcom C. Расчитано на 2 переменные. Кроссовер - классический, отбор - элитарный. // (c) BSM Group, Burger Y.A. (Kruger) // x = 0..XMaxValue // y = 0..YMaxValue #include <stdio.h> #include <stdlib.h> #include "math.h" #define PI 3.14159265358979323846 #define MaxGenNum 256 #define MaxPopulationLeng 65536 long XMaxValue=1024; long YMaxValue=1024; double LastX,LastY,LastZ; char BestIsIn=0; double BestX,BestY,BestZ; double NumOfHromosoms; long PBestLeng=16; // длина лучшей выборки long PMaxLeng=128; // максимальная длина популяции long PLeng=0; // текущая длина популяции long HLeng=32; // количество ген в хромосоме double MutateHPercent=8;// процент мутаций в популяции double MutateGPercent=8;// процент мутаций в хромосоме typedef struct { char G[MaxGenNum]; // набор ген double V; // значение оценки }HROMOSOM; HROMOSOM *P[MaxPopulationLeng]; // популяция HROMOSOM *B[MaxPopulationLeng]; // для селекции void PrintInfo(void) { printf("X=%g ",BestX); printf("Y=%g ",BestY); printf("Z(X,Y)=%g\n",BestZ); } double CalcZ(double X,double Y) { double z; double sx=X*PI/XMaxValue; double sy=Y*PI/YMaxValue; z=fabs(127+200*(cos(sx*sx+sy*sy)*cos(sy*sx))*sqrt(sin(sx)*sin(sy))); return z; } void SortPopulation(long l,long r) { long i=l,j=r; double x=P[(r+l)/2]->V; HROMOSOM *y; do { while (P[i]->V > x) i++; while (x > P[j]->V) j--; if (i<=j) { y=P[i];P[i]=P[j];P[j]=y; i++;j--; }; }while(i<j); if (l<j) SortPopulation(l,j); if (i<r) SortPopulation(i,r); } double GetX(HROMOSOM *h) { long t; double d=0; for(t=0;t<HLeng;t++) { d+=(double)h->G[t]*pow(2,t-0); } d=XMaxValue*d/(pow(2,HLeng)-1); return d; } double GetY(HROMOSOM *h) { long t; double d=0; for(t=HLeng;t<HLeng*2;t++) { d+=(double)h->G[t]*pow(2,t-HLeng); } d=XMaxValue*d/(pow(2,HLeng)-1); return d; } double MiFunction(HROMOSOM *h) { double X,Y,Z; X=GetX(h); Y=GetY(h); Z=CalcZ(X,Y); LastX=X; LastY=Y; LastZ=Z; return Z; } HROMOSOM *NewHromosom(void) { HROMOSOM *t; t=(HROMOSOM *)calloc(1,sizeof(HROMOSOM)); NumOfHromosoms++; return t; } void KillHromosom(HROMOSOM *h) { free(h); } int AddHromosom(HROMOSOM *h) { long mh=0; long t; if(PLeng<PMaxLeng) { P[PLeng]=h; PLeng++; return 0; } else { for(t=0;t<PLeng;t++) if(P[t]->V < P[mh]->V)mh=t; if(h->V > P[mh]->V)// >= ? { KillHromosom(P[mh]); P[mh]=h; } else return -1; return 0; } } void RandomFillHromosom(HROMOSOM *h) { long t; for(t=0;t<HLeng*2;t++) { if(rand()<RAND_MAX/2) h->G[t]=0; else h->G[t]=1; } h->V=MiFunction(h); } void GenerateHromosom(HROMOSOM *h1,HROMOSOM *h2,HROMOSOM *s1,HROMOSOM *s2) { long t; long l=rand()*HLeng*2/RAND_MAX; for(t=0;t<l;t++) { h1->G[t]=s1->G[t]; h2->G[t]=s2->G[t]; } for(t=l;t<HLeng*2;t++) { h1->G[t]=s2->G[t]; h2->G[t]=s1->G[t]; } h1->V=MiFunction(h1); h2->V=MiFunction(h2); } void MutateHromosom(HROMOSOM *h) { double l1,l2; long g; l1=MutateHPercent*RAND_MAX/100; l2=MutateGPercent*RAND_MAX/100; if(rand()<l1) { for(g=0;g<HLeng*2;g++) { if(rand()<l2) { h->G[g]^=1; } } } h->V=MiFunction(h); } void GA() { HROMOSOM *h,*h1,*h2; long x,y,z,mx,my; long c=0; long t; for(t=0;t<PMaxLeng;t++) { h=NewHromosom(); RandomFillHromosom(h); if(AddHromosom(h)==-1)KillHromosom(h); } if(PLeng>0)SortPopulation(0,PLeng-1); Loop: if(kbhit()){getch();goto Exit;} for(t=0;t<PBestLeng;t++)B[t]=P[t]; for(my=0;my<PBestLeng;my++) { for(mx=my+1;mx<PBestLeng;mx++) { c++; h1=NewHromosom(); h2=NewHromosom(); GenerateHromosom(h1,h2,B[my],B[mx]); MutateHromosom(h1); if(AddHromosom(h1)==-1)KillHromosom(h1); MutateHromosom(h2); if(AddHromosom(h2)==-1)KillHromosom(h2); } } if(PLeng>0)SortPopulation(0,PLeng-1); if(BestIsIn==0||P[0]->V>BestZ) { BestIsIn=1; BestX=GetX(P[0]); BestY=GetY(P[0]); BestZ=P[0]->V; PrintInfo(); } goto Loop; Exit: for(x=0;x<PLeng;x++)KillHromosom(P[x]); return; } int main(void) { GA(); return 0; } ****************************************************************************** Q10. Какие существуют методы кроссинговера? A. (Дэвид Бисслей, статья) "Традиционный" генетический алгоритм использует одноточечный кроссинговер, в котором две скрещивающиеся хромосомы разрезаются один раз в соответствующей точке и производится обмен полученными частями. Однако было изобретено много других различных алгоритмов с иными видами кроссинговера, часто включающих больше чем одну точку разреза. DeJong исследовал эффективность многоточечного кроссинговера и пришел к выводу, что двуточечный кроссинговер дает улучшение, но что дальнейшее добавление точек кроссинговера редуцирует деятельность генетического алгоритма. Проблема с добавлением дополнительных точек кроссинговера состоит в том, что стандартные блоки, вероятно, будут прерваны. Однако преимущество большего количества точек кроссинговера состоит в том, что пространство состояний может быть исследовано более полно и подробно. ДВУХТОЧЕЧHЫЙ КРОССИHГОВЕР. В двухточечном кроссинговере (и многоточечном кроссинговере вообще) хромосомы расцениваются как циклы, которые формируются соединением концов линейной хромосомы вместе. Для замены сегмента одного цикла сегментом другого цикла требуется выбор двух точек разреза. В этом представлении, одноточечный кроссинговер может быть рассмотрен как кроссинговер с двумя точками, но с одной точкой разреза, зафиксированной в начале строки. Следовательно, двухточечный кроссинговер решает ту же самую задачу, что и одноточечный кроссинговер , но более полно. Хромосома, рассматриваемая как цикл, может содержать большее количество стандартных блоков, так как они могут совершить "циклический возврат" в конце строки. В настоящий момент многие исследователи соглашаются, что двухточечный кроссинговер вообще лучше, чем одноточечный. линейное представление: хххххххххххх ДДДДДДДДДДДД> циклическое представление:Ъ>ххххххххххххДї АДДДДДДДДДДДДДДЩ УHИФИЦИРОВАHHЫЙ (ОДHОРОДHЫЙ) КРОССИHГОВЕР. Унифицированный кроссинговер принципиально отличается от одноточечного кроссинговера. Каждый ген в потомстве создается посредством копирования соответствующего гена от одного или другого родителя, выбранного согласно случайно сгенерированной маске кроссинговера. Если в маске кроссинговера стоит 1, то ген копируется от первого родителя, если в маске стоит 0, то ген копируется от второго родителя. Процесс повторяется с обмененными родителями для создания второго потомства. Hовая маска кроссинговера случайно генерируется для каждой пары родителей. ******************************************************************************. Kрюгер. --- * Origin: А хто тут есть, у кого есть за что поесть? (2:468/85.3) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.algorithms/23173afbf2cd.html, оценка из 5, голосов 10
|