summaryrefslogtreecommitdiffstats
path: root/abc70930/src/bdd/cudd/cuddGenetic.c
diff options
context:
space:
mode:
Diffstat (limited to 'abc70930/src/bdd/cudd/cuddGenetic.c')
-rw-r--r--abc70930/src/bdd/cudd/cuddGenetic.c921
1 files changed, 0 insertions, 921 deletions
diff --git a/abc70930/src/bdd/cudd/cuddGenetic.c b/abc70930/src/bdd/cudd/cuddGenetic.c
deleted file mode 100644
index 9fe03dad..00000000
--- a/abc70930/src/bdd/cudd/cuddGenetic.c
+++ /dev/null
@@ -1,921 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddGenetic.c]
-
- PackageName [cudd]
-
- Synopsis [Genetic algorithm for variable reordering.]
-
- Description [Internal procedures included in this file:
- <ul>
- <li> cuddGa()
- </ul>
- Static procedures included in this module:
- <ul>
- <li> make_random()
- <li> sift_up()
- <li> build_dd()
- <li> largest()
- <li> rand_int()
- <li> array_hash()
- <li> array_compare()
- <li> find_best()
- <li> find_average_fitness()
- <li> PMX()
- <li> roulette()
- </ul>
-
- The genetic algorithm implemented here is as follows. We start with
- the current DD order. We sift this order and use this as the
- reference DD. We only keep 1 DD around for the entire process and
- simply rearrange the order of this DD, storing the various orders
- and their corresponding DD sizes. We generate more random orders to
- build an initial population. This initial population is 3 times the
- number of variables, with a maximum of 120. Each random order is
- built (from the reference DD) and its size stored. Each random
- order is also sifted to keep the DD sizes fairly small. Then a
- crossover is performed between two orders (picked randomly) and the
- two resulting DDs are built and sifted. For each new order, if its
- size is smaller than any DD in the population, it is inserted into
- the population and the DD with the largest number of nodes is thrown
- out. The crossover process happens up to 50 times, and at this point
- the DD in the population with the smallest size is chosen as the
- result. This DD must then be built from the reference DD.]
-
- SeeAlso []
-
- Author [Curt Musfeldt, Alan Shuler, Fabio Somenzi]
-
- Copyright [This file was created at the University of Colorado at
- Boulder. The University of Colorado at Boulder makes no warranty
- about the suitability of this software for any purpose. It is
- presented on an AS IS basis.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddGenetic.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
-#endif
-
-static int popsize; /* the size of the population */
-static int numvars; /* the number of input variables in the ckt. */
-/* storedd stores the population orders and sizes. This table has two
-** extra rows and one extras column. The two extra rows are used for the
-** offspring produced by a crossover. Each row stores one order and its
-** size. The order is stored by storing the indices of variables in the
-** order in which they appear in the order. The table is in reality a
-** one-dimensional array which is accessed via a macro to give the illusion
-** it is a two-dimensional structure.
-*/
-static int *storedd;
-static st_table *computed; /* hash table to identify existing orders */
-static int *repeat; /* how many times an order is present */
-static int large; /* stores the index of the population with
- ** the largest number of nodes in the DD */
-static int result;
-static int cross; /* the number of crossovers to perform */
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-/* macro used to access the population table as if it were a
-** two-dimensional structure.
-*/
-#define STOREDD(i,j) storedd[(i)*(numvars+1)+(j)]
-
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static int make_random ARGS((DdManager *table, int lower));
-static int sift_up ARGS((DdManager *table, int x, int x_low));
-static int build_dd ARGS((DdManager *table, int num, int lower, int upper));
-static int largest ARGS(());
-static int rand_int ARGS((int a));
-static int array_hash ARGS((char *array, int modulus));
-static int array_compare ARGS((const char *array1, const char *array2));
-static int find_best ARGS(());
-static double find_average_fitness ARGS(());
-static int PMX ARGS((int maxvar));
-static int roulette ARGS((int *p1, int *p2));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**Function********************************************************************
-
- Synopsis [Genetic algorithm for DD reordering.]
-
- Description [Genetic algorithm for DD reordering.
- The two children of a crossover will be stored in
- storedd[popsize] and storedd[popsize+1] --- the last two slots in the
- storedd array. (This will make comparisons and replacement easy.)
- Returns 1 in case of success; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-int
-cuddGa(
- DdManager * table /* manager */,
- int lower /* lowest level to be reordered */,
- int upper /* highest level to be reorderded */)
-{
- int i,n,m; /* dummy/loop vars */
- int index;
- double average_fitness;
- int small; /* index of smallest DD in population */
-
- /* Do an initial sifting to produce at least one reasonable individual. */
- if (!cuddSifting(table,lower,upper)) return(0);
-
- /* Get the initial values. */
- numvars = upper - lower + 1; /* number of variables to be reordered */
- if (table->populationSize == 0) {
- popsize = 3 * numvars; /* population size is 3 times # of vars */
- if (popsize > 120) {
- popsize = 120; /* Maximum population size is 120 */
- }
- } else {
- popsize = table->populationSize; /* user specified value */
- }
- if (popsize < 4) popsize = 4; /* enforce minimum population size */
-
- /* Allocate population table. */
- storedd = ALLOC(int,(popsize+2)*(numvars+1));
- if (storedd == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
-
- /* Initialize the computed table. This table is made up of two data
- ** structures: A hash table with the key given by the order, which says
- ** if a given order is present in the population; and the repeat
- ** vector, which says how many copies of a given order are stored in
- ** the population table. If there are multiple copies of an order, only
- ** one has a repeat count greater than 1. This copy is the one pointed
- ** by the computed table.
- */
- repeat = ALLOC(int,popsize);
- if (repeat == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- FREE(storedd);
- return(0);
- }
- for (i = 0; i < popsize; i++) {
- repeat[i] = 0;
- }
- computed = st_init_table(array_compare,array_hash);
- if (computed == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- FREE(storedd);
- FREE(repeat);
- return(0);
- }
-
- /* Copy the current DD and its size to the population table. */
- for (i = 0; i < numvars; i++) {
- STOREDD(0,i) = table->invperm[i+lower]; /* order of initial DD */
- }
- STOREDD(0,numvars) = table->keys - table->isolated; /* size of initial DD */
-
- /* Store the initial order in the computed table. */
- if (st_insert(computed,(char *)storedd,(char *) 0) == ST_OUT_OF_MEM) {
- FREE(storedd);
- FREE(repeat);
- st_free_table(computed);
- return(0);
- }
- repeat[0]++;
-
- /* Insert the reverse order as second element of the population. */
- for (i = 0; i < numvars; i++) {
- STOREDD(1,numvars-1-i) = table->invperm[i+lower]; /* reverse order */
- }
-
- /* Now create the random orders. make_random fills the population
- ** table with random permutations. The successive loop builds and sifts
- ** the DDs for the reverse order and each random permutation, and stores
- ** the results in the computed table.
- */
- if (!make_random(table,lower)) {
- table->errorCode = CUDD_MEMORY_OUT;
- FREE(storedd);
- FREE(repeat);
- st_free_table(computed);
- return(0);
- }
- for (i = 1; i < popsize; i++) {
- result = build_dd(table,i,lower,upper); /* build and sift order */
- if (!result) {
- FREE(storedd);
- FREE(repeat);
- st_free_table(computed);
- return(0);
- }
- if (st_lookup(computed,(char *)&STOREDD(i,0),(char **)&index)) {
- repeat[index]++;
- } else {
- if (st_insert(computed,(char *)&STOREDD(i,0),(char *)(long)i) ==
- ST_OUT_OF_MEM) {
- FREE(storedd);
- FREE(repeat);
- st_free_table(computed);
- return(0);
- }
- repeat[i]++;
- }
- }
-
-#if 0
-#ifdef DD_STATS
- /* Print the initial population. */
- (void) fprintf(table->out,"Initial population after sifting\n");
- for (m = 0; m < popsize; m++) {
- for (i = 0; i < numvars; i++) {
- (void) fprintf(table->out," %2d",STOREDD(m,i));
- }
- (void) fprintf(table->out," : %3d (%d)\n",
- STOREDD(m,numvars),repeat[m]);
- }
-#endif
-#endif
-
- small = find_best();
- average_fitness = find_average_fitness();
-#ifdef DD_STATS
- (void) fprintf(table->out,"\nInitial population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness);
-#endif
-
- /* Decide how many crossovers should be tried. */
- if (table->numberXovers == 0) {
- cross = 3*numvars;
- if (cross > 60) { /* do a maximum of 50 crossovers */
- cross = 60;
- }
- } else {
- cross = table->numberXovers; /* use user specified value */
- }
-
- /* Perform the crossovers to get the best order. */
- for (m = 0; m < cross; m++) {
- if (!PMX(table->size)) { /* perform one crossover */
- table->errorCode = CUDD_MEMORY_OUT;
- FREE(storedd);
- FREE(repeat);
- st_free_table(computed);
- return(0);
- }
- /* The offsprings are left in the last two entries of the
- ** population table. These are now considered in turn.
- */
- for (i = popsize; i <= popsize+1; i++) {
- result = build_dd(table,i,lower,upper); /* build and sift child */
- if (!result) {
- FREE(storedd);
- FREE(repeat);
- st_free_table(computed);
- return(0);
- }
- large = largest(); /* find the largest DD in population */
-
- /* If the new child is smaller than the largest DD in the current
- ** population, enter it into the population in place of the
- ** largest DD.
- */
- if (STOREDD(i,numvars) < STOREDD(large,numvars)) {
- /* Look up the largest DD in the computed table.
- ** Decrease its repetition count. If the repetition count
- ** goes to 0, remove the largest DD from the computed table.
- */
- result = st_lookup(computed,(char *)&STOREDD(large,0),(char
- **)&index);
- if (!result) {
- FREE(storedd);
- FREE(repeat);
- st_free_table(computed);
- return(0);
- }
- repeat[index]--;
- if (repeat[index] == 0) {
- int *pointer = &STOREDD(index,0);
- result = st_delete(computed, (char **)&pointer,NULL);
- if (!result) {
- FREE(storedd);
- FREE(repeat);
- st_free_table(computed);
- return(0);
- }
- }
- /* Copy the new individual to the entry of the
- ** population table just made available and update the
- ** computed table.
- */
- for (n = 0; n <= numvars; n++) {
- STOREDD(large,n) = STOREDD(i,n);
- }
- if (st_lookup(computed,(char *)&STOREDD(large,0),(char
- **)&index)) {
- repeat[index]++;
- } else {
- if (st_insert(computed,(char *)&STOREDD(large,0),
- (char *)(long)large) == ST_OUT_OF_MEM) {
- FREE(storedd);
- FREE(repeat);
- st_free_table(computed);
- return(0);
- }
- repeat[large]++;
- }
- }
- }
- }
-
- /* Find the smallest DD in the population and build it;
- ** that will be the result.
- */
- small = find_best();
-
- /* Print stats on the final population. */
-#ifdef DD_STATS
- average_fitness = find_average_fitness();
- (void) fprintf(table->out,"\nFinal population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness);
-#endif
-
- /* Clean up, build the result DD, and return. */
- st_free_table(computed);
- computed = NULL;
- result = build_dd(table,small,lower,upper);
- FREE(storedd);
- FREE(repeat);
- return(result);
-
-} /* end of cuddGa */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-/**Function********************************************************************
-
- Synopsis [Generates the random sequences for the initial population.]
-
- Description [Generates the random sequences for the initial population.
- The sequences are permutations of the indices between lower and
- upper in the current order.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-make_random(
- DdManager * table,
- int lower)
-{
- int i,j; /* loop variables */
- int *used; /* is a number already in a permutation */
- int next; /* next random number without repetitions */
-
- used = ALLOC(int,numvars);
- if (used == NULL) {
- table->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
-#if 0
-#ifdef DD_STATS
- (void) fprintf(table->out,"Initial population before sifting\n");
- for (i = 0; i < 2; i++) {
- for (j = 0; j < numvars; j++) {
- (void) fprintf(table->out," %2d",STOREDD(i,j));
- }
- (void) fprintf(table->out,"\n");
- }
-#endif
-#endif
- for (i = 2; i < popsize; i++) {
- for (j = 0; j < numvars; j++) {
- used[j] = 0;
- }
- /* Generate a permutation of {0...numvars-1} and use it to
- ** permute the variables in the layesr from lower to upper.
- */
- for (j = 0; j < numvars; j++) {
- do {
- next = rand_int(numvars-1);
- } while (used[next] != 0);
- used[next] = 1;
- STOREDD(i,j) = table->invperm[next+lower];
- }
-#if 0
-#ifdef DD_STATS
- /* Print the order just generated. */
- for (j = 0; j < numvars; j++) {
- (void) fprintf(table->out," %2d",STOREDD(i,j));
- }
- (void) fprintf(table->out,"\n");
-#endif
-#endif
- }
- FREE(used);
- return(1);
-
-} /* end of make_random */
-
-
-/**Function********************************************************************
-
- Synopsis [Moves one variable up.]
-
- Description [Takes a variable from position x and sifts it up to
- position x_low; x_low should be less than x. Returns 1 if successful;
- 0 otherwise]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-sift_up(
- DdManager * table,
- int x,
- int x_low)
-{
- int y;
- int size;
-
- y = cuddNextLow(table,x);
- while (y >= x_low) {
- size = cuddSwapInPlace(table,y,x);
- if (size == 0) {
- return(0);
- }
- x = y;
- y = cuddNextLow(table,x);
- }
- return(1);
-
-} /* end of sift_up */
-
-
-/**Function********************************************************************
-
- Synopsis [Builds a DD from a given order.]
-
- Description [Builds a DD from a given order. This procedure also
- sifts the final order and inserts into the array the size in nodes
- of the result. Returns 1 if successful; 0 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-build_dd(
- DdManager * table,
- int num /* the index of the individual to be built */,
- int lower,
- int upper)
-{
- int i,j; /* loop vars */
- int position;
- int index;
- int limit; /* how large the DD for this order can grow */
- int size;
-
- /* Check the computed table. If the order already exists, it
- ** suffices to copy the size from the existing entry.
- */
- if (computed && st_lookup(computed,(char *)&STOREDD(num,0),(char **)&index)) {
- STOREDD(num,numvars) = STOREDD(index,numvars);
-#ifdef DD_STATS
- (void) fprintf(table->out,"\nCache hit for index %d", index);
-#endif
- return(1);
- }
-
- /* Stop if the DD grows 20 times larges than the reference size. */
- limit = 20 * STOREDD(0,numvars);
-
- /* Sift up the variables so as to build the desired permutation.
- ** First the variable that has to be on top is sifted to the top.
- ** Then the variable that has to occupy the secon position is sifted
- ** up to the second position, and so on.
- */
- for (j = 0; j < numvars; j++) {
- i = STOREDD(num,j);
- position = table->perm[i];
- result = sift_up(table,position,j+lower);
- if (!result) return(0);
- size = table->keys - table->isolated;
- if (size > limit) break;
- }
-
- /* Sift the DD just built. */
-#ifdef DD_STATS
- (void) fprintf(table->out,"\n");
-#endif
- result = cuddSifting(table,lower,upper);
- if (!result) return(0);
-
- /* Copy order and size to table. */
- for (j = 0; j < numvars; j++) {
- STOREDD(num,j) = table->invperm[lower+j];
- }
- STOREDD(num,numvars) = table->keys - table->isolated; /* size of new DD */
- return(1);
-
-} /* end of build_dd */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the largest DD in the population.]
-
- Description [Finds the largest DD in the population. If an order is
- repeated, it avoids choosing the copy that is in the computed table
- (it has repeat[i] > 1).]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-largest(
- )
-{
- int i; /* loop var */
- int big; /* temporary holder to return result */
-
- big = 0;
- while (repeat[big] > 1) big++;
- for (i = big + 1; i < popsize; i++) {
- if (STOREDD(i,numvars) >= STOREDD(big,numvars) && repeat[i] <= 1) {
- big = i;
- }
- }
- return(big);
-
-} /* end of largest */
-
-
-/**Function********************************************************************
-
- Synopsis [Generates a random number between 0 and the integer a.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-rand_int(
- int a)
-{
- return(Cudd_Random() % (a+1));
-
-} /* end of rand_int */
-
-
-/**Function********************************************************************
-
- Synopsis [Hash function for the computed table.]
-
- Description [Hash function for the computed table. Returns the bucket
- number.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-array_hash(
- char * array,
- int modulus)
-{
- int val = 0;
- int i;
- int *intarray;
-
- intarray = (int *) array;
-
- for (i = 0; i < numvars; i++) {
- val = val * 997 + intarray[i];
- }
-
- return ((val < 0) ? -val : val) % modulus;
-
-} /* end of array_hash */
-
-
-/**Function********************************************************************
-
- Synopsis [Comparison function for the computed table.]
-
- Description [Comparison function for the computed table. Returns 0 if
- the two arrays are equal; 1 otherwise.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-array_compare(
- const char * array1,
- const char * array2)
-{
- int i;
- int *intarray1, *intarray2;
-
- intarray1 = (int *) array1;
- intarray2 = (int *) array2;
-
- for (i = 0; i < numvars; i++) {
- if (intarray1[i] != intarray2[i]) return(1);
- }
- return(0);
-
-} /* end of array_compare */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the index of the fittest individual.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-find_best(
- )
-{
- int i,small;
-
- small = 0;
- for (i = 1; i < popsize; i++) {
- if (STOREDD(i,numvars) < STOREDD(small,numvars)) {
- small = i;
- }
- }
- return(small);
-
-} /* end of find_best */
-
-
-/**Function********************************************************************
-
- Synopsis [Returns the average fitness of the population.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static double
-find_average_fitness(
- )
-{
- int i;
- int total_fitness = 0;
- double average_fitness;
-
- for (i = 0; i < popsize; i++) {
- total_fitness += STOREDD(i,numvars);
- }
- average_fitness = (double) total_fitness / (double) popsize;
- return(average_fitness);
-
-} /* end of find_average_fitness */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the crossover between two parents.]
-
- Description [Performs the crossover between two randomly chosen
- parents, and creates two children, x1 and x2. Uses the Partially
- Matched Crossover operator.]
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-PMX(
- int maxvar)
-{
- int cut1,cut2; /* the two cut positions (random) */
- int mom,dad; /* the two randomly chosen parents */
- int *inv1; /* inverse permutations for repair algo */
- int *inv2;
- int i; /* loop vars */
- int u,v; /* aux vars */
-
- inv1 = ALLOC(int,maxvar);
- if (inv1 == NULL) {
- return(0);
- }
- inv2 = ALLOC(int,maxvar);
- if (inv2 == NULL) {
- FREE(inv1);
- return(0);
- }
-
- /* Choose two orders from the population using roulette wheel. */
- if (!roulette(&mom,&dad)) {
- FREE(inv1);
- FREE(inv2);
- return(0);
- }
-
- /* Choose two random cut positions. A cut in position i means that
- ** the cut immediately precedes position i. If cut1 < cut2, we
- ** exchange the middle of the two orderings; otherwise, we
- ** exchange the beginnings and the ends.
- */
- cut1 = rand_int(numvars-1);
- do {
- cut2 = rand_int(numvars-1);
- } while (cut1 == cut2);
-
-#if 0
- /* Print out the parents. */
- (void) fprintf(table->out,
- "Crossover of %d (mom) and %d (dad) between %d and %d\n",
- mom,dad,cut1,cut2);
- for (i = 0; i < numvars; i++) {
- if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
- (void) fprintf(table->out,"%2d ",STOREDD(mom,i));
- }
- (void) fprintf(table->out,"\n");
- for (i = 0; i < numvars; i++) {
- if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
- (void) fprintf(table->out,"%2d ",STOREDD(dad,i));
- }
- (void) fprintf(table->out,"\n");
-#endif
-
- /* Initialize the inverse permutations: -1 means yet undetermined. */
- for (i = 0; i < maxvar; i++) {
- inv1[i] = -1;
- inv2[i] = -1;
- }
-
- /* Copy the portions whithin the cuts. */
- for (i = cut1; i != cut2; i = (i == numvars-1) ? 0 : i+1) {
- STOREDD(popsize,i) = STOREDD(dad,i);
- inv1[STOREDD(popsize,i)] = i;
- STOREDD(popsize+1,i) = STOREDD(mom,i);
- inv2[STOREDD(popsize+1,i)] = i;
- }
-
- /* Now apply the repair algorithm outside the cuts. */
- for (i = cut2; i != cut1; i = (i == numvars-1 ) ? 0 : i+1) {
- v = i;
- do {
- u = STOREDD(mom,v);
- v = inv1[u];
- } while (v != -1);
- STOREDD(popsize,i) = u;
- inv1[u] = i;
- v = i;
- do {
- u = STOREDD(dad,v);
- v = inv2[u];
- } while (v != -1);
- STOREDD(popsize+1,i) = u;
- inv2[u] = i;
- }
-
-#if 0
- /* Print the results of crossover. */
- for (i = 0; i < numvars; i++) {
- if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
- (void) fprintf(table->out,"%2d ",STOREDD(popsize,i));
- }
- (void) fprintf(table->out,"\n");
- for (i = 0; i < numvars; i++) {
- if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
- (void) fprintf(table->out,"%2d ",STOREDD(popsize+1,i));
- }
- (void) fprintf(table->out,"\n");
-#endif
-
- FREE(inv1);
- FREE(inv2);
- return(1);
-
-} /* end of PMX */
-
-
-/**Function********************************************************************
-
- Synopsis [Selects two parents with the roulette wheel method.]
-
- Description [Selects two distinct parents with the roulette wheel method.]
-
- SideEffects [The indices of the selected parents are returned as side
- effects.]
-
- SeeAlso []
-
-******************************************************************************/
-static int
-roulette(
- int * p1,
- int * p2)
-{
- double *wheel;
- double spin;
- int i;
-
- wheel = ALLOC(double,popsize);
- if (wheel == NULL) {
- return(0);
- }
-
- /* The fitness of an individual is the reciprocal of its size. */
- wheel[0] = 1.0 / (double) STOREDD(0,numvars);
-
- for (i = 1; i < popsize; i++) {
- wheel[i] = wheel[i-1] + 1.0 / (double) STOREDD(i,numvars);
- }
-
- /* Get a random number between 0 and wheel[popsize-1] (that is,
- ** the sum of all fitness values. 2147483561 is the largest number
- ** returned by Cudd_Random.
- */
- spin = wheel[numvars-1] * (double) Cudd_Random() / 2147483561.0;
-
- /* Find the lucky element by scanning the wheel. */
- for (i = 0; i < popsize; i++) {
- if (spin <= wheel[i]) break;
- }
- *p1 = i;
-
- /* Repeat the process for the second parent, making sure it is
- ** distinct from the first.
- */
- do {
- spin = wheel[popsize-1] * (double) Cudd_Random() / 2147483561.0;
- for (i = 0; i < popsize; i++) {
- if (spin <= wheel[i]) break;
- }
- } while (i == *p1);
- *p2 = i;
-
- FREE(wheel);
- return(1);
-
-} /* end of roulette */
-