1 /**********************************************************************
2 ga_crossover.c
3 **********************************************************************
4
5 ga_crossover - Genetic algorithm crossover operators.
6 Copyright ©2000-2003, 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 performing GA crossover operations.
29
30 These functions should duplicate user data where
31 appropriate.
32
33 To do: Merge static crossover functions by passing datatype size.
34
35 **********************************************************************/
36
37 #include "gaul/ga_core.h"
38
39 /**********************************************************************
40 ga_singlepoint_crossover_integer_chromosome()
41 synopsis: `Mates' two chromosomes by single-point crossover.
42 parameters:
43 return:
44 last updated: 18/10/00
45 **********************************************************************/
46
ga_singlepoint_crossover_integer_chromosome(population * pop,int * father,int * mother,int * son,int * daughter)47 static void ga_singlepoint_crossover_integer_chromosome( population *pop,
48 int *father, int *mother,
49 int *son, int *daughter )
50 {
51 int location; /* Point of crossover */
52
53 /* Checks */
54 if (!father || !mother || !son || !daughter)
55 die("Null pointer to integer-array chromosome structure passed.");
56
57 /* Choose crossover point and perform operation */
58 location=random_int(pop->len_chromosomes);
59
60 memcpy(son, mother, location*sizeof(int));
61 memcpy(daughter, father, location*sizeof(int));
62
63 memcpy(&(son[location]), &(father[location]), (pop->len_chromosomes-location)*sizeof(int));
64 memcpy(&(daughter[location]), &(mother[location]), (pop->len_chromosomes-location)*sizeof(int));
65
66 return;
67 }
68
69
70 /**********************************************************************
71 ga_doublepoint_crossover_integer_chromosome()
72 synopsis: `Mates' two chromosomes by double-point crossover.
73 parameters:
74 return:
75 last updated: 31/05/01
76 **********************************************************************/
77
ga_doublepoint_crossover_integer_chromosome(population * pop,int * father,int * mother,int * son,int * daughter)78 static void ga_doublepoint_crossover_integer_chromosome(population *pop,
79 int *father, int *mother,
80 int *son, int *daughter)
81 {
82 int location1, location2; /* Points of crossover. */
83 int tmp; /* For swapping crossover loci. */
84
85 /* Checks */
86 if (!father || !mother || !son || !daughter)
87 die("Null pointer to integer-array chromosome structure passed.");
88
89 /* Choose crossover point and perform operation */
90 location1=random_int(pop->len_chromosomes);
91 do
92 {
93 location2=random_int(pop->len_chromosomes);
94 } while (location2==location1);
95
96 if (location1 > location2)
97 {
98 tmp = location1;
99 location1 = location2;
100 location2 = tmp;
101 }
102
103 memcpy(son, father, location1*sizeof(int));
104 memcpy(daughter, mother, location1*sizeof(int));
105
106 memcpy(&(son[location1]), &(mother[location1]), (location2-location1)*sizeof(int));
107 memcpy(&(daughter[location1]), &(father[location1]), (location2-location1)*sizeof(int));
108
109 memcpy(&(son[location2]), &(father[location2]), (pop->len_chromosomes-location2)*sizeof(int));
110 memcpy(&(daughter[location2]), &(mother[location2]), (pop->len_chromosomes-location2)*sizeof(int));
111
112 return;
113 }
114
115
116 /**********************************************************************
117 ga_crossover_integer_singlepoints()
118 synopsis: `Mates' two genotypes by single-point crossover of
119 each chromosome.
120 parameters:
121 return:
122 last updated: 12/05/00
123 **********************************************************************/
124
ga_crossover_integer_singlepoints(population * pop,entity * father,entity * mother,entity * son,entity * daughter)125 void ga_crossover_integer_singlepoints( population *pop,
126 entity *father, entity *mother,
127 entity *son, entity *daughter )
128 {
129 int i; /* Loop variable over all chromosomes */
130
131 /* Checks */
132 if (!father || !mother || !son || !daughter)
133 die("Null pointer to entity structure passed");
134
135 for (i=0; i<pop->num_chromosomes; i++)
136 {
137 ga_singlepoint_crossover_integer_chromosome( pop,
138 (int *)father->chromosome[i],
139 (int *)mother->chromosome[i],
140 (int *)son->chromosome[i],
141 (int *)daughter->chromosome[i]);
142 }
143
144 return;
145 }
146
147
148 /**********************************************************************
149 ga_crossover_integer_doublepoints()
150 synopsis: `Mates' two genotypes by double-point crossover of
151 each chromosome.
152 parameters:
153 return:
154 last updated: 31/05/00
155 **********************************************************************/
156
ga_crossover_integer_doublepoints(population * pop,entity * father,entity * mother,entity * son,entity * daughter)157 void ga_crossover_integer_doublepoints( population *pop,
158 entity *father, entity *mother,
159 entity *son, entity *daughter )
160 {
161 int i; /* Loop variable over all chromosomes */
162
163 /* Checks */
164 if (!father || !mother || !son || !daughter)
165 die("Null pointer to entity structure passed");
166
167 for (i=0; i<pop->num_chromosomes; i++)
168 {
169 ga_doublepoint_crossover_integer_chromosome( pop,
170 (int *)father->chromosome[i],
171 (int *)mother->chromosome[i],
172 (int *)son->chromosome[i],
173 (int *)daughter->chromosome[i]);
174 }
175
176 return;
177 }
178
179
180 /**********************************************************************
181 ga_crossover_integer_mixing()
182 synopsis: `Mates' two genotypes by mixing parents chromsomes.
183 Keeps all chromosomes intact, and therefore do not
184 need to recreate structural data.
185 parameters:
186 return:
187 last updated: 27/04/00
188 **********************************************************************/
189
ga_crossover_integer_mixing(population * pop,entity * father,entity * mother,entity * son,entity * daughter)190 void ga_crossover_integer_mixing( population *pop,
191 entity *father, entity *mother,
192 entity *son, entity *daughter)
193 {
194 int i; /* Loop variable over all chromosomes */
195
196 /* Checks */
197 if (!father || !mother || !son || !daughter)
198 die("Null pointer to entity structure passed");
199
200 for (i=0; i<pop->num_chromosomes; i++)
201 {
202 if (random_boolean())
203 {
204 memcpy(son->chromosome[i], father->chromosome[i], pop->len_chromosomes*sizeof(int));
205 memcpy(daughter->chromosome[i], mother->chromosome[i], pop->len_chromosomes*sizeof(int));
206 ga_copy_data(pop, son, father, i);
207 ga_copy_data(pop, daughter, mother, i);
208 }
209 else
210 {
211 memcpy(daughter->chromosome[i], father->chromosome[i], pop->len_chromosomes*sizeof(int));
212 memcpy(son->chromosome[i], mother->chromosome[i], pop->len_chromosomes*sizeof(int));
213 ga_copy_data(pop, daughter, father, i);
214 ga_copy_data(pop, son, mother, i);
215 }
216 }
217
218 return;
219 }
220
221
222 /**********************************************************************
223 ga_crossover_integer_mean()
224 synopsis: `Mates' two genotypes by averaging the parents
225 alleles. son rounded down, daughter rounded up.
226 Keeps no chromosomes intact, and therefore will
227 need to recreate all structural data.
228 parameters:
229 return:
230 last updated: 18 Jun 2004
231 **********************************************************************/
232
ga_crossover_integer_mean(population * pop,entity * father,entity * mother,entity * son,entity * daughter)233 void ga_crossover_integer_mean( population *pop,
234 entity *father, entity *mother,
235 entity *son, entity *daughter )
236 {
237 int i, j; /* Loop over all chromosomes, alleles. */
238 int sum; /* Intermediate value. */
239
240 /* Checks. */
241 if (!father || !mother || !son || !daughter)
242 die("Null pointer to entity structure passed.");
243
244 for (i=0; i<pop->num_chromosomes; i++)
245 {
246 for (j=0; j<pop->len_chromosomes; j++)
247 {
248 sum = ((int *)father->chromosome[i])[j] + ((int *)mother->chromosome[i])[j];
249 if ( sum > 0 )
250 {
251 ((int *)son->chromosome[i])[j] = sum/2;
252 ((int *)daughter->chromosome[i])[j] = (sum + 1)/2;
253 }
254 else
255 {
256 ((int *)son->chromosome[i])[j] = (sum - 1)/2;
257 ((int *)daughter->chromosome[i])[j] = sum/2;
258 }
259 }
260 }
261
262 return;
263 }
264
265
266 /**********************************************************************
267 ga_crossover_integer_allele_mixing()
268 synopsis: `Mates' two genotypes by randomizing the parents
269 alleles.
270 Keeps no chromosomes intact, and therefore will
271 need to recreate all structural data.
272 parameters:
273 return:
274 last updated: 30/04/00
275 **********************************************************************/
276
ga_crossover_integer_allele_mixing(population * pop,entity * father,entity * mother,entity * son,entity * daughter)277 void ga_crossover_integer_allele_mixing( population *pop,
278 entity *father, entity *mother,
279 entity *son, entity *daughter )
280 {
281 int i, j; /* Loop over all chromosomes, alleles. */
282
283 /* Checks. */
284 if (!father || !mother || !son || !daughter)
285 die("Null pointer to entity structure passed.");
286
287 for (i=0; i<pop->num_chromosomes; i++)
288 {
289 for (j=0; j<pop->len_chromosomes; j++)
290 {
291 if (random_boolean())
292 {
293 ((int *)son->chromosome[i])[j] = ((int *)father->chromosome[i])[j];
294 ((int *)daughter->chromosome[i])[j] = ((int *)mother->chromosome[i])[j];
295 }
296 else
297 {
298 ((int *)daughter->chromosome[i])[j] = ((int *)father->chromosome[i])[j];
299 ((int *)son->chromosome[i])[j] = ((int *)mother->chromosome[i])[j];
300 }
301 }
302 }
303
304 return;
305 }
306
307
308 /**********************************************************************
309 ga_singlepoint_crossover_boolean_chromosome()
310 synopsis: `Mates' two chromosomes by single-point crossover.
311 parameters:
312 return:
313 last updated: 29 Jun 2003
314 **********************************************************************/
315
ga_singlepoint_crossover_boolean_chromosome(population * pop,boolean * father,boolean * mother,boolean * son,boolean * daughter)316 static void ga_singlepoint_crossover_boolean_chromosome( population *pop,
317 boolean *father, boolean *mother,
318 boolean *son, boolean *daughter )
319 {
320 int location; /* Point of crossover */
321
322 /* Checks */
323 if (!father || !mother || !son || !daughter)
324 die("Null pointer to boolean-array chromosome structure passed.");
325
326 /* Choose crossover point and perform operation */
327 location=random_int(pop->len_chromosomes);
328
329 memcpy(son, mother, location*sizeof(boolean));
330 memcpy(daughter, father, location*sizeof(boolean));
331
332 memcpy(&(son[location]), &(father[location]), (pop->len_chromosomes-location)*sizeof(boolean));
333 memcpy(&(daughter[location]), &(mother[location]), (pop->len_chromosomes-location)*sizeof(boolean));
334
335 return;
336 }
337
338
339 /**********************************************************************
340 ga_doublepoint_crossover_boolean_chromosome()
341 synopsis: `Mates' two chromosomes by double-point crossover.
342 parameters:
343 return:
344 last updated: 29 Jun 2003
345 **********************************************************************/
346
ga_doublepoint_crossover_boolean_chromosome(population * pop,boolean * father,boolean * mother,boolean * son,boolean * daughter)347 static void ga_doublepoint_crossover_boolean_chromosome(population *pop,
348 boolean *father, boolean *mother,
349 boolean *son, boolean *daughter)
350 {
351 int location1, location2; /* Points of crossover. */
352 int tmp; /* For swapping crossover loci. */
353
354 /* Checks */
355 if (!father || !mother || !son || !daughter)
356 die("Null pointer to boolean-array chromosome structure passed.");
357
358 /* Choose crossover point and perform operation */
359 location1=random_int(pop->len_chromosomes);
360 do
361 {
362 location2=random_int(pop->len_chromosomes);
363 } while (location2==location1);
364
365 if (location1 > location2)
366 {
367 tmp = location1;
368 location1 = location2;
369 location2 = tmp;
370 }
371
372 memcpy(son, father, location1*sizeof(boolean));
373 memcpy(daughter, mother, location1*sizeof(boolean));
374
375 memcpy(&(son[location1]), &(mother[location1]), (location2-location1)*sizeof(boolean));
376 memcpy(&(daughter[location1]), &(father[location1]), (location2-location1)*sizeof(boolean));
377
378 memcpy(&(son[location2]), &(father[location2]), (pop->len_chromosomes-location2)*sizeof(boolean));
379 memcpy(&(daughter[location2]), &(mother[location2]), (pop->len_chromosomes-location2)*sizeof(boolean));
380
381 return;
382 }
383
384
385 /**********************************************************************
386 ga_crossover_boolean_singlepoints()
387 synopsis: `Mates' two genotypes by single-point crossover of
388 each chromosome.
389 parameters:
390 return:
391 last updated: 29 Jun 2003
392 **********************************************************************/
393
ga_crossover_boolean_singlepoints(population * pop,entity * father,entity * mother,entity * son,entity * daughter)394 void ga_crossover_boolean_singlepoints( population *pop,
395 entity *father, entity *mother,
396 entity *son, entity *daughter )
397 {
398 int i; /* Loop variable over all chromosomes */
399
400 /* Checks */
401 if (!father || !mother || !son || !daughter)
402 die("Null pointer to entity structure passed.");
403
404 for (i=0; i<pop->num_chromosomes; i++)
405 {
406 ga_singlepoint_crossover_boolean_chromosome( pop,
407 (boolean *)father->chromosome[i],
408 (boolean *)mother->chromosome[i],
409 (boolean *)son->chromosome[i],
410 (boolean *)daughter->chromosome[i]);
411 }
412
413 return;
414 }
415
416
417 /**********************************************************************
418 ga_crossover_boolean_doublepoints()
419 synopsis: `Mates' two genotypes by double-point crossover of
420 each chromosome.
421 parameters:
422 return:
423 last updated: 29 Jun 2003
424 **********************************************************************/
425
ga_crossover_boolean_doublepoints(population * pop,entity * father,entity * mother,entity * son,entity * daughter)426 void ga_crossover_boolean_doublepoints( population *pop,
427 entity *father, entity *mother,
428 entity *son, entity *daughter )
429 {
430 int i; /* Loop variable over all chromosomes */
431
432 /* Checks */
433 if (!father || !mother || !son || !daughter)
434 die("Null pointer to entity structure passed.");
435
436 for (i=0; i<pop->num_chromosomes; i++)
437 {
438 ga_doublepoint_crossover_boolean_chromosome( pop,
439 (boolean *)father->chromosome[i],
440 (boolean *)mother->chromosome[i],
441 (boolean *)son->chromosome[i],
442 (boolean *)daughter->chromosome[i]);
443 }
444
445 return;
446 }
447
448
449 /**********************************************************************
450 ga_crossover_boolean_mixing()
451 synopsis: `Mates' two genotypes by mixing parents chromsomes.
452 Keeps all chromosomes intact, and therefore do not
453 need to recreate structural data.
454 parameters:
455 return:
456 last updated: 27/04/00
457 **********************************************************************/
458
ga_crossover_boolean_mixing(population * pop,entity * father,entity * mother,entity * son,entity * daughter)459 void ga_crossover_boolean_mixing( population *pop,
460 entity *father, entity *mother,
461 entity *son, entity *daughter )
462 {
463 int i; /* Loop variable over all chromosomes */
464
465 /* Checks */
466 if (!father || !mother || !son || !daughter)
467 die("Null pointer to entity structure passed.");
468
469 for (i=0; i<pop->num_chromosomes; i++)
470 {
471 if (random_boolean())
472 {
473 memcpy(son->chromosome[i], father->chromosome[i], pop->len_chromosomes*sizeof(boolean));
474 memcpy(daughter->chromosome[i], mother->chromosome[i], pop->len_chromosomes*sizeof(boolean));
475 ga_copy_data(pop, son, father, i);
476 ga_copy_data(pop, daughter, mother, i);
477 }
478 else
479 {
480 memcpy(daughter->chromosome[i], father->chromosome[i], pop->len_chromosomes*sizeof(boolean));
481 memcpy(son->chromosome[i], mother->chromosome[i], pop->len_chromosomes*sizeof(boolean));
482 ga_copy_data(pop, daughter, father, i);
483 ga_copy_data(pop, son, mother, i);
484 }
485 }
486
487 return;
488 }
489
490
491 /**********************************************************************
492 ga_crossover_boolean_allele_mixing()
493 synopsis: `Mates' two genotypes by randomizing the parents
494 alleles.
495 Keeps no chromosomes intact, and therefore will
496 need to recreate all structural data.
497 parameters:
498 return:
499 last updated: 30/04/00
500 **********************************************************************/
501
ga_crossover_boolean_allele_mixing(population * pop,entity * father,entity * mother,entity * son,entity * daughter)502 void ga_crossover_boolean_allele_mixing( population *pop,
503 entity *father, entity *mother,
504 entity *son, entity *daughter )
505 {
506 int i, j; /* Loop over all chromosomes, alleles. */
507
508 /* Checks. */
509 if (!father || !mother || !son || !daughter)
510 die("Null pointer to entity structure passed.");
511
512 for (i=0; i<pop->num_chromosomes; i++)
513 {
514 for (j=0; j<pop->len_chromosomes; j++)
515 {
516 if (random_boolean())
517 {
518 ((boolean *)son->chromosome[i])[j] = ((boolean *)father->chromosome[i])[j];
519 ((boolean *)daughter->chromosome[i])[j] = ((boolean *)mother->chromosome[i])[j];
520 }
521 else
522 {
523 ((boolean *)daughter->chromosome[i])[j] = ((boolean *)father->chromosome[i])[j];
524 ((boolean *)son->chromosome[i])[j] = ((boolean *)mother->chromosome[i])[j];
525 }
526 }
527 }
528
529 return;
530 }
531
532
533 /**********************************************************************
534 ga_crossover_char_mixing()
535 synopsis: `Mates' two genotypes by mixing parents chromsomes.
536 Keeps all chromosomes intact, and therefore do not
537 need to recreate structural data.
538 parameters:
539 return:
540 last updated: 16/06/01
541 **********************************************************************/
542
ga_crossover_char_mixing(population * pop,entity * father,entity * mother,entity * son,entity * daughter)543 void ga_crossover_char_mixing( population *pop,
544 entity *father, entity *mother,
545 entity *son, entity *daughter )
546 {
547 int i; /* Loop variable over all chromosomes */
548
549 /* Checks */
550 if (!father || !mother || !son || !daughter)
551 die("Null pointer to entity structure passed");
552
553 for (i=0; i<pop->num_chromosomes; i++)
554 {
555 if (random_boolean())
556 {
557 memcpy( son->chromosome[i], father->chromosome[i],
558 pop->len_chromosomes*sizeof(char) );
559 memcpy( daughter->chromosome[i], mother->chromosome[i],
560 pop->len_chromosomes*sizeof(char) );
561 ga_copy_data(pop, son, father, i);
562 ga_copy_data(pop, daughter, mother, i);
563 }
564 else
565 {
566 memcpy( daughter->chromosome[i], father->chromosome[i],
567 pop->len_chromosomes*sizeof(char) );
568 memcpy( son->chromosome[i], mother->chromosome[i],
569 pop->len_chromosomes*sizeof(char) );
570 ga_copy_data(pop, daughter, father, i);
571 ga_copy_data(pop, son, mother, i);
572 }
573 }
574
575 return;
576 }
577
578
579 /**********************************************************************
580 ga_crossover_char_allele_mixing()
581 synopsis: `Mates' two genotypes by randomizing the parents
582 alleles.
583 Keeps no chromosomes intact, and therefore will
584 need to recreate all structural data.
585 parameters:
586 return:
587 last updated: 16/06/01
588 **********************************************************************/
589
ga_crossover_char_allele_mixing(population * pop,entity * father,entity * mother,entity * son,entity * daughter)590 void ga_crossover_char_allele_mixing( population *pop,
591 entity *father, entity *mother,
592 entity *son, entity *daughter )
593 {
594 int i, j; /* Loop over all chromosomes, alleles. */
595
596 /* Checks. */
597 if (!father || !mother || !son || !daughter)
598 die("Null pointer to entity structure passed.");
599
600 for (i=0; i<pop->num_chromosomes; i++)
601 {
602 for (j=0; j<pop->len_chromosomes; j++)
603 {
604 if (random_boolean())
605 {
606 ((char *)son->chromosome[i])[j] = ((char *)father->chromosome[i])[j];
607 ((char *)daughter->chromosome[i])[j] = ((char *)mother->chromosome[i])[j];
608 }
609 else
610 {
611 ((char *)daughter->chromosome[i])[j] = ((char *)father->chromosome[i])[j];
612 ((char *)son->chromosome[i])[j] = ((char *)mother->chromosome[i])[j];
613 }
614 }
615 }
616
617 return;
618 }
619
620
621 /**********************************************************************
622 ga_crossover_double_mixing()
623 synopsis: `Mates' two genotypes by mixing parents chromsomes.
624 Keeps all chromosomes intact, and therefore do not
625 need to recreate structural data.
626 parameters:
627 return:
628 last updated: 16/06/01
629 **********************************************************************/
630
ga_crossover_double_mixing(population * pop,entity * father,entity * mother,entity * son,entity * daughter)631 void ga_crossover_double_mixing( population *pop,
632 entity *father, entity *mother,
633 entity *son, entity *daughter )
634 {
635 int i; /* Loop variable over all chromosomes */
636
637 /* Checks */
638 if (!father || !mother || !son || !daughter)
639 die("Null pointer to entity structure passed");
640
641 for (i=0; i<pop->num_chromosomes; i++)
642 {
643 if (random_boolean())
644 {
645 memcpy( son->chromosome[i], father->chromosome[i],
646 pop->len_chromosomes*sizeof(double) );
647 memcpy( daughter->chromosome[i], mother->chromosome[i],
648 pop->len_chromosomes*sizeof(double) );
649 ga_copy_data(pop, son, father, i);
650 ga_copy_data(pop, daughter, mother, i);
651 }
652 else
653 {
654 memcpy( daughter->chromosome[i], father->chromosome[i],
655 pop->len_chromosomes*sizeof(double) );
656 memcpy( son->chromosome[i], mother->chromosome[i],
657 pop->len_chromosomes*sizeof(double) );
658 ga_copy_data(pop, daughter, father, i);
659 ga_copy_data(pop, son, mother, i);
660 }
661 }
662
663 return;
664 }
665
666
667 /**********************************************************************
668 ga_crossover_double_mean()
669 synopsis: `Mates' two genotypes by averaging the parents
670 alleles.
671 Keeps no chromosomes intact, and therefore will
672 need to recreate all structural data.
673 FIXME: Children are identical!
674 parameters:
675 return:
676 last updated: 18 Jun 2004
677 **********************************************************************/
678
ga_crossover_double_mean(population * pop,entity * father,entity * mother,entity * son,entity * daughter)679 void ga_crossover_double_mean( population *pop,
680 entity *father, entity *mother,
681 entity *son, entity *daughter )
682 {
683 int i, j; /* Loop over all chromosomes, alleles. */
684
685 /* Checks. */
686 if (!father || !mother || !son || !daughter)
687 die("Null pointer to entity structure passed.");
688
689 for (i=0; i<pop->num_chromosomes; i++)
690 {
691 for (j=0; j<pop->len_chromosomes; j++)
692 {
693 ((double *)son->chromosome[i])[j] = 0.5 * (((double *)father->chromosome[i])[j] + ((double *)mother->chromosome[i])[j]);
694 ((double *)daughter->chromosome[i])[j] = 0.5 * (((double *)father->chromosome[i])[j] + ((double *)mother->chromosome[i])[j]);
695 }
696 }
697
698 return;
699 }
700
701
702 /**********************************************************************
703 ga_crossover_double_allele_mixing()
704 synopsis: `Mates' two genotypes by randomizing the parents
705 alleles.
706 Keeps no chromosomes intact, and therefore will
707 need to recreate all structural data.
708 parameters:
709 return:
710 last updated: 16/06/01
711 **********************************************************************/
712
ga_crossover_double_allele_mixing(population * pop,entity * father,entity * mother,entity * son,entity * daughter)713 void ga_crossover_double_allele_mixing( population *pop,
714 entity *father, entity *mother,
715 entity *son, entity *daughter )
716 {
717 int i, j; /* Loop over all chromosomes, alleles. */
718
719 /* Checks. */
720 if (!father || !mother || !son || !daughter)
721 die("Null pointer to entity structure passed.");
722
723 for (i=0; i<pop->num_chromosomes; i++)
724 {
725 for (j=0; j<pop->len_chromosomes; j++)
726 {
727 if (random_boolean())
728 {
729 ((double *)son->chromosome[i])[j] = ((double *)father->chromosome[i])[j];
730 ((double *)daughter->chromosome[i])[j] = ((double *)mother->chromosome[i])[j];
731 }
732 else
733 {
734 ((double *)daughter->chromosome[i])[j] = ((double *)father->chromosome[i])[j];
735 ((double *)son->chromosome[i])[j] = ((double *)mother->chromosome[i])[j];
736 }
737 }
738 }
739
740 return;
741 }
742
743
744 /**********************************************************************
745 ga_crossover_char_singlepoints()
746 synopsis: `Mates' two genotypes by single-point crossover of
747 each chromosome.
748 parameters:
749 return:
750 last updated: 16/07/01
751 **********************************************************************/
752
ga_crossover_char_singlepoints(population * pop,entity * father,entity * mother,entity * son,entity * daughter)753 void ga_crossover_char_singlepoints( population *pop,
754 entity *father, entity *mother,
755 entity *son, entity *daughter )
756 {
757 int i; /* Loop variable over all chromosomes. */
758 int location; /* Point of crossover. */
759
760 /* Checks */
761 if (!father || !mother || !son || !daughter)
762 die("Null pointer to entity structure passed");
763
764 for (i=0; i<pop->num_chromosomes; i++)
765 {
766 /* Choose crossover point and perform operation */
767 location=random_int(pop->len_chromosomes);
768
769 memcpy( son->chromosome[i], mother->chromosome[i],
770 location*sizeof(char) );
771 memcpy( daughter->chromosome[i], father->chromosome[i],
772 location*sizeof(char));
773
774 memcpy( &(((char *)son->chromosome[i])[location]),
775 &(((char *)father->chromosome[i])[location]),
776 (pop->len_chromosomes-location)*sizeof(char) );
777 memcpy( &(((char *)daughter->chromosome[i])[location]),
778 &(((char *)mother->chromosome[i])[location]),
779 (pop->len_chromosomes-location)*sizeof(char) );
780 }
781
782 return;
783 }
784
785
786 /**********************************************************************
787 ga_crossover_char_doublepoints()
788 synopsis: `Mates' two genotypes by double-point crossover of
789 each chromosome.
790 parameters:
791 return:
792 last updated: 16/07/01
793 **********************************************************************/
794
ga_crossover_char_doublepoints(population * pop,entity * father,entity * mother,entity * son,entity * daughter)795 void ga_crossover_char_doublepoints( population *pop,
796 entity *father, entity *mother,
797 entity *son, entity *daughter )
798 {
799 int i; /* Loop variable over all chromosomes. */
800 int location1, location2; /* Points of crossover. */
801 int tmp; /* For swapping crossover loci. */
802
803 /* Checks */
804 if (!father || !mother || !son || !daughter)
805 die("Null pointer to entity structure passed");
806
807 for (i=0; i<pop->num_chromosomes; i++)
808 {
809 /* Choose crossover point and perform operation */
810 location1=random_int(pop->len_chromosomes);
811 do
812 {
813 location2=random_int(pop->len_chromosomes);
814 } while (location2==location1);
815
816 if (location1 > location2)
817 {
818 tmp = location1;
819 location1 = location2;
820 location2 = tmp;
821 }
822
823 memcpy( son->chromosome[i], father->chromosome[i],
824 location1*sizeof(char) );
825 memcpy( daughter->chromosome[i], mother->chromosome[i],
826 location1*sizeof(char) );
827
828 memcpy( &(((char *)son->chromosome[i])[location1]),
829 &(((char *)mother->chromosome[i])[location1]),
830 (location2-location1)*sizeof(char) );
831 memcpy( &(((char *)daughter->chromosome[i])[location1]),
832 &(((char *)father->chromosome[i])[location1]),
833 (location2-location1)*sizeof(char) );
834
835 memcpy( &(((char *)son->chromosome[i])[location2]),
836 &(((char *)father->chromosome[i])[location2]),
837 (pop->len_chromosomes-location2)*sizeof(char) );
838 memcpy( &(((char *)daughter->chromosome[i])[location2]),
839 &(((char *)mother->chromosome[i])[location2]),
840 (pop->len_chromosomes-location2)*sizeof(char) );
841 }
842
843 return;
844 }
845
846
847 /**********************************************************************
848 ga_crossover_bitstring_singlepoints()
849 synopsis: `Mates' two genotypes by single-point crossover of
850 each chromosome.
851 parameters:
852 return:
853 last updated: 30/06/01
854 **********************************************************************/
855
ga_crossover_bitstring_singlepoints(population * pop,entity * father,entity * mother,entity * son,entity * daughter)856 void ga_crossover_bitstring_singlepoints(population *pop, entity *father, entity *mother, entity *son, entity *daughter)
857 {
858 int i; /* Loop variable over all chromosomes. */
859 int location; /* Point of crossover. */
860
861 /* Checks */
862 if (!father || !mother || !son || !daughter)
863 die("Null pointer to entity structure passed");
864
865 for (i=0; i<pop->num_chromosomes; i++)
866 {
867 /* Choose crossover point and perform operation */
868 location=random_int(pop->len_chromosomes);
869
870 ga_bit_copy(son->chromosome[i], mother->chromosome[i],
871 0, 0, location);
872 ga_bit_copy(daughter->chromosome[i], father->chromosome[i],
873 0, 0, location);
874
875 ga_bit_copy(daughter->chromosome[i], mother->chromosome[i],
876 location, location, pop->len_chromosomes-location);
877 ga_bit_copy(son->chromosome[i], father->chromosome[i],
878 location, location, pop->len_chromosomes-location);
879 }
880
881 return;
882 }
883
884
885 /**********************************************************************
886 ga_crossover_bitstring_doublepoints()
887 synopsis: `Mates' two genotypes by double-point crossover of
888 each chromosome.
889 parameters: population * Population structure.
890 entity *father, *mother Parent entities.
891 entity *son, *daughter Child entities.
892 return:
893 last updated: 23 Jun 2003
894 **********************************************************************/
895
ga_crossover_bitstring_doublepoints(population * pop,entity * father,entity * mother,entity * son,entity * daughter)896 void ga_crossover_bitstring_doublepoints( population *pop,
897 entity *father, entity *mother,
898 entity *son, entity *daughter )
899 {
900 int i; /* Loop variable over all chromosomes. */
901 int location1, location2; /* Points of crossover. */
902 int tmp; /* For swapping crossover loci. */
903
904 /* Checks */
905 if (!father || !mother || !son || !daughter)
906 die("Null pointer to entity structure passed");
907
908 for (i=0; i<pop->num_chromosomes; i++)
909 {
910 /* Choose crossover point and perform operation */
911 location1=random_int(pop->len_chromosomes);
912 do
913 {
914 location2=random_int(pop->len_chromosomes);
915 } while (location2==location1);
916
917 if (location1 > location2)
918 {
919 tmp = location1;
920 location1 = location2;
921 location2 = tmp;
922 }
923
924 ga_bit_copy(son->chromosome[i], mother->chromosome[i],
925 0, 0, location1);
926 ga_bit_copy(daughter->chromosome[i], father->chromosome[i],
927 0, 0, location1);
928
929 ga_bit_copy(son->chromosome[i], father->chromosome[i],
930 location1, location1, location2-location1);
931 ga_bit_copy(daughter->chromosome[i], mother->chromosome[i],
932 location1, location1, location2-location1);
933
934 ga_bit_copy(son->chromosome[i], mother->chromosome[i],
935 location2, location2, pop->len_chromosomes-location2);
936 ga_bit_copy(daughter->chromosome[i], father->chromosome[i],
937 location2, location2, pop->len_chromosomes-location2);
938 }
939
940 return;
941 }
942
943
944 /**********************************************************************
945 ga_crossover_bitstring_mixing()
946 synopsis: `Mates' two genotypes by mixing parents chromsomes.
947 Keeps all chromosomes intact, and therefore do not
948 need to recreate structural data.
949 parameters:
950 return:
951 last updated: 30/06/01
952 **********************************************************************/
953
ga_crossover_bitstring_mixing(population * pop,entity * father,entity * mother,entity * son,entity * daughter)954 void ga_crossover_bitstring_mixing(population *pop, entity *father, entity *mother, entity *son, entity *daughter)
955 {
956 int i; /* Loop variable over all chromosomes */
957
958 /* Checks */
959 if (!father || !mother || !son || !daughter)
960 die("Null pointer to entity structure passed");
961
962 for (i=0; i<pop->num_chromosomes; i++)
963 {
964 if (random_boolean())
965 {
966 ga_bit_clone(son->chromosome[i], father->chromosome[i], pop->len_chromosomes);
967 ga_bit_clone(daughter->chromosome[i], mother->chromosome[i], pop->len_chromosomes);
968 ga_copy_data(pop, son, father, i);
969 ga_copy_data(pop, daughter, mother, i);
970 }
971 else
972 {
973 ga_bit_clone(daughter->chromosome[i], father->chromosome[i], pop->len_chromosomes);
974 ga_bit_clone(son->chromosome[i], mother->chromosome[i], pop->len_chromosomes);
975 ga_copy_data(pop, daughter, father, i);
976 ga_copy_data(pop, son, mother, i);
977 }
978 }
979
980 return;
981 }
982
983
984 /**********************************************************************
985 ga_crossover_bitstring_allele_mixing()
986 synopsis: `Mates' two genotypes by randomizing the parents
987 alleles.
988 Keeps no chromosomes intact, and therefore will
989 need to recreate all structural data.
990 parameters:
991 return:
992 last updated: 30/06/01
993 **********************************************************************/
994
ga_crossover_bitstring_allele_mixing(population * pop,entity * father,entity * mother,entity * son,entity * daughter)995 void ga_crossover_bitstring_allele_mixing( population *pop,
996 entity *father, entity *mother,
997 entity *son, entity *daughter )
998 {
999 int i, j; /* Loop over all chromosomes, alleles. */
1000
1001 /* Checks. */
1002 if (!father || !mother || !son || !daughter)
1003 die("Null pointer to entity structure passed.");
1004
1005 for (i=0; i<pop->num_chromosomes; i++)
1006 {
1007 for (j=0; j<pop->len_chromosomes; j++)
1008 {
1009 if (random_boolean())
1010 {
1011 if (ga_bit_get(father->chromosome[i],j))
1012 ga_bit_set(son->chromosome[i],j);
1013 else
1014 ga_bit_clear(son->chromosome[i],j);
1015
1016 if (ga_bit_get(mother->chromosome[i],j))
1017 ga_bit_set(daughter->chromosome[i],j);
1018 else
1019 ga_bit_clear(daughter->chromosome[i],j);
1020 }
1021 else
1022 {
1023 if (ga_bit_get(father->chromosome[i],j))
1024 ga_bit_set(daughter->chromosome[i],j);
1025 else
1026 ga_bit_clear(daughter->chromosome[i],j);
1027
1028 if (ga_bit_get(mother->chromosome[i],j))
1029 ga_bit_set(son->chromosome[i],j);
1030 else
1031 ga_bit_clear(son->chromosome[i],j);
1032 }
1033 }
1034 }
1035
1036 return;
1037 }
1038
1039
1040 /**********************************************************************
1041 ga_singlepoint_crossover_double_chromosome()
1042 synopsis: `Mates' two chromosomes by single-point crossover.
1043 parameters:
1044 return:
1045 last updated: 07 Nov 2002
1046 **********************************************************************/
1047
ga_singlepoint_crossover_double_chromosome(population * pop,double * father,double * mother,double * son,double * daughter)1048 static void ga_singlepoint_crossover_double_chromosome( population *pop,
1049 double *father, double *mother,
1050 double *son, double *daughter )
1051 {
1052 int location; /* Point of crossover */
1053
1054 /* Checks */
1055 if (!father || !mother || !son || !daughter)
1056 die("Null pointer to chromosome structure passed.");
1057
1058 /* Choose crossover point and perform operation */
1059 location=random_int(pop->len_chromosomes);
1060
1061 memcpy(son, mother, location*sizeof(double));
1062 memcpy(daughter, father, location*sizeof(double));
1063
1064 memcpy(&(son[location]), &(father[location]), (pop->len_chromosomes-location)*sizeof(double));
1065 memcpy(&(daughter[location]), &(mother[location]), (pop->len_chromosomes-location)*sizeof(double));
1066
1067 return;
1068 }
1069
1070
1071 /**********************************************************************
1072 ga_doublepoint_crossover_double_chromosome()
1073 synopsis: `Mates' two chromosomes by double-point crossover.
1074 parameters:
1075 return:
1076 last updated: 07 Nov 2002
1077 **********************************************************************/
1078
ga_doublepoint_crossover_double_chromosome(population * pop,double * father,double * mother,double * son,double * daughter)1079 static void ga_doublepoint_crossover_double_chromosome(population *pop,
1080 double *father, double *mother,
1081 double *son, double *daughter)
1082 {
1083 int location1, location2; /* Points of crossover. */
1084 int tmp; /* For swapping crossover loci. */
1085
1086 /* Checks */
1087 if (!father || !mother || !son || !daughter)
1088 die("Null pointer to chromosome structure passed.");
1089
1090 /* Choose crossover point and perform operation */
1091 location1=random_int(pop->len_chromosomes);
1092 do
1093 {
1094 location2=random_int(pop->len_chromosomes);
1095 } while (location2==location1);
1096
1097 if (location1 > location2)
1098 {
1099 tmp = location1;
1100 location1 = location2;
1101 location2 = tmp;
1102 }
1103
1104 memcpy(son, father, location1*sizeof(double));
1105 memcpy(daughter, mother, location1*sizeof(double));
1106
1107 memcpy(&(son[location1]), &(mother[location1]), (location2-location1)*sizeof(double));
1108 memcpy(&(daughter[location1]), &(father[location1]), (location2-location1)*sizeof(double));
1109
1110 memcpy(&(son[location2]), &(father[location2]), (pop->len_chromosomes-location2)*sizeof(double));
1111 memcpy(&(daughter[location2]), &(mother[location2]), (pop->len_chromosomes-location2)*sizeof(double));
1112
1113 return;
1114 }
1115
1116
1117 /**********************************************************************
1118 ga_crossover_double_singlepoints()
1119 synopsis: `Mates' two genotypes by single-point crossover of
1120 each chromosome.
1121 parameters:
1122 return:
1123 last updated: 07 Nov 2002
1124 **********************************************************************/
1125
ga_crossover_double_singlepoints(population * pop,entity * father,entity * mother,entity * son,entity * daughter)1126 void ga_crossover_double_singlepoints(population *pop, entity *father, entity *mother, entity *son, entity *daughter)
1127 {
1128 int i; /* Loop variable over all chromosomes */
1129
1130 /* Checks */
1131 if (!father || !mother || !son || !daughter)
1132 die("Null pointer to entity structure passed");
1133
1134 for (i=0; i<pop->num_chromosomes; i++)
1135 {
1136 ga_singlepoint_crossover_double_chromosome( pop,
1137 (double *)father->chromosome[i],
1138 (double *)mother->chromosome[i],
1139 (double *)son->chromosome[i],
1140 (double *)daughter->chromosome[i]);
1141 }
1142
1143 return;
1144 }
1145
1146
1147 /**********************************************************************
1148 ga_crossover_double_doublepoints()
1149 synopsis: `Mates' two genotypes by double-point crossover of
1150 each chromosome.
1151 parameters:
1152 return:
1153 last updated: 07 Nov 2002
1154 **********************************************************************/
1155
ga_crossover_double_doublepoints(population * pop,entity * father,entity * mother,entity * son,entity * daughter)1156 void ga_crossover_double_doublepoints( population *pop,
1157 entity *father, entity *mother,
1158 entity *son, entity *daughter )
1159 {
1160 int i; /* Loop variable over all chromosomes */
1161
1162 /* Checks */
1163 if (!father || !mother || !son || !daughter)
1164 die("Null pointer to entity structure passed");
1165
1166 for (i=0; i<pop->num_chromosomes; i++)
1167 {
1168 ga_doublepoint_crossover_double_chromosome( pop,
1169 (double *)father->chromosome[i],
1170 (double *)mother->chromosome[i],
1171 (double *)son->chromosome[i],
1172 (double *)daughter->chromosome[i]);
1173 }
1174
1175 return;
1176 }
1177
1178
1179