2 * A simple ant-ology of genetic algorithms.
4 * mj@ucw.cz, Discord YOLD 3166
20 #define NSLOTS (NMARKS*NTYPES*NWAYS)
21 #define SLOT(m,t,w) (((m)*NTYPES+(t))*NWAYS+(w))
24 unsigned char op, mark, state;
34 struct slot slots[NSLOTS];
38 struct state states[NSTATES];
66 "##################################"
67 "#.$$$............................#"
68 "#...$............................#"
69 "#...$.....................$$$....#"
70 "#...$....................$....$..#"
71 "#...$....................$....$..#"
72 "#...$$$$.$$$$$........$$.........#"
73 "#............$................$..#"
74 "#............$.......$...........#"
75 "#............$.......$...........#"
76 "#............$.......$........$..#"
77 "#....................$...........#"
78 "#............$...................#"
79 "#............$................$..#"
80 "#............$.......$...........#"
81 "#............$.......$.....$$$...#"
82 "#.................$.....$........#"
83 "#................................#"
84 "#............$...................#"
85 "#............$...$.......$.......#"
86 "#............$...$..........$....#"
87 "#............$...$...............#"
88 "#............$...$...............#"
89 "#............$.............$.....#"
90 "#............$..........$........#"
91 "#...$$..$$$$$....$...............#"
92 "#.$..............$...............#"
93 "#.$..............$...............#"
94 "#.$......$$$$$$$.................#"
95 "#.$.....$........................#"
96 "#.......$........................#"
97 "#..$$$$..........................#"
98 "#................................#"
99 "##################################"
104 #define MI(a,b) ((b)*XSIZE+(a))
105 char mazec[XSIZE*YSIZE];
106 char *types = "$#.012345";
110 struct automaton autpool[POPSIZE];
111 struct automaton *pop[POPSIZE];
118 puts("Initializing maze");
119 for(i=0; i<XSIZE*YSIZE; i++)
121 char *z = strchr(types, maze[i]);
122 if (!z) { fprintf(stderr, "Maze bug\n"); exit(1); }
123 mazec[i] = z - types;
128 aut_gen_random(struct automaton *aut)
132 for(i=0; i<NSTATES; i++)
133 for(j=0; j<NSLOTS; j++)
135 struct slot *s = &aut->states[i].slots[j];
136 s->op = random() % OP_MAX;
137 s->state = random() % NSTATES;
138 s->mark = random() % NMARKS;
147 for(i=0; i<YSIZE; i++)
149 for(j=0; j<XSIZE; j++)
150 putchar(types[(int)z[x++]]);
156 fitness(struct automaton *aut, int flag)
158 char tmp[XSIZE*YSIZE];
163 static int dx[4] = { 0, -1, 0, 1 };
164 static int dy[4] = { 1, 0, -1, 0 };
168 memcpy(tmp, mazec, XSIZE*YSIZE);
171 int way = random() % NWAYS;
172 int here = tmp[MI(x,y)];
173 int mark = (here < 3) ? 0 : here-3;
174 int ahead = tmp[MI(x+dx[d],y+dy[d])];
175 int right = tmp[MI(x+dx[(d+1)%4],y+dy[(d+1)%4])];
176 int left = tmp[MI(x+dx[(d+3)%4],y+dy[(d+3)%4])];
178 int view = (ahead >= 2) ? 2 : ahead;
180 int view = ((ahead==1)?4:0) | ((left==1)?2:0) | ((right==1)?1:0);
182 struct slot *s = &aut->states[state].slots[SLOT(mark, view, way)];
183 tmp[MI(x,y)] = s->mark + 3;
189 case OP_LEFT: d = (d+3) % 4; break;
190 case OP_RIGHT: d = (d+1) % 4; break;
191 case OP_UTB: d = (d+2) % 4; break;
193 ahead = tmp[MI(x+dx[d],y+dy[d])];
196 case 0: energy+=10; bonus+=100; /* food */
197 default: x+=dx[d]; y+=dy[d]; break; /* empty */
198 case 1: energy-=5; break; /* wall */
212 for(i=0; i<POPSIZE; i++)
214 aut_gen_random(&autpool[i]);
215 pop[i] = &autpool[i];
220 fcmp(struct automaton **a, struct automaton **b)
222 int fa = (*a)->fitness;
223 int fb = (*b)->fitness;
225 return (fa < fb) ? -1 : (fa > fb) ? 1 : 0;
229 mutate(struct automaton *a)
236 state = random() % NSTATES;
237 slot = random() % NSLOTS;
238 s = &a->states[state].slots[slot];
239 s->op = random() % OP_MAX;
240 s->state = random() % NSTATES;
241 s->mark = random() % NMARKS;
246 crossover(struct automaton *a, struct automaton *b)
248 int marks[NMARKS], types[NTYPES], ways[NWAYS], slots[NSLOTS];
253 for(i=0; i<NMARKS; i++)
254 marks[i] = random() % 2;
255 for(i=0; i<NTYPES; i++)
256 types[i] = random() % 2;
257 for(i=0; i<NWAYS; i++)
258 ways[i] = random() % 2;
259 for(i=0; i<NMARKS; i++)
260 for(j=0; j<NTYPES; j++)
261 for(k=0; k<NWAYS; k++)
262 slots[SLOT(i,j,k)] = marks[i] && types[j] && ways[k];
263 for(i=0; i<NSTATES; i++)
265 for(j=0; j<NSLOTS; j++)
269 z = a->states[i].slots[j];
270 a->states[i].slots[j] = b->states[i].slots[j];
271 b->states[i].slots[j] = z;
276 rgenom(struct automaton **x, int n, int t)
278 int z = random() % t;
282 while (k <= z && n--)
283 k += x[i++]->fitness;
292 for(i=0; i<POPSIZE; i++)
294 struct automaton *a = pop[i];
295 a->fitness = (fitness(a,0) + fitness(a,0) + fitness(a,0)) / 3;
297 qsort(pop, POPSIZE, sizeof(struct automaton *), (int(*)(const void *,const void *)) fcmp);
298 for(i=0; i<POPSIZE; i++)
300 struct automaton *a = pop[i];
301 // printf("%d: %d\n", i, a->fitness);
304 fitness(pop[POPSIZE-1], 1);
305 printf("best=%d worst=%d\n", pop[POPSIZE-1]->fitness, pop[0]->fitness);
309 for(i=death; i<POPSIZE; i++)
310 total += pop[i]->fitness;
311 for(i=0; i<death; i++)
313 struct automaton *a = pop[i];
314 struct automaton *x = rgenom(pop+death, POPSIZE-death, total);
315 memcpy(a, x, sizeof(struct automaton));
318 for(i=0; i<POPSIZE; i++)
320 struct automaton *a = pop[i];
321 int what = random() % 1024;
322 // printf("%d %d\n", i, what);
326 crossover(a, rgenom(pop+death, POPSIZE-death, total));
340 printf("gen=%d\n", gen++);
343 // srandom(time(NULL));