next up previous contents
Next: Module: Backpropagation Up: Source Code Previous: Module: Standard Network   Contents

Subsections

Module: Genetic Algorithm

File: gen.h


  1	
  2	/* Declarations of general genetic algorithms */
  3	
  4	#ifndef GEN_H
  5	#define GEN_H   1
  6	
  7	#include "defs.h"
  8	
  9	char *GenOptStr();
 10	char *GenUsage();
 11	char GenParamStr[256];
 12	
 13	/* CONSTANTS */
 14	
 15	int Pcopy;      /* % of indiv. to copy per gen. */
 16	int Pmutate;    /* % of indiv. to mutate per gen.*/
 17	int Pcrossover; /* % of indiv. to crossover per gen. */
 18	
 19	int Ncopy;      /* no. of indiv. to copy per gen. */
 20	int Nmutate;    /* no. of indiv. to mutate per gen.*/
 21	int Ncrossover; /* no. of indiv. to crossover per gen. */
 22	
 23	int Decimation; /* initial decimation factor */
 24	float DecErrMin;
 25	float DecErrAvg;
 26	
 27	int HashLen;    /* lenth of hashkey 9n bits */
 28	int HashSize;   /* size of hashtable */
 29	
 30	/* Variables set by calcerr */
 31	
 32	int Nunique;    /* no. of different indiv. */
 33	int Nredundant; /* no. of redundant indiv. */
 34	int Nmismatch;  /* no. of mismatches */
 35	
 36	float ErrMin;
 37	float ErrAvg;
 38	int TopInd;
 39	
 40	/* Arrays */
 41	
 42	ind    *Pop;    /* Poulation */
 43	errtyp *Err;    /* errorlist of Populaton */
 44	
 45	/* Procedures */
 46	
 47	int handleGenOpt(char opt,char* arg);
 48	int initGen(int popsize,int popmem);
 49	void randomPop(int popsize);
 50	
 51	int hashfct(ind x);
 52	void clearerrtab();
 53	
 54	errtyp geterr(int n);
 55	void mutate(ind x0,ind x1);
 56	void crossover(ind x0,ind y0,ind x1,ind y1);
 57	void copy(ind x0,ind x1);
 58	void calcerrors(int popsize);
 59	void selection(int popsize);
 60	
 61	#endif

File: gen.c


  1	
  2	/* Implementation of general genetic algorithms */
  3	
  4	#include "defs.h"
  5	#include "gen.h"
  6	#include "ind.h"
  7	
  8	/* Parameter Handling */
  9	
 10	#define DEFMUTATE       60
 11	#define DEFNMUTATE      AUTO
 12	#define DEFCOPY         0
 13	#define DEFDECIMATION   0
 14	#define DEFHASH         AUTO
 15	
 16	char *GenOptStr() {return "m:n:c:u:d:h:\0";}
 17	
 18	char *GenUsage() {return
 19	  "Genetic Parameters:\n"
 20	  "-m <percentage of mutations>:     60\n"
 21	  "-n <n for 1..n point mutations>:  auto\n"
 22	  "-c <percentage of copies>:        0\n"
 23	  "-u <perc. of uniform selections>: 0\n"
 24	  "-d <initial decimation factor>:   0\n"
 25	  "-h <size of hashtable (0=off)>:   auto\n\0";}
 26	
 27	/* set default values */
 28	
 29	int Pcopy       =DEFCOPY;       /* % of indiv. to copy per gen. */
 30	int Pmutate     =DEFMUTATE;     /* % of indiv. to mutate per gen.*/
 31	int Puniform    =0;             /* % of indiv. for uniform selection */
 32	int Nmutate     =DEFNMUTATE;    /* 1..Nmutate point mutations */
 33	int Decimation  =DEFDECIMATION; /* initial decimation factor */
 34	int HashLen     =DEFHASH;       /* lenth of hashkey 9n bits */
 35	int HashSize    =0;             /* size of hashtable */
 36	int Nunique     =UNDEF;         /* no. of different indiv. */
 37	int Nredundant  =UNDEF;         /* no. of redundant indiv. */
 38	int Nmismatch   =UNDEF;         /* no. of mismatches */
 39	
 40	ind *OldPop;    /* old population */
 41	int HashMask;   /* HashSize-1 */
 42	int *HashTab;
 43	int Nuniform;
 44	
 45	int handleGenOpt(char opt,char* arg)
 46	{
 47	  switch(opt)
 48	  {
 49	    case 'm': return (Pmutate   =getint(arg,0,100))<0;
 50	    case 'n': return (Nmutate   =getint(arg,1,1000))<0;
 51	    case 'c': return (Pcopy     =getint(arg,0,100))<0;
 52	    case 'u': return (Puniform  =getint(arg,0,100))<0;
 53	    case 'd': return (Decimation=getint(arg,0,100))<0;
 54	    case 'h': return (HashLen   =getint(arg,0,16))<0;
 55	    default: return 1;
 56	  };
 57	}
 58	
 59	int initGen(int popsize,int popmem)
 60	{
 61	  int i,j,k,n,h,t;
 62	  word *p;
 63	  ind* pop;
 64	  char s[128];
 65	  errtyp e,m;
 66	
 67	  GenCalcs=0;
 68	  Pcrossover=100-Pmutate-Pcopy;
 69	  if(Pcrossover<0) return 1;
 70	  Nuniform=Puniform*(MAXRANDOM/100);
 71	
 72	  if(HashLen==AUTO) HashLen=Pmutate>50 ? 0 : duallog(popsize)+1;
 73	  if(HashLen)
 74	  {
 75	    if(popsize>(1<<HashLen)) return 1;
 76	    HashSize=1 << HashLen;
 77	    HashMask=HashSize-1;
 78	    HashTab=(int*)malloc(HashSize*WORDLEN);
 79	  };
 80	  if(!(Pop=(ind*)malloc(popmem*INDLEN))) return 1;
 81	  if(!(p=(word*)malloc(popmem*CrWords*WORDLEN))) return 1;
 82	  for(i=0;i<popmem;i++) Pop[i]=p+i*CrWords;
 83	  if(!(OldPop=(ind*)malloc(popmem*INDLEN))) return 1;
 84	  if(!(p=(word*)malloc(popmem*CrWords*WORDLEN))) return 1;
 85	  for(i=0;i<popmem;i++) OldPop[i]=p+i*CrWords;
 86	  if(!(Err=(errtyp*)malloc(popmem*ERRLEN))) return 1;
 87	  if(Decimation<=1) Decimation=0;
 88	  if(Decimation)
 89	  {
 90	    h=HashLen; HashLen=0;
 91	    DecErrAvg=0; DecErrMin=MAXERROR;
 92	    k=(popsize-1)/Decimation+1; n=0;
 93	    while(n<popsize)
 94	    {
 95	      randomPop(popsize);
 96	      calcerrors(popsize);
 97	      if(DecErrMin>ErrMin) DecErrMin=ErrMin;
 98	      DecErrAvg+=ErrAvg;
 99	      for(i=0;i<k && n<popsize;i++)
100	      {
101	        t=0;
102	        for(j=1;j<popsize;j++)
103	          if(Err[j]<Err[t]) t=j;
104	        copy(Pop[t],OldPop[n++]);
105	        Err[t]=MAXERROR;
106	      };
107	    };
108	    pop=Pop; Pop=OldPop; OldPop=pop;
109	    DecErrAvg/=Decimation;
110	    HashLen=h;
111	  } else {
112	    randomPop(popsize);
113	  };
114	  if(Nmutate==AUTO) Nmutate=CrBits/50+1;
115	
116	  s[0]=0;
117	  if(HashLen) sprintf(s,", HashSize = %d",HashSize);
118	  sprintf(GenParamStr,
119	    "Genetic:    Pcopy = %d %%, Pmutate(1..%d pt.) = %d %%, "
120	    "Pcrossover = %d %%%s\n"
121	    "            Selection %d %% linear, %d %% uniform\n",
122	    Pcopy,Nmutate,Pmutate,Pcrossover,s,100-Puniform,Puniform);
123	  if(Decimation)
124	  {
125	    sprintf(s,"Decimation: Factor = %d, PopSize = %d, "
126	      "MinErr=%6.2f, AvgErr=%6.2f\n",
127	      Decimation,popmem*Decimation,DecErrMin,DecErrAvg);
128	    strcat(GenParamStr,s);
129	  };
130	  return 0;
131	}
132	
133	void randomPop(int popsize)
134	{
135	  int i,j;
136	  word m;
137	  byte *p;
138	
139	  p=(byte*)Pop[0];
140	  for(i=0;i<popsize*CrWords*WORDLEN;i++) p[i]=getrand() & 0xff;
141	  j=CrBits % (8*WORDLEN);
142	  if(CrBits%(WORDLEN*8))
143	  {
144	    m=(1<<j)-1;
145	    for(i=0;i<popsize;i++)
146	      Pop[i][CrWords-1] &= m;
147	  };
148	}
149	
150	void clearerrtab()
151	{
152	  int i;
153	
154	  for(i=0;i<HashSize;i++) HashTab[i]=NOENTRY;
155	  Nunique=Nredundant=Nmismatch=0;
156	}
157	
158	int hashfct(ind x)
159	{
160	  int i;
161	  word w=0;
162	
163	  for(i=0;i<CrWords;i++) w+=x[i];
164	  w+=w>>HashLen;
165	  w+=w>>HashLen;
166	  w+=w>>HashLen;
167	  return (int)(w & HashMask);
168	}
169	
170	errtyp geterr(int n)
171	{
172	  int i,j,h,k;
173	  word w;
174	  errtyp e;
175	
176	  h=hashfct(Pop[n]);
177	mismatch:
178	  k=HashTab[h];
179	  if(k==NOENTRY)
180	  {
181	    e=Err[n]=calcerr(Pop[n]);
182	    HashTab[h]=n;
183	    Nunique++;
184	    return e;
185	  } else {
186	    for(i=0;i<CrWords;i++)
187	      if(Pop[n][i]!=Pop[k][i])
188	      {
189	        h=(h+1)&HashMask;
190	        Nmismatch++;
191	        goto mismatch;
192	      };
193	    e=Err[n]=Err[k];
194	    Nredundant++;
195	    return e;
196	  };
197	}
198	
199	void mutate(ind x0,ind x1)
200	{
201	  int i,k,m;
202	  for(i=0;i<CrWords;i++) x1[i]=x0[i];
203	  m=getrand()%Nmutate;
204	  for(i=0;i<=m;i++)
205	  {
206	    k=getrand()%CrBits;
207	    x1[wordoffs(k)]^=1<<bitoffs(k);
208	  };
209	}
210	
211	void crossover(ind x0,ind y0,ind x1,ind y1)
212	{
213	  int n,i,k;
214	  word w,m,xx0,xx1,yy0,yy1;
215	
216	  n=getrand()%CrBits; n=67;
217	  k=wordoffs(n);
218	  for(i=0;i<k;i++)
219	  {
220	    x1[i]=y0[i]; y1[i]=x0[i];
221	  };
222	  m=(1<<bitoffs(n))-1;
223	
224	  xx0=m & (x0[k]); xx1=(~m) & (x0[k]);
225	  yy0=m & (y0[k]); yy1=(~m) & (y0[k]);
226	
227	  x1[k]=yy0|xx1;
228	  y1[k]=xx0|yy1;
229	
230	  for(i=k+1;i<CrWords;i++)
231	  {
232	    x1[i]=x0[i]; y1[i]=y0[i];
233	  };
234	
235	}
236	
237	void copy(ind x0,ind x1)
238	{
239	  int i;
240	
241	  for(i=0;i<CrWords;i++) x1[i]=x0[i];
242	}
243	
244	void calcerrors(int popsize)
245	{
246	  int i;
247	  errtyp e,sum,min;
248	
249	  sum=0; min=MAXERROR;
250	  if(HashLen)
251	  {
252	    clearerrtab();
253	    for(i=0;i<popsize;i++)
254	    {
255	      e=geterr(i);
256	      sum+=e;
257	      if(e<min) { min=e; TopInd=i; };
258	    };
259	  } else {
260	    for(i=0;i<popsize;i++)
261	    {
262	      e=Err[i]=calcerr(Pop[i]);
263	      sum+=e;
264	      if(e<min) { min=e; TopInd=i; };
265	    };
266	  };
267	  ErrMin=(float)min;
268	  ErrAvg=((float)sum)/((float)popsize);
269	}
270	
271	ind selectind(int popsize)
272	{
273	  int p,q,n;
274	
275	  if(getrand()>=Nuniform)
276	  {
277	    p=getrand()%popsize;
278	    q=getrand()%popsize;
279	    return (Err[p]<=Err[q]) ? OldPop[p] : OldPop[q];
280	  } else {
281	    return OldPop[getrand()%popsize];
282	  };
283	}
284	
285	void selection(int popsize)
286	{
287	  int n,i,j;
288	  ind *p;
289	
290	  int ncopy,nmutate,ncrossover;
291	
292	  ncopy=(popsize*Pcopy)/100;
293	  nmutate=(popsize*Pmutate)/100;
294	  ncrossover=popsize-ncopy-nmutate;
295	  if(ncopy==0)
296	  {
297	    ncopy=1;
298	    if(nmutate) nmutate--; else ncrossover--;
299	  }
300	  if(ncrossover&1) { ncrossover--; nmutate++; };
301	
302	  p=Pop; Pop=OldPop; OldPop=p; i=0;
303	  copy(OldPop[TopInd],Pop[i++]);
304	  for(j=1;j<ncopy;j++)
305	    copy(selectind(popsize),Pop[i++]);
306	  for(j=0;j<ncrossover;j+=2)
307	   crossover(selectind(popsize),selectind(popsize),Pop[i++],Pop[i++]);
308	  while(i<popsize)
309	    mutate(selectind(popsize),Pop[i++]);
310	}
311



(c) Bernhard Ömer - oemer@tph.tuwien.ac.at - http://tph.tuwien.ac.at/~oemer/