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