1 /**********************************************************************
2   ga_chromo.c
3  **********************************************************************
4 
5   ga_chromo - Genetic algorithm chromosome handling routines.
6   Copyright ©2000-2004, Stewart Adcock <stewart@linux-domain.com>
7   All rights reserved.
8 
9   The latest version of this program should be available at:
10   http://gaul.sourceforge.net/
11 
12   This program is free software; you can redistribute it and/or modify
13   it under the terms of the GNU General Public License as published by
14   the Free Software Foundation; either version 2 of the License, or
15   (at your option) any later version.  Alternatively, if your project
16   is incompatible with the GPL, I will probably agree to requests
17   for permission to use the terms of any other license.
18 
19   This program is distributed in the hope that it will be useful, but
20   WITHOUT ANY WARRANTY WHATSOEVER.
21 
22   A full copy of the GNU General Public License should be in the file
23   "COPYING" provided with this distribution; if not, see:
24   http://www.gnu.org/
25 
26  **********************************************************************
27 
28   Synopsis:     Routines for handling GAUL's built-in chromosome types.
29 
30 		The functions required for each chromsome type are:
31 		ga_chromosome_XXX_allocate() - assign memory.
32 		ga_chromosome_XXX_deallocate() - free memory.
33 		ga_chromosome_XXX_replicate() - copy genetic information.
34 		ga_chromosome_XXX_to_bytes() - for serialization.
35 		   (Leave max_bytes==0, if no need to free (i.e. static))
36 		ga_chromosome_XXX_from_bytes() - for deserialization.
37 		ga_chromosome_XXX_to_string() - Human readable NULL-
38 		   terminated string.
39 
40 		The chromosome types are:
41 		integer - C int.
42 		boolean - boolean (generally, C _Bool by default).
43 		double - C double.
44 		char - C char.
45 		bitstring - bitstring.
46 		list - generic linked-list.
47 
48   To do:	Will need chromosome comparison functions.
49 
50  **********************************************************************/
51 
52 #include "gaul/ga_chromo.h"
53 
54 /**********************************************************************
55   ga_chromosome_integer_allocate()
56   synopsis:	Allocate the chromosomes for an entity.  Initial
57 		contents are garbage (there is no need to zero them).
58   parameters:
59   return:
60   last updated: 05 Oct 2004
61  **********************************************************************/
62 
ga_chromosome_integer_allocate(population * pop,entity * embryo)63 boolean ga_chromosome_integer_allocate( population *pop,
64                                         entity *embryo )
65   {
66   int		i;		/* Loop variable over all chromosomes */
67 
68   if (!pop) die("Null pointer to population structure passed.");
69   if (!embryo) die("Null pointer to entity structure passed.");
70 
71   if (embryo->chromosome!=NULL)
72     die("This entity already contains chromosomes.");
73 
74 #if USE_CHROMO_CHUNKS == 1
75   THREAD_LOCK(pop->chromo_chunk_lock);
76   if (!pop->chromo_chunk)
77     {
78     pop->chromoarray_chunk = mem_chunk_new(pop->num_chromosomes*sizeof(int *), 1024);
79     pop->chromo_chunk = mem_chunk_new(pop->num_chromosomes*pop->len_chromosomes*sizeof(int), 2048);
80     }
81 
82   embryo->chromosome = mem_chunk_alloc(pop->chromoarray_chunk);
83   embryo->chromosome[0] = mem_chunk_alloc(pop->chromo_chunk);
84   THREAD_UNLOCK(pop->chromo_chunk_lock);
85 #else
86   embryo->chromosome = s_malloc(pop->num_chromosomes*sizeof(int *));
87   embryo->chromosome[0] = s_malloc(pop->num_chromosomes*pop->len_chromosomes*sizeof(int));
88 #endif
89 
90   for (i=1; i<pop->num_chromosomes; i++)
91     {
92     embryo->chromosome[i] = &(((int *)embryo->chromosome[i-1])[pop->len_chromosomes]);
93     }
94 
95   return TRUE;
96   }
97 
98 
99 /**********************************************************************
100   ga_chromosome_integer_deallocate()
101   synopsis:	Deallocate the chromosomes for an entity.
102   parameters:
103   return:
104   last updated: 05 Oct 2004
105  **********************************************************************/
106 
ga_chromosome_integer_deallocate(population * pop,entity * corpse)107 void ga_chromosome_integer_deallocate( population *pop,
108                                        entity *corpse )
109   {
110 
111   if (!pop) die("Null pointer to population structure passed.");
112   if (!corpse) die("Null pointer to entity structure passed.");
113 
114   if (corpse->chromosome==NULL)
115     die("This entity already contains no chromosomes.");
116 
117 #if USE_CHROMO_CHUNKS == 1
118   THREAD_LOCK(pop->chromo_chunk_lock);
119   mem_chunk_free(pop->chromo_chunk, corpse->chromosome[0]);
120   mem_chunk_free(pop->chromoarray_chunk, corpse->chromosome);
121   corpse->chromosome=NULL;
122 
123   if (mem_chunk_isempty(pop->chromo_chunk))
124     {
125     mem_chunk_destroy(pop->chromo_chunk);
126     mem_chunk_destroy(pop->chromoarray_chunk);
127     pop->chromo_chunk = NULL;
128     }
129   THREAD_UNLOCK(pop->chromo_chunk_lock);
130 #else
131   s_free(corpse->chromosome[0]);
132   s_free(corpse->chromosome);
133   corpse->chromosome=NULL;
134 #endif
135 
136   return;
137   }
138 
139 
140 /**********************************************************************
141   ga_chromosome_integer_replicate()
142   synopsis:	Duplicate a chromosome exactly.
143   parameters:
144   return:
145   last updated: 13/06/01
146  **********************************************************************/
147 
ga_chromosome_integer_replicate(const population * pop,entity * parent,entity * child,const int chromosomeid)148 void ga_chromosome_integer_replicate( const population *pop,
149                                       entity *parent, entity *child,
150                                       const int chromosomeid )
151   {
152 
153   if (!pop) die("Null pointer to population structure passed.");
154   if (!parent || !child) die("Null pointer to entity structure passed.");
155   if (!parent->chromosome || !child->chromosome) die("Entity has no chromsomes.");
156 
157   memcpy( child->chromosome[chromosomeid],
158           parent->chromosome[chromosomeid],
159           pop->len_chromosomes * sizeof(int));
160 
161   return;
162   }
163 
164 
165 /**********************************************************************
166   ga_chromosome_integer_to_bytes()
167   synopsis:	Convert to contiguous form.  In this case, a trivial
168 		process.
169   parameters:
170   return:	Number of bytes processed.
171   last updated: 1 Feb 2002
172  **********************************************************************/
173 
ga_chromosome_integer_to_bytes(const population * pop,entity * joe,byte ** bytes,unsigned int * max_bytes)174 unsigned int ga_chromosome_integer_to_bytes(const population *pop, entity *joe,
175                                      byte **bytes, unsigned int *max_bytes)
176   {
177   int		num_bytes;	/* Actual size of genes. */
178 
179   if (!pop) die("Null pointer to population structure passed.");
180   if (!joe) die("Null pointer to entity structure passed.");
181 
182   if (*max_bytes!=0) die("Internal error.");
183 
184   if (!joe->chromosome)
185     {
186     *bytes = (byte *)"\0";
187     return 0;
188     }
189 
190   num_bytes = pop->len_chromosomes * pop->num_chromosomes *
191               sizeof(int);
192 
193   *bytes = (byte *)joe->chromosome[0];
194 
195   return num_bytes;
196   }
197 
198 
199 /**********************************************************************
200   ga_chromosome_integer_from_bytes()
201   synopsis:	Convert from contiguous form.  In this case, a trivial
202 		process.
203   parameters:
204   return:
205   last updated: 1 Feb 2002
206  **********************************************************************/
207 
ga_chromosome_integer_from_bytes(const population * pop,entity * joe,byte * bytes)208 void ga_chromosome_integer_from_bytes(const population *pop, entity *joe, byte *bytes)
209   {
210 
211   if (!pop) die("Null pointer to population structure passed.");
212   if (!joe) die("Null pointer to entity structure passed.");
213 
214   if (!joe->chromosome) die("Entity has no chromsomes.");
215 
216   memcpy(joe->chromosome[0], bytes,
217          pop->len_chromosomes * pop->num_chromosomes * sizeof(int));
218 
219   return;
220   }
221 
222 
223 /**********************************************************************
224   ga_chromosome_integer_to_string()
225   synopsis:	Convert to human readable form.
226   parameters:	const population *pop	Population (compatible with entity)
227   		const entity *joe	Entity to encode as text.
228 		char *text		Malloc()'ed text buffer, or NULL.
229 		size_t *textlen		Current size of text buffer.
230   return:
231   last updated: 19 Aug 2002
232  **********************************************************************/
233 
ga_chromosome_integer_to_string(const population * pop,const entity * joe,char * text,size_t * textlen)234 char *ga_chromosome_integer_to_string(
235                               const population *pop, const entity *joe,
236                               char *text, size_t *textlen)
237   {
238   int		i, j;		/* Loop over chromosome, alleles. */
239   int		k=0;		/* Pointer into 'text'. */
240   int		l;		/* Number of appended digits. */
241 
242   if (!pop) die("Null pointer to population structure passed.");
243   if (!joe) die("Null pointer to entity structure passed.");
244 
245 /* Ensure that a reasonable amount of memory is allocated. */
246   if (!text || *textlen < 8 * pop->len_chromosomes * pop->num_chromosomes)
247     {
248     *textlen = 8 * pop->len_chromosomes * pop->num_chromosomes;
249     text = s_realloc(text, sizeof(char) * *textlen);
250     }
251 
252 /* Handle empty chromosomes. */
253   if (!joe->chromosome)
254     {
255     text[1] = '\0';
256     return text;
257     }
258 
259   for(i=0; i<pop->num_chromosomes; i++)
260     {
261     for(j=0; j<pop->len_chromosomes; j++)
262       {
263       if (*textlen-k<8)
264         {
265         *textlen *= 2;   /* FIXME: This isn't intelligent. */
266         text = s_realloc(text, sizeof(char) * *textlen);
267         }
268 
269       l = snprintf(&(text[k]), *textlen-k, "%d ",
270                        ((int *)joe->chromosome[i])[j]);
271 
272       if (l == -1)
273         {	/* Truncation occured. */
274 	*textlen *= 2;	/* FIXME: This isn't intelligent. */
275         text = s_realloc(text, sizeof(char) * *textlen);
276         l = snprintf(&(text[k]), *textlen-k, "%d ",
277                        ((int *)joe->chromosome[i])[j]);
278 
279         if (l == -1) die("Internal error, string truncated again.");
280         }
281 
282       k += l;
283       }
284     }
285 
286 /* Replace last space character with NULL character. */
287   text[k-1]='\0';
288 
289   return text;
290   }
291 
292 
293 /**********************************************************************
294   ga_chromosome_boolean_allocate()
295   synopsis:	Allocate the chromosomes for an entity.  Initial
296 		contents are garbage (there is no need to zero them).
297   parameters:
298   return:
299   last updated: 13/06/01
300  **********************************************************************/
301 
ga_chromosome_boolean_allocate(population * pop,entity * embryo)302 boolean ga_chromosome_boolean_allocate(population *pop, entity *embryo)
303   {
304   int		i;		/* Loop variable over all chromosomes */
305 
306   if (!pop) die("Null pointer to population structure passed.");
307   if (!embryo) die("Null pointer to entity structure passed.");
308 
309   if (embryo->chromosome!=NULL)
310     die("This entity already contains chromosomes.");
311 
312   embryo->chromosome = s_malloc(pop->num_chromosomes*sizeof(boolean *));
313   embryo->chromosome[0] = s_malloc(pop->num_chromosomes*pop->len_chromosomes*sizeof(boolean));
314 
315   for (i=1; i<pop->num_chromosomes; i++)
316     {
317     embryo->chromosome[i] = &(((boolean *)embryo->chromosome[i-1])[pop->len_chromosomes]);
318     }
319 
320   return TRUE;
321   }
322 
323 
324 /**********************************************************************
325   ga_chromosome_boolean_deallocate()
326   synopsis:	Deallocate the chromosomes for an entity.
327   parameters:
328   return:
329   last updated: 13/06/01
330  **********************************************************************/
331 
ga_chromosome_boolean_deallocate(population * pop,entity * corpse)332 void ga_chromosome_boolean_deallocate(population *pop, entity *corpse)
333   {
334 
335   if (!pop) die("Null pointer to population structure passed.");
336   if (!corpse) die("Null pointer to entity structure passed.");
337 
338   if (corpse->chromosome==NULL)
339     die("This entity already contains no chromosomes.");
340 
341   s_free(corpse->chromosome[0]);
342   s_free(corpse->chromosome);
343   corpse->chromosome=NULL;
344 
345   return;
346   }
347 
348 
349 /**********************************************************************
350   ga_chromosome_boolean_replicate()
351   synopsis:	Duplicate a chromosome exactly.
352   parameters:
353   return:
354   last updated: 19 Mar 2002
355  **********************************************************************/
356 
ga_chromosome_boolean_replicate(const population * pop,entity * parent,entity * child,const int chromosomeid)357 void ga_chromosome_boolean_replicate( const population *pop,
358                                       entity *parent, entity *child,
359                                       const int chromosomeid )
360   {
361 
362   if (!pop) die("Null pointer to population structure passed.");
363   if (!parent || !child) die("Null pointer to entity structure passed.");
364   if (!parent->chromosome || !child->chromosome) die("Entity has no chromsomes.");
365 
366   memcpy(child->chromosome[chromosomeid], parent->chromosome[chromosomeid],
367               pop->len_chromosomes * sizeof(boolean));
368 
369   return;
370   }
371 
372 
373 /**********************************************************************
374   ga_chromosome_boolean_to_bytes()
375   synopsis:	Convert to contiguous form.  In this case, a trivial
376 		process.  (Note that we could compress the data at this
377 		point but CPU time is currenty more important to me
378 		than memory or bandwidth)
379   parameters:
380   return:
381   last updated: 1 Feb 2002
382  **********************************************************************/
383 
ga_chromosome_boolean_to_bytes(const population * pop,entity * joe,byte ** bytes,unsigned int * max_bytes)384 unsigned int ga_chromosome_boolean_to_bytes(const population *pop, entity *joe,
385                                     byte **bytes, unsigned int *max_bytes)
386   {
387   int		num_bytes;	/* Actual size of genes. */
388 
389   if (!pop) die("Null pointer to population structure passed.");
390   if (!joe) die("Null pointer to entity structure passed.");
391 
392   if (*max_bytes!=0) die("Internal error.");
393 
394   if (!joe->chromosome)
395     {
396     *bytes = (byte *)"\0";
397     return 0;
398     }
399 
400   num_bytes = pop->len_chromosomes * pop->num_chromosomes *
401               sizeof(boolean);
402 
403   *bytes = (byte *)joe->chromosome[0];
404 
405   return num_bytes;
406   }
407 
408 
409 /**********************************************************************
410   ga_chromosome_boolean_from_bytes()
411   synopsis:	Convert from contiguous form.  In this case, a trivial
412 		process.
413   parameters:
414   return:
415   last updated: 1 Feb 2002
416  **********************************************************************/
417 
ga_chromosome_boolean_from_bytes(const population * pop,entity * joe,byte * bytes)418 void ga_chromosome_boolean_from_bytes(const population *pop, entity *joe, byte *bytes)
419   {
420 
421   if (!pop) die("Null pointer to population structure passed.");
422   if (!joe) die("Null pointer to entity structure passed.");
423 
424   if (!joe->chromosome) die("Entity has no chromsomes.");
425 
426   memcpy(joe->chromosome[0], bytes,
427          pop->len_chromosomes * pop->num_chromosomes * sizeof(boolean));
428 
429   return;
430   }
431 
432 
433 /**********************************************************************
434   ga_chromosome_boolean_to_string()
435   synopsis:	Convert to human readable form.
436   parameters:
437   return:
438   last updated: 19 Aug 2002
439  **********************************************************************/
440 
ga_chromosome_boolean_to_string(const population * pop,const entity * joe,char * text,size_t * textlen)441 char *ga_chromosome_boolean_to_string(
442                               const population *pop, const entity *joe,
443                               char *text, size_t *textlen)
444   {
445   int		i, j;		/* Loop over chromosome, alleles. */
446   int		k=0;		/* Pointer into 'text'. */
447 
448   if (!pop) die("Null pointer to population structure passed.");
449   if (!joe) die("Null pointer to entity structure passed.");
450 
451   if (!text || *textlen < pop->len_chromosomes * pop->num_chromosomes + 1)
452     {
453     *textlen = pop->len_chromosomes * pop->num_chromosomes + 1;
454     text = s_realloc(text, sizeof(char) * *textlen);
455     }
456 
457   if (!joe->chromosome)
458     {
459     text[0] = '\0';
460     }
461   else
462     {
463     for(i=0; i<pop->num_chromosomes; i++)
464       {
465       for(j=0; j<pop->len_chromosomes; j++)
466         {
467         text[k++] = ((boolean *)joe->chromosome[i])[j]?'1':'0';
468         }
469       }
470     text[k] = '\0';
471     }
472 
473   return text;
474   }
475 
476 
477 /**********************************************************************
478   ga_chromosome_double_allocate()
479   synopsis:	Allocate the chromosomes for an entity.  Initial
480 		contents are garbage (there is no need to zero them).
481   parameters:
482   return:
483   last updated: 16/06/01
484  **********************************************************************/
485 
ga_chromosome_double_allocate(population * pop,entity * embryo)486 boolean ga_chromosome_double_allocate(population *pop, entity *embryo)
487   {
488   int		i;		/* Loop variable over all chromosomes */
489 
490   if (!pop) die("Null pointer to population structure passed.");
491   if (!embryo) die("Null pointer to entity structure passed.");
492 
493   if (embryo->chromosome!=NULL)
494     die("This entity already contains chromosomes.");
495 
496   embryo->chromosome = s_malloc(pop->num_chromosomes*sizeof(double *));
497   embryo->chromosome[0] = s_malloc(pop->num_chromosomes*pop->len_chromosomes*sizeof(double));
498 
499   for (i=1; i<pop->num_chromosomes; i++)
500     {
501     embryo->chromosome[i] = &(((double *)embryo->chromosome[i-1])[pop->len_chromosomes]);
502     }
503 
504   return TRUE;
505   }
506 
507 
508 /**********************************************************************
509   ga_chromosome_double_deallocate()
510   synopsis:	Deallocate the chromosomes for an entity.
511   parameters:
512   return:
513   last updated: 16/06/01
514  **********************************************************************/
515 
ga_chromosome_double_deallocate(population * pop,entity * corpse)516 void ga_chromosome_double_deallocate(population *pop, entity *corpse)
517   {
518 
519   if (!pop) die("Null pointer to population structure passed.");
520   if (!corpse) die("Null pointer to entity structure passed.");
521 
522   if (corpse->chromosome==NULL)
523     die("This entity already contains no chromosomes.");
524 
525   s_free(corpse->chromosome[0]);
526   s_free(corpse->chromosome);
527   corpse->chromosome=NULL;
528 
529   return;
530   }
531 
532 
533 /**********************************************************************
534   ga_chromosome_double_replicate()
535   synopsis:	Duplicate a chromosome exactly.
536   parameters:
537   return:
538   last updated: 16/06/01
539  **********************************************************************/
540 
ga_chromosome_double_replicate(const population * pop,entity * parent,entity * child,const int chromosomeid)541 void ga_chromosome_double_replicate( const population *pop,
542                                       entity *parent, entity *child,
543                                       const int chromosomeid )
544   {
545 
546   if (!pop) die("Null pointer to population structure passed.");
547   if (!parent || !child) die("Null pointer to entity structure passed.");
548   if (!parent->chromosome || !child->chromosome) die("Entity has no chromsomes.");
549 
550   memcpy(child->chromosome[chromosomeid], parent->chromosome[chromosomeid],
551               pop->len_chromosomes * sizeof(double));
552 
553   return;
554   }
555 
556 
557 /**********************************************************************
558   ga_chromosome_double_to_bytes()
559   synopsis:	Convert to contiguous form.  In this case, a trivial
560 		process.  (Note that we could compress the data at this
561 		point but CPU time is currenty more important to me
562 		than memory or bandwidth)
563   parameters:
564   return:
565   last updated: 1 Feb 2002
566  **********************************************************************/
567 
ga_chromosome_double_to_bytes(const population * pop,entity * joe,byte ** bytes,unsigned int * max_bytes)568 unsigned int ga_chromosome_double_to_bytes(const population *pop, entity *joe,
569                                     byte **bytes, unsigned int *max_bytes)
570   {
571   int		num_bytes;	/* Actual size of genes. */
572 
573   if (!pop) die("Null pointer to population structure passed.");
574   if (!joe) die("Null pointer to entity structure passed.");
575 
576   if (*max_bytes!=0) die("Internal error.");
577 
578   if (!joe->chromosome)
579     {
580     *bytes = (byte *)"\0";
581     return 0;
582     }
583 
584   num_bytes = pop->len_chromosomes * pop->num_chromosomes *
585               sizeof(double);
586 
587   *bytes = (byte *)joe->chromosome[0];
588 
589   return num_bytes;
590   }
591 
592 
593 /**********************************************************************
594   ga_chromosome_double_from_bytes()
595   synopsis:	Convert from contiguous form.  In this case, a trivial
596 		process.
597   parameters:
598   return:
599   last updated: 1 Feb 2002
600  **********************************************************************/
601 
ga_chromosome_double_from_bytes(const population * pop,entity * joe,byte * bytes)602 void ga_chromosome_double_from_bytes(const population *pop, entity *joe, byte *bytes)
603   {
604 
605   if (!pop) die("Null pointer to population structure passed.");
606   if (!joe) die("Null pointer to entity structure passed.");
607 
608   if (!joe->chromosome) die("Entity has no chromsomes.");
609 
610   memcpy(joe->chromosome[0], bytes,
611          pop->len_chromosomes * pop->num_chromosomes * sizeof(double));
612 
613   return;
614   }
615 
616 
617 /**********************************************************************
618   ga_chromosome_double_to_string()
619   synopsis:	Convert to human readable form.
620   parameters:
621   return:
622   last updated: 19 Aug 2002
623  **********************************************************************/
624 
ga_chromosome_double_to_string(const population * pop,const entity * joe,char * text,size_t * textlen)625 char *ga_chromosome_double_to_string(
626                               const population *pop, const entity *joe,
627                               char *text, size_t *textlen)
628   {
629   int		i, j;		/* Loop over chromosome, alleles. */
630   int		k=0;		/* Pointer into 'text'. */
631   int		l;		/* Number of 'snprintf'ed characters. */
632 
633   if (!pop) die("Null pointer to population structure passed.");
634   if (!joe) die("Null pointer to entity structure passed.");
635 
636   if (!text || *textlen < 10 * pop->len_chromosomes * pop->num_chromosomes)
637     {
638     *textlen = 10 * pop->len_chromosomes * pop->num_chromosomes;
639     text = s_realloc(text, sizeof(char) * *textlen);
640     }
641 
642   if (!joe->chromosome)
643     {
644     text[1] = '\0';
645     return text;
646     }
647 
648   for(i=0; i<pop->num_chromosomes; i++)
649     {
650     for(j=0; j<pop->len_chromosomes; j++)
651       {
652       if (*textlen-k<8)
653         {
654 	*textlen *= 2;	/* FIXME: This isn't intelligent. */
655         text = s_realloc(text, sizeof(char) * *textlen);
656         }
657 
658       l = snprintf(&(text[k]), *textlen-k, "%f ",
659                        ((double *)joe->chromosome[i])[j]);
660 
661       if (l == -1)
662         {	/* Truncation occured. */
663 	*textlen *= 2;	/* FIXME: This isn't intelligent. */
664         text = s_realloc(text, sizeof(char) * *textlen);
665         l = snprintf(&(text[k]), *textlen-k, "%f ",
666                        ((double *)joe->chromosome[i])[j]);
667 
668         if (l == -1) die("Internal error, string truncated again.");
669         }
670 
671       k += l;
672       }
673     }
674 
675   text[k-1] = '\0';
676 
677   return text;
678   }
679 
680 
681 /**********************************************************************
682   ga_chromosome_char_allocate()
683   synopsis:	Allocate the chromosomes for an entity.  Initial
684 		contents are garbage (there is no need to zero them).
685   parameters:
686   return:
687   last updated: 16/06/01
688  **********************************************************************/
689 
ga_chromosome_char_allocate(population * pop,entity * embryo)690 boolean ga_chromosome_char_allocate(population *pop, entity *embryo)
691   {
692   int		i;		/* Loop variable over all chromosomes */
693 
694   if (!pop) die("Null pointer to population structure passed.");
695   if (!embryo) die("Null pointer to entity structure passed.");
696 
697   if (embryo->chromosome!=NULL)
698     die("This entity already contains chromosomes.");
699 
700   embryo->chromosome = s_malloc(pop->num_chromosomes*sizeof(char *));
701   embryo->chromosome[0] = s_malloc(pop->num_chromosomes*pop->len_chromosomes*sizeof(char));
702 
703   for (i=1; i<pop->num_chromosomes; i++)
704     {
705     embryo->chromosome[i] = &(((char *)embryo->chromosome[i-1])[pop->len_chromosomes]);
706     }
707 
708   return TRUE;
709   }
710 
711 
712 /**********************************************************************
713   ga_chromosome_char_deallocate()
714   synopsis:	Deallocate the chromosomes for an entity.
715   parameters:
716   return:
717   last updated: 16/06/01
718  **********************************************************************/
719 
ga_chromosome_char_deallocate(population * pop,entity * corpse)720 void ga_chromosome_char_deallocate(population *pop, entity *corpse)
721   {
722 
723   if (!pop) die("Null pointer to population structure passed.");
724   if (!corpse) die("Null pointer to entity structure passed.");
725 
726   if (corpse->chromosome==NULL)
727     die("This entity already contains no chromosomes.");
728 
729 /*  ga_entity_dump(pop, corpse);*/
730 
731   s_free(corpse->chromosome[0]);
732   s_free(corpse->chromosome);
733   corpse->chromosome=NULL;
734 
735   return;
736   }
737 
738 
739 /**********************************************************************
740   ga_chromosome_char_replicate()
741   synopsis:	Duplicate a chromosome exactly.
742   parameters:
743   return:
744   last updated: 19 Mar 2002
745  **********************************************************************/
746 
ga_chromosome_char_replicate(const population * pop,entity * parent,entity * child,const int chromosomeid)747 void ga_chromosome_char_replicate( const population *pop,
748                                    entity *parent, entity *child,
749                                    const int chromosomeid )
750   {
751 
752   if (!pop) die("Null pointer to population structure passed.");
753   if (!parent || !child) die("Null pointer to entity structure passed.");
754   if (!parent->chromosome || !child->chromosome) die("Entity has no chromsomes.");
755 
756   memcpy(child->chromosome[chromosomeid], parent->chromosome[chromosomeid],
757               pop->len_chromosomes * sizeof(char));
758 
759   return;
760   }
761 
762 
763 /**********************************************************************
764   ga_chromosome_char_to_bytes()
765   synopsis:	Convert to contiguous form.  In this case, a highly
766 		trivial process.
767   parameters:
768   return:
769   last updated: 1 Feb 2002
770  **********************************************************************/
771 
ga_chromosome_char_to_bytes(const population * pop,entity * joe,byte ** bytes,unsigned int * max_bytes)772 unsigned int ga_chromosome_char_to_bytes(const population *pop, entity *joe,
773                                     byte **bytes, unsigned int *max_bytes)
774   {
775   int		num_bytes;	/* Actual size of genes. */
776 
777   if (!pop) die("Null pointer to population structure passed.");
778   if (!joe) die("Null pointer to entity structure passed.");
779 
780   if (*max_bytes!=0) die("Internal error.");
781 
782   if (!joe->chromosome)
783     {
784     *bytes = (byte *)"\0";
785     return 0;
786     }
787 
788   num_bytes = pop->len_chromosomes * pop->num_chromosomes * sizeof(char);
789 
790   *bytes = (byte *)joe->chromosome[0];
791 
792   return num_bytes;
793   }
794 
795 
796 /**********************************************************************
797   ga_chromosome_char_from_bytes()
798   synopsis:	Convert from contiguous form.  In this case, a trivial
799 		process.
800   parameters:
801   return:
802   last updated: 1 Feb 2002
803  **********************************************************************/
804 
ga_chromosome_char_from_bytes(const population * pop,entity * joe,byte * bytes)805 void ga_chromosome_char_from_bytes(const population *pop, entity *joe, byte *bytes)
806   {
807 
808   if (!pop) die("Null pointer to population structure passed.");
809   if (!joe) die("Null pointer to entity structure passed.");
810 
811   if (!joe->chromosome) die("Entity has no chromsomes.");
812 
813   memcpy(joe->chromosome[0], bytes,
814          pop->len_chromosomes * pop->num_chromosomes * sizeof(char));
815 
816   return;
817   }
818 
819 
820 /**********************************************************************
821   ga_chromosome_char_to_string()
822   synopsis:	Convert genetic data into human readable form.
823   parameters:
824   return:
825   last updated: 19 Aug 2002
826  **********************************************************************/
827 
ga_chromosome_char_to_string(const population * pop,const entity * joe,char * text,size_t * textlen)828 char *ga_chromosome_char_to_string(
829                               const population *pop, const entity *joe,
830                               char *text, size_t *textlen)
831   {
832   int		i;		/* Loop over chromosome, alleles. */
833   int		k=0;		/* Pointer into 'text'. */
834 
835   if (!pop) die("Null pointer to population structure passed.");
836   if (!joe) die("Null pointer to entity structure passed.");
837 
838   if (*textlen < pop->len_chromosomes * pop->num_chromosomes + 1)
839     {
840     *textlen = pop->len_chromosomes * pop->num_chromosomes + 1;
841     text = s_realloc(text, sizeof(char) * *textlen);
842     }
843 
844   if (!joe->chromosome)
845     {
846     text[0] = '\0';
847     }
848   else
849     {
850     for(i=0; i<pop->num_chromosomes; i++)
851       {
852       memcpy(&(text[k]), joe->chromosome[0],
853          pop->len_chromosomes * sizeof(char));
854       k += pop->len_chromosomes;
855       }
856     text[k] = '\0';
857     }
858 
859   return text;
860   }
861 
862 
863 /**********************************************************************
864   ga_chromosome_bitstring_allocate()
865   synopsis:	Allocate the chromosomes for an entity.  Initial
866 		contents are garbage (there is no need to zero them).
867   parameters:
868   return:
869   last updated: 30/06/01
870  **********************************************************************/
871 
ga_chromosome_bitstring_allocate(population * pop,entity * embryo)872 boolean ga_chromosome_bitstring_allocate(population *pop, entity *embryo)
873   {
874   int		i;		/* Loop variable over all chromosomes */
875 
876   if (!pop) die("Null pointer to population structure passed.");
877   if (!embryo) die("Null pointer to entity structure passed.");
878 
879   if (embryo->chromosome!=NULL)
880     die("This entity already contains chromosomes.");
881 
882   embryo->chromosome = s_malloc(pop->num_chromosomes*sizeof(byte *));
883 
884   for (i=0; i<pop->num_chromosomes; i++)
885     embryo->chromosome[i] = ga_bit_new(pop->len_chromosomes);
886 
887   return TRUE;
888   }
889 
890 
891 /**********************************************************************
892   ga_chromosome_bitstring_deallocate()
893   synopsis:	Deallocate the chromosomes for an entity.
894   parameters:
895   return:
896   last updated: 30/06/01
897  **********************************************************************/
898 
ga_chromosome_bitstring_deallocate(population * pop,entity * corpse)899 void ga_chromosome_bitstring_deallocate(population *pop, entity *corpse)
900   {
901   int		i;		/* Loop variable over all chromosomes */
902 
903   if (!pop) die("Null pointer to population structure passed.");
904   if (!corpse) die("Null pointer to entity structure passed.");
905 
906   if (corpse->chromosome==NULL)
907     die("This entity already contains no chromosomes.");
908 
909   for (i=0; i<pop->num_chromosomes; i++)
910     ga_bit_free(corpse->chromosome[i]);
911 
912   s_free(corpse->chromosome);
913   corpse->chromosome=NULL;
914 
915   return;
916   }
917 
918 
919 /**********************************************************************
920   ga_chromosome_bitstring_replicate()
921   synopsis:	Duplicate a chromosome exactly.
922   parameters:
923   return:
924   last updated: 30/06/01
925  **********************************************************************/
926 
ga_chromosome_bitstring_replicate(const population * pop,entity * parent,entity * child,const int chromosomeid)927 void ga_chromosome_bitstring_replicate( const population *pop,
928                                       entity *parent, entity *child,
929                                       const int chromosomeid )
930   {
931 
932   if (!pop) die("Null pointer to population structure passed.");
933   if (!parent || !child) die("Null pointer to entity structure passed.");
934   if (!parent->chromosome || !child->chromosome) die("Entity has no chromsomes.");
935 
936   ga_bit_clone( child->chromosome[chromosomeid],
937                 parent->chromosome[chromosomeid],
938                 pop->len_chromosomes );
939 
940   return;
941   }
942 
943 
944 /**********************************************************************
945   ga_chromosome_bitstring_to_bytes()
946   synopsis:	Convert to contiguous form.
947   parameters:
948   return:
949   last updated: 30/06/01
950  **********************************************************************/
951 
ga_chromosome_bitstring_to_bytes(const population * pop,entity * joe,byte ** bytes,unsigned int * max_bytes)952 unsigned int ga_chromosome_bitstring_to_bytes(const population *pop,
953                                     entity *joe,
954                                      byte **bytes, unsigned int *max_bytes)
955   {
956   int		num_bytes;	/* Actual size of genes. */
957   int		i;		/* Loop variable over all chromosomes */
958 
959   if (!pop) die("Null pointer to population structure passed.");
960   if (!joe) die("Null pointer to entity structure passed.");
961 
962   num_bytes = ga_bit_sizeof(pop->len_chromosomes) * pop->num_chromosomes;
963 
964   if (num_bytes>*max_bytes)
965     {
966     *max_bytes = num_bytes;
967     *bytes = s_realloc(*bytes, *max_bytes*sizeof(byte));
968     /* sizeof(byte) should always be 1 */
969     }
970 
971   if (!joe->chromosome)
972     {
973     *bytes = (byte *)0;
974     return 0;
975     }
976 
977   for(i=0; i<pop->num_chromosomes; i++)
978     {
979     ga_bit_copy( *bytes, joe->chromosome[i],
980                  i*pop->len_chromosomes, 0,
981                  pop->len_chromosomes );
982     }
983 
984   return num_bytes;
985   }
986 
987 
988 /**********************************************************************
989   ga_chromosome_bitstring_from_bytes()
990   synopsis:	Convert from contiguous form.  In this case, a trivial
991 		process.
992   parameters:
993   return:
994   last updated: 13/06/01
995  **********************************************************************/
996 
ga_chromosome_bitstring_from_bytes(const population * pop,entity * joe,byte * bytes)997 void ga_chromosome_bitstring_from_bytes( const population *pop,
998                                          entity *joe,
999                                          byte *bytes )
1000   {
1001   int		i;		/* Loop variable over all chromosomes */
1002 
1003   if (!pop) die("Null pointer to population structure passed.");
1004   if (!joe) die("Null pointer to entity structure passed.");
1005 
1006   if (!joe->chromosome) die("Entity has no chromsomes.");
1007 
1008   for(i=0; i<pop->num_chromosomes; i++)
1009     {
1010     ga_bit_copy( joe->chromosome[i], bytes,
1011                  0, i*pop->len_chromosomes,
1012                  pop->len_chromosomes );
1013     }
1014 
1015   return;
1016   }
1017 
1018 
1019 /**********************************************************************
1020   ga_chromosome_bitstring_to_string()
1021   synopsis:	Convert to human readable form.
1022   parameters:
1023   return:
1024   last updated: 19 Aug 2002
1025  **********************************************************************/
1026 
ga_chromosome_bitstring_to_string(const population * pop,const entity * joe,char * text,size_t * textlen)1027 char *ga_chromosome_bitstring_to_string(
1028                               const population *pop, const entity *joe,
1029                               char *text, size_t *textlen)
1030   {
1031   int		i, j;		/* Loop over chromosome, alleles. */
1032   int		k=0;		/* Pointer into 'text'. */
1033 
1034   if (!pop) die("Null pointer to population structure passed.");
1035   if (!joe) die("Null pointer to entity structure passed.");
1036 
1037   if (!text || *textlen < pop->len_chromosomes * pop->num_chromosomes + 1)
1038     {
1039     *textlen = pop->len_chromosomes * pop->num_chromosomes + 1;
1040     text = s_realloc(text, sizeof(char) * *textlen);
1041     }
1042 
1043   if (!joe->chromosome)
1044     {
1045     text[0] = '\0';
1046     }
1047   else
1048     {
1049     for(i=0; i<pop->num_chromosomes; i++)
1050       {
1051       for(j=0; j<pop->len_chromosomes; j++)
1052         {
1053         text[k++] = ga_bit_get(joe->chromosome[i],j)?'1':'0';
1054         }
1055       }
1056     text[k] = '\0';
1057     }
1058 
1059   return text;
1060   }
1061 
1062 
1063 /**********************************************************************
1064   ga_chromosome_list_allocate()
1065   synopsis:	Allocate the chromosomes for an entity.  Initial
1066 		contents are set to null.
1067   parameters:
1068   return:
1069   last updated: 05 Oct 2004
1070  **********************************************************************/
1071 
ga_chromosome_list_allocate(population * pop,entity * embryo)1072 boolean ga_chromosome_list_allocate(population *pop, entity *embryo)
1073   {
1074   int		i;		/* Loop variable over all chromosomes */
1075 
1076   if (!pop) die("Null pointer to population structure passed.");
1077   if (!embryo) die("Null pointer to entity structure passed.");
1078 
1079   if (embryo->chromosome!=NULL)
1080     die("This entity already contains chromosomes.");
1081 
1082   embryo->chromosome = s_malloc(pop->num_chromosomes*sizeof(DLList *));
1083 
1084   for (i=0; i<pop->num_chromosomes; i++)
1085     embryo->chromosome[i] = NULL;
1086 
1087   return TRUE;
1088   }
1089 
1090 
1091 /**********************************************************************
1092   ga_chromosome_list_deallocate()
1093   synopsis:	Deallocate the chromosomes for an entity.
1094   parameters:
1095   return:
1096   last updated: 05 Oct 2004
1097  **********************************************************************/
1098 
ga_chromosome_list_deallocate(population * pop,entity * corpse)1099 void ga_chromosome_list_deallocate(population *pop, entity *corpse)
1100   {
1101   int		i;		/* Loop variable over all chromosomes */
1102 
1103   if (!pop) die("Null pointer to population structure passed.");
1104   if (!corpse) die("Null pointer to entity structure passed.");
1105 
1106   if (corpse->chromosome==NULL)
1107     die("This entity already contains no chromosomes.");
1108 
1109   for (i=0; i<pop->num_chromosomes; i++)
1110     dlink_free_all(corpse->chromosome[i]);
1111 
1112   s_free(corpse->chromosome);
1113   corpse->chromosome=NULL;
1114 
1115   return;
1116   }
1117 
1118 
1119 /**********************************************************************
1120   ga_chromosome_list_replicate()
1121   synopsis:	Duplicate a chromosome exactly.
1122 		Currently unimplemented at present.
1123   parameters:
1124   return:
1125   last updated: 05 Oct 2004
1126  **********************************************************************/
1127 
ga_chromosome_list_replicate(const population * pop,entity * parent,entity * child,const int chromosomeid)1128 void ga_chromosome_list_replicate( const population *pop,
1129                                       entity *parent, entity *child,
1130                                       const int chromosomeid )
1131   {
1132 
1133   if (!pop) die("Null pointer to population structure passed.");
1134   if (!parent || !child) die("Null pointer to entity structure passed.");
1135   if (!parent->chromosome || !child->chromosome) die("Entity has no chromsomes.");
1136 
1137   child->chromosome[chromosomeid] = dlink_clone(
1138                 parent->chromosome[chromosomeid] );
1139 
1140   return;
1141   }
1142 
1143 
1144 /**********************************************************************
1145   ga_chromosome_list_to_bytes()
1146   synopsis:	Convert to contiguous form.
1147 		Currently unimplemented at present.
1148 		FIXME: Need a user-defined callback to implement this
1149 		according to contents of the list.
1150   parameters:
1151   return:
1152   last updated: 05 Oct 2004
1153  **********************************************************************/
1154 
ga_chromosome_list_to_bytes(const population * pop,entity * joe,byte ** bytes,unsigned int * max_bytes)1155 unsigned int ga_chromosome_list_to_bytes(const population *pop,
1156                                     entity *joe,
1157                                      byte **bytes, unsigned int *max_bytes)
1158   {
1159   int		num_bytes=0;	/* Actual size of genes. */
1160 
1161   if (!pop) die("Null pointer to population structure passed.");
1162   if (!joe) die("Null pointer to entity structure passed.");
1163 
1164   die("ga_chromosome_list_to_bytes() is not implemented.");
1165 
1166   /* Avoid compiler warnings. */
1167   **bytes = 0;
1168   *max_bytes = 0;
1169 
1170   return num_bytes;
1171   }
1172 
1173 
1174 /**********************************************************************
1175   ga_chromosome_list_from_bytes()
1176   synopsis:	Convert from contiguous form.  In this case, a trivial
1177 		process.
1178 		Currently unimplemented at present.
1179 		FIXME: Need a user-defined callback to implement this
1180 		according to contents of the list.
1181   parameters:
1182   return:
1183   last updated: 05 Oct 2004
1184  **********************************************************************/
1185 
ga_chromosome_list_from_bytes(const population * pop,entity * joe,byte * bytes)1186 void ga_chromosome_list_from_bytes( const population *pop,
1187                                          entity *joe,
1188                                          byte *bytes )
1189   {
1190 
1191   if (!pop) die("Null pointer to population structure passed.");
1192   if (!joe) die("Null pointer to entity structure passed.");
1193 
1194   if (!joe->chromosome) die("Entity has no chromsomes.");
1195 
1196   die("ga_chromosome_list_from_bytes() is not implemented.");
1197 
1198   /* Avoid compiler warning. */
1199   *bytes = 0;
1200 
1201   return;
1202   }
1203 
1204 
1205 /**********************************************************************
1206   ga_chromosome_list_to_string()
1207   synopsis:	Convert to human readable form.
1208 		Currently unimplemented at present.
1209 		FIXME: Need a user-defined callback to implement this
1210 		according to contents of the list.
1211   parameters:
1212   return:
1213   last updated: 05 Oct 2004
1214  **********************************************************************/
1215 
ga_chromosome_list_to_string(const population * pop,const entity * joe,char * text,size_t * textlen)1216 char *ga_chromosome_list_to_string(
1217                               const population *pop, const entity *joe,
1218                               char *text, size_t *textlen)
1219   {
1220 
1221   if (!pop) die("Null pointer to population structure passed.");
1222   if (!joe) die("Null pointer to entity structure passed.");
1223 
1224   if (!text || *textlen < 14)
1225     {
1226     *textlen = 14;
1227     text = s_realloc(text, sizeof(char) * *textlen);
1228     }
1229 
1230   strncpy(text, "<unavailable>", 14);
1231 
1232   return text;
1233   }
1234 
1235 
1236 
1237