#ifndef lint static char *rcsid = "$Header: /tmp_mnt/vida/disks/disk5/Users/terry/r/gassy/RCS/crossover.c,v 1.3 1992/10/09 06:43:50 terry Exp terry $"; #endif #include "types.h" #include "utility.h" /* * Now cross them over, choosing from context->population and * moving into new_population. There are nselected to choose from (in * selections), and nreproducers must be produced (into new_population). */ VOID * no_crossover_random_copy(selections, nselected, nreproducers, new_population, context) INT *selections; INT nselected; INT nreproducers; POPULATION new_population; CONTEXT *context; { /* * Just choose them randomly & copy them complete. */ register INT i; for (i = 0; i < nreproducers; i++){ copy_individual(&new_population[i], &context->population[selections[uniform(nselected)]], context); } return; } VOID * no_crossover(selections, nselected, nreproducers, new_population, context) INT *selections; INT nselected; INT nreproducers; POPULATION new_population; CONTEXT *context; { /* * Just copy them as you see 'em in selections. */ register INT i; for (i = 0; i < nreproducers; i++){ copy_individual(&new_population[i], &context->population[selections[i]], context); } return; } #if defined(APP_INDIVIDUALS_HAVE_CONSTANT_SIZE) && defined(APP_INDIVIDUALS_ARE_STRINGS) VOID uniform_crossover_function(); VOID two_pt_crossover_function(); VOID one_pt_crossover_function(); VOID * one_pt_crossover(selections, nselected, nreproducers, new_population, context) INT *selections; INT nselected; INT nreproducers; POPULATION new_population; CONTEXT *context; { general_crossover(one_pt_crossover_function, selections, nselected, nreproducers, new_population, context); } VOID one_pt_crossover_function(parent_1, parent_2, child_1, child_2, context) INDIVIDUAL_TYPE parent_1; INDIVIDUAL_TYPE parent_2; INDIVIDUAL_TYPE child_1; INDIVIDUAL_TYPE child_2; CONTEXT *context; { register INT crossover_point = uniform(context->genome_size - 1) + 1; /* produces 1..context->genome_size-1 */ register INT pos; for (pos = 0; pos < crossover_point; pos++){ child_1[pos] = parent_1[pos]; child_2[pos] = parent_2[pos]; } for (; pos < context->genome_size; pos++){ child_1[pos] = parent_2[pos]; child_2[pos] = parent_1[pos]; } return; } VOID * two_pt_crossover(selections, nselected, nreproducers, new_population, context) INT *selections; INT nselected; INT nreproducers; POPULATION new_population; CONTEXT *context; { general_crossover(two_pt_crossover_function, selections, nselected, nreproducers, new_population, context); } VOID two_pt_crossover_function(parent_1, parent_2, child_1, child_2, context) INDIVIDUAL_TYPE parent_1; INDIVIDUAL_TYPE parent_2; INDIVIDUAL_TYPE child_1; INDIVIDUAL_TYPE child_2; CONTEXT *context; { register INT crossover_point_1 = uniform(context->genome_size - 1) + 1; /* produces 1..context->genome_size-1 */ register INT crossover_point_2 = uniform(context->genome_size - 1) + 1; /* produces 1..context->genome_size-1 */ register INT pos; /* If the two crossover points are the same, this becomes one point crossover. */ if (crossover_point_1 > crossover_point_2){ register INT tmp; tmp = crossover_point_1; crossover_point_1 = crossover_point_2; crossover_point_2 = tmp; } for (pos = 0; pos < crossover_point_1; pos++){ child_1[pos] = parent_1[pos]; child_2[pos] = parent_2[pos]; } for (; pos < crossover_point_2; pos++){ child_1[pos] = parent_2[pos]; child_2[pos] = parent_1[pos]; } for (; pos < context->genome_size; pos++){ child_1[pos] = parent_1[pos]; child_2[pos] = parent_2[pos]; } return; } VOID * uniform_crossover(selections, nselected, nreproducers, new_population, context) INT *selections; INT nselected; INT nreproducers; POPULATION new_population; CONTEXT *context; { general_crossover(uniform_crossover_function, selections, nselected, nreproducers, new_population, context); } VOID uniform_crossover_function(parent_1, parent_2, child_1, child_2, context) INDIVIDUAL_TYPE parent_1; INDIVIDUAL_TYPE parent_2; INDIVIDUAL_TYPE child_1; INDIVIDUAL_TYPE child_2; CONTEXT *context; { register INT pos; for (pos = 0; pos < context->genome_size; pos++){ if (DO_UNIFORM){ child_1[pos] = parent_1[pos]; child_2[pos] = parent_2[pos]; } else { child_1[pos] = parent_2[pos]; child_2[pos] = parent_1[pos]; } } return; } #endif