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