SVF
cuddGenetic.c
Go to the documentation of this file.
1 
83 #include "CUDD/util.h"
84 #include "CUDD/cuddInt.h"
85 
86 /*---------------------------------------------------------------------------*/
87 /* Constant declarations */
88 /*---------------------------------------------------------------------------*/
89 
90 /*---------------------------------------------------------------------------*/
91 /* Stucture declarations */
92 /*---------------------------------------------------------------------------*/
93 
94 /*---------------------------------------------------------------------------*/
95 /* Type declarations */
96 /*---------------------------------------------------------------------------*/
97 
98 /*---------------------------------------------------------------------------*/
99 /* Variable declarations */
100 /*---------------------------------------------------------------------------*/
101 
102 #ifndef lint
103 static char rcsid[] DD_UNUSED = "$Id: cuddGenetic.c,v 1.30 2012/02/05 01:07:18 fabio Exp $";
104 #endif
105 
106 static int popsize; /* the size of the population */
107 static int numvars; /* the number of input variables in the ckt. */
108 /* storedd stores the population orders and sizes. This table has two
109 ** extra rows and one extras column. The two extra rows are used for the
110 ** offspring produced by a crossover. Each row stores one order and its
111 ** size. The order is stored by storing the indices of variables in the
112 ** order in which they appear in the order. The table is in reality a
113 ** one-dimensional array which is accessed via a macro to give the illusion
114 ** it is a two-dimensional structure.
115 */
116 static int *storedd;
117 static st_table *computed; /* hash table to identify existing orders */
118 static int *repeat; /* how many times an order is present */
119 static int large; /* stores the index of the population with
120  ** the largest number of nodes in the DD */
121 static int result;
122 static int cross; /* the number of crossovers to perform */
123 
124 /*---------------------------------------------------------------------------*/
125 /* Macro declarations */
126 /*---------------------------------------------------------------------------*/
127 
128 /* macro used to access the population table as if it were a
129 ** two-dimensional structure.
130 */
131 #define STOREDD(i,j) storedd[(i)*(numvars+1)+(j)]
132 
133 #ifdef __cplusplus
134 extern "C" {
135 #endif
136 
139 /*---------------------------------------------------------------------------*/
140 /* Static function prototypes */
141 /*---------------------------------------------------------------------------*/
142 
143 static int make_random (DdManager *table, int lower);
144 static int sift_up (DdManager *table, int x, int x_low);
145 static int build_dd (DdManager *table, int num, int lower, int upper);
146 static int largest (void);
147 static int rand_int (int a);
148 static int array_hash (char *array, int modulus);
149 static int array_compare (const char *array1, const char *array2);
150 static int find_best (void);
151 #ifdef DD_STATS
152 static double find_average_fitness (void);
153 #endif
154 static int PMX (int maxvar);
155 static int roulette (int *p1, int *p2);
156 
159 #ifdef __cplusplus
160 }
161 #endif
162 
163 /*---------------------------------------------------------------------------*/
164 /* Definition of exported functions */
165 /*---------------------------------------------------------------------------*/
166 
167 /*---------------------------------------------------------------------------*/
168 /* Definition of internal functions */
169 /*---------------------------------------------------------------------------*/
170 
171 
187 int
189  DdManager * table /* manager */,
190  int lower /* lowest level to be reordered */,
191  int upper /* highest level to be reorderded */)
192 {
193  int i,n,m; /* dummy/loop vars */
194  int index;
195 #ifdef DD_STATS
196  double average_fitness;
197 #endif
198  int small; /* index of smallest DD in population */
199 
200  /* Do an initial sifting to produce at least one reasonable individual. */
201  if (!cuddSifting(table,lower,upper)) return(0);
202 
203  /* Get the initial values. */
204  numvars = upper - lower + 1; /* number of variables to be reordered */
205  if (table->populationSize == 0) {
206  popsize = 3 * numvars; /* population size is 3 times # of vars */
207  if (popsize > 120) {
208  popsize = 120; /* Maximum population size is 120 */
209  }
210  } else {
211  popsize = table->populationSize; /* user specified value */
212  }
213  if (popsize < 4) popsize = 4; /* enforce minimum population size */
214 
215  /* Allocate population table. */
216  storedd = ALLOC(int,(popsize+2)*(numvars+1));
217  if (storedd == NULL) {
218  table->errorCode = CUDD_MEMORY_OUT;
219  return(0);
220  }
221 
222  /* Initialize the computed table. This table is made up of two data
223  ** structures: A hash table with the key given by the order, which says
224  ** if a given order is present in the population; and the repeat
225  ** vector, which says how many copies of a given order are stored in
226  ** the population table. If there are multiple copies of an order, only
227  ** one has a repeat count greater than 1. This copy is the one pointed
228  ** by the computed table.
229  */
230  repeat = ALLOC(int,popsize);
231  if (repeat == NULL) {
232  table->errorCode = CUDD_MEMORY_OUT;
233  FREE(storedd);
234  return(0);
235  }
236  for (i = 0; i < popsize; i++) {
237  repeat[i] = 0;
238  }
240  if (computed == NULL) {
241  table->errorCode = CUDD_MEMORY_OUT;
242  FREE(storedd);
243  FREE(repeat);
244  return(0);
245  }
246 
247  /* Copy the current DD and its size to the population table. */
248  for (i = 0; i < numvars; i++) {
249  STOREDD(0,i) = table->invperm[i+lower]; /* order of initial DD */
250  }
251  STOREDD(0,numvars) = table->keys - table->isolated; /* size of initial DD */
252 
253  /* Store the initial order in the computed table. */
254  if (st_insert(computed,(char *)storedd,(char *) 0) == ST_OUT_OF_MEM) {
255  FREE(storedd);
256  FREE(repeat);
257  st_free_table(computed);
258  return(0);
259  }
260  repeat[0]++;
261 
262  /* Insert the reverse order as second element of the population. */
263  for (i = 0; i < numvars; i++) {
264  STOREDD(1,numvars-1-i) = table->invperm[i+lower]; /* reverse order */
265  }
266 
267  /* Now create the random orders. make_random fills the population
268  ** table with random permutations. The successive loop builds and sifts
269  ** the DDs for the reverse order and each random permutation, and stores
270  ** the results in the computed table.
271  */
272  if (!make_random(table,lower)) {
273  table->errorCode = CUDD_MEMORY_OUT;
274  FREE(storedd);
275  FREE(repeat);
276  st_free_table(computed);
277  return(0);
278  }
279  for (i = 1; i < popsize; i++) {
280  result = build_dd(table,i,lower,upper); /* build and sift order */
281  if (!result) {
282  FREE(storedd);
283  FREE(repeat);
284  st_free_table(computed);
285  return(0);
286  }
287  if (st_lookup_int(computed,(char *)&STOREDD(i,0),&index)) {
288  repeat[index]++;
289  } else {
290  if (st_insert(computed,(char *)&STOREDD(i,0),(char *)(long)i) ==
291  ST_OUT_OF_MEM) {
292  FREE(storedd);
293  FREE(repeat);
294  st_free_table(computed);
295  return(0);
296  }
297  repeat[i]++;
298  }
299  }
300 
301 #if 0
302 #ifdef DD_STATS
303  /* Print the initial population. */
304  (void) fprintf(table->out,"Initial population after sifting\n");
305  for (m = 0; m < popsize; m++) {
306  for (i = 0; i < numvars; i++) {
307  (void) fprintf(table->out," %2d",STOREDD(m,i));
308  }
309  (void) fprintf(table->out," : %3d (%d)\n",
310  STOREDD(m,numvars),repeat[m]);
311  }
312 #endif
313 #endif
314 
315  small = find_best();
316 #ifdef DD_STATS
317  average_fitness = find_average_fitness();
318  (void) fprintf(table->out,"\nInitial population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness);
319 #endif
320 
321  /* Decide how many crossovers should be tried. */
322  if (table->numberXovers == 0) {
323  cross = 3*numvars;
324  if (cross > 60) { /* do a maximum of 50 crossovers */
325  cross = 60;
326  }
327  } else {
328  cross = table->numberXovers; /* use user specified value */
329  }
330  if (cross >= popsize) {
331  cross = popsize;
332  }
333 
334  /* Perform the crossovers to get the best order. */
335  for (m = 0; m < cross; m++) {
336  if (!PMX(table->size)) { /* perform one crossover */
337  table->errorCode = CUDD_MEMORY_OUT;
338  FREE(storedd);
339  FREE(repeat);
340  st_free_table(computed);
341  return(0);
342  }
343  /* The offsprings are left in the last two entries of the
344  ** population table. These are now considered in turn.
345  */
346  for (i = popsize; i <= popsize+1; i++) {
347  result = build_dd(table,i,lower,upper); /* build and sift child */
348  if (!result) {
349  FREE(storedd);
350  FREE(repeat);
351  st_free_table(computed);
352  return(0);
353  }
354  large = largest(); /* find the largest DD in population */
355 
356  /* If the new child is smaller than the largest DD in the current
357  ** population, enter it into the population in place of the
358  ** largest DD.
359  */
360  if (STOREDD(i,numvars) < STOREDD(large,numvars)) {
361  /* Look up the largest DD in the computed table.
362  ** Decrease its repetition count. If the repetition count
363  ** goes to 0, remove the largest DD from the computed table.
364  */
365  result = st_lookup_int(computed,(char *)&STOREDD(large,0),
366  &index);
367  if (!result) {
368  FREE(storedd);
369  FREE(repeat);
370  st_free_table(computed);
371  return(0);
372  }
373  repeat[index]--;
374  if (repeat[index] == 0) {
375  int *pointer = &STOREDD(index,0);
376  result = st_delete(computed, &pointer, NULL);
377  if (!result) {
378  FREE(storedd);
379  FREE(repeat);
380  st_free_table(computed);
381  return(0);
382  }
383  }
384  /* Copy the new individual to the entry of the
385  ** population table just made available and update the
386  ** computed table.
387  */
388  for (n = 0; n <= numvars; n++) {
389  STOREDD(large,n) = STOREDD(i,n);
390  }
391  if (st_lookup_int(computed,(char *)&STOREDD(large,0),
392  &index)) {
393  repeat[index]++;
394  } else {
395  if (st_insert(computed,(char *)&STOREDD(large,0),
396  (char *)(long)large) == ST_OUT_OF_MEM) {
397  FREE(storedd);
398  FREE(repeat);
399  st_free_table(computed);
400  return(0);
401  }
402  repeat[large]++;
403  }
404  }
405  }
406  }
407 
408  /* Find the smallest DD in the population and build it;
409  ** that will be the result.
410  */
411  small = find_best();
412 
413  /* Print stats on the final population. */
414 #ifdef DD_STATS
415  average_fitness = find_average_fitness();
416  (void) fprintf(table->out,"\nFinal population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness);
417 #endif
418 
419  /* Clean up, build the result DD, and return. */
420  st_free_table(computed);
421  computed = NULL;
422  result = build_dd(table,small,lower,upper);
423  FREE(storedd);
424  FREE(repeat);
425  return(result);
426 
427 } /* end of cuddGa */
428 
429 
430 /*---------------------------------------------------------------------------*/
431 /* Definition of static functions */
432 /*---------------------------------------------------------------------------*/
433 
447 static int
449  DdManager * table,
450  int lower)
451 {
452  int i,j; /* loop variables */
453  int *used; /* is a number already in a permutation */
454  int next; /* next random number without repetitions */
455 
456  used = ALLOC(int,numvars);
457  if (used == NULL) {
458  table->errorCode = CUDD_MEMORY_OUT;
459  return(0);
460  }
461 #if 0
462 #ifdef DD_STATS
463  (void) fprintf(table->out,"Initial population before sifting\n");
464  for (i = 0; i < 2; i++) {
465  for (j = 0; j < numvars; j++) {
466  (void) fprintf(table->out," %2d",STOREDD(i,j));
467  }
468  (void) fprintf(table->out,"\n");
469  }
470 #endif
471 #endif
472  for (i = 2; i < popsize; i++) {
473  for (j = 0; j < numvars; j++) {
474  used[j] = 0;
475  }
476  /* Generate a permutation of {0...numvars-1} and use it to
477  ** permute the variables in the layesr from lower to upper.
478  */
479  for (j = 0; j < numvars; j++) {
480  do {
481  next = rand_int(numvars-1);
482  } while (used[next] != 0);
483  used[next] = 1;
484  STOREDD(i,j) = table->invperm[next+lower];
485  }
486 #if 0
487 #ifdef DD_STATS
488  /* Print the order just generated. */
489  for (j = 0; j < numvars; j++) {
490  (void) fprintf(table->out," %2d",STOREDD(i,j));
491  }
492  (void) fprintf(table->out,"\n");
493 #endif
494 #endif
495  }
496  FREE(used);
497  return(1);
498 
499 } /* end of make_random */
500 
501 
515 static int
517  DdManager * table,
518  int x,
519  int x_low)
520 {
521  int y;
522  int size;
523 
524  y = cuddNextLow(table,x);
525  while (y >= x_low) {
526  size = cuddSwapInPlace(table,y,x);
527  if (size == 0) {
528  return(0);
529  }
530  x = y;
531  y = cuddNextLow(table,x);
532  }
533  return(1);
534 
535 } /* end of sift_up */
536 
537 
551 static int
553  DdManager * table,
554  int num /* the index of the individual to be built */,
555  int lower,
556  int upper)
557 {
558  int i,j; /* loop vars */
559  int position;
560  int index;
561  int limit; /* how large the DD for this order can grow */
562  int size;
563 
564  /* Check the computed table. If the order already exists, it
565  ** suffices to copy the size from the existing entry.
566  */
567  if (computed && st_lookup_int(computed,(char *)&STOREDD(num,0),&index)) {
568  STOREDD(num,numvars) = STOREDD(index,numvars);
569 #ifdef DD_STATS
570  (void) fprintf(table->out,"\nCache hit for index %d", index);
571 #endif
572  return(1);
573  }
574 
575  /* Stop if the DD grows 20 times larges than the reference size. */
576  limit = 20 * STOREDD(0,numvars);
577 
578  /* Sift up the variables so as to build the desired permutation.
579  ** First the variable that has to be on top is sifted to the top.
580  ** Then the variable that has to occupy the secon position is sifted
581  ** up to the second position, and so on.
582  */
583  for (j = 0; j < numvars; j++) {
584  i = STOREDD(num,j);
585  position = table->perm[i];
586  result = sift_up(table,position,j+lower);
587  if (!result) return(0);
588  size = table->keys - table->isolated;
589  if (size > limit) break;
590  }
591 
592  /* Sift the DD just built. */
593 #ifdef DD_STATS
594  (void) fprintf(table->out,"\n");
595 #endif
596  result = cuddSifting(table,lower,upper);
597  if (!result) return(0);
598 
599  /* Copy order and size to table. */
600  for (j = 0; j < numvars; j++) {
601  STOREDD(num,j) = table->invperm[lower+j];
602  }
603  STOREDD(num,numvars) = table->keys - table->isolated; /* size of new DD */
604  return(1);
605 
606 } /* end of build_dd */
607 
608 
622 static int
623 largest(void)
624 {
625  int i; /* loop var */
626  int big; /* temporary holder to return result */
627 
628  big = 0;
629  while (repeat[big] > 1) big++;
630  for (i = big + 1; i < popsize; i++) {
631  if (STOREDD(i,numvars) >= STOREDD(big,numvars) && repeat[i] <= 1) {
632  big = i;
633  }
634  }
635  return(big);
636 
637 } /* end of largest */
638 
639 
651 static int
653  int a)
654 {
655  return(Cudd_Random() % (a+1));
656 
657 } /* end of rand_int */
658 
659 
672 static int
674  char * array,
675  int modulus)
676 {
677  int val = 0;
678  int i;
679  int *intarray;
680 
681  intarray = (int *) array;
682 
683  for (i = 0; i < numvars; i++) {
684  val = val * 997 + intarray[i];
685  }
686 
687  return ((val < 0) ? -val : val) % modulus;
688 
689 } /* end of array_hash */
690 
691 
704 static int
706  const char * array1,
707  const char * array2)
708 {
709  int i;
710  int *intarray1, *intarray2;
711 
712  intarray1 = (int *) array1;
713  intarray2 = (int *) array2;
714 
715  for (i = 0; i < numvars; i++) {
716  if (intarray1[i] != intarray2[i]) return(1);
717  }
718  return(0);
719 
720 } /* end of array_compare */
721 
722 
734 static int
736 {
737  int i,small;
738 
739  small = 0;
740  for (i = 1; i < popsize; i++) {
741  if (STOREDD(i,numvars) < STOREDD(small,numvars)) {
742  small = i;
743  }
744  }
745  return(small);
746 
747 } /* end of find_best */
748 
749 
761 #ifdef DD_STATS
762 static double
763 find_average_fitness(void)
764 {
765  int i;
766  int total_fitness = 0;
767  double average_fitness;
768 
769  for (i = 0; i < popsize; i++) {
770  total_fitness += STOREDD(i,numvars);
771  }
772  average_fitness = (double) total_fitness / (double) popsize;
773  return(average_fitness);
774 
775 } /* end of find_average_fitness */
776 #endif
777 
778 
792 static int
794  int maxvar)
795 {
796  int cut1,cut2; /* the two cut positions (random) */
797  int mom,dad; /* the two randomly chosen parents */
798  int *inv1; /* inverse permutations for repair algo */
799  int *inv2;
800  int i; /* loop vars */
801  int u,v; /* aux vars */
802 
803  inv1 = ALLOC(int,maxvar);
804  if (inv1 == NULL) {
805  return(0);
806  }
807  inv2 = ALLOC(int,maxvar);
808  if (inv2 == NULL) {
809  FREE(inv1);
810  return(0);
811  }
812 
813  /* Choose two orders from the population using roulette wheel. */
814  if (!roulette(&mom,&dad)) {
815  FREE(inv1);
816  FREE(inv2);
817  return(0);
818  }
819 
820  /* Choose two random cut positions. A cut in position i means that
821  ** the cut immediately precedes position i. If cut1 < cut2, we
822  ** exchange the middle of the two orderings; otherwise, we
823  ** exchange the beginnings and the ends.
824  */
825  cut1 = rand_int(numvars-1);
826  do {
827  cut2 = rand_int(numvars-1);
828  } while (cut1 == cut2);
829 
830 #if 0
831  /* Print out the parents. */
832  (void) fprintf(table->out,
833  "Crossover of %d (mom) and %d (dad) between %d and %d\n",
834  mom,dad,cut1,cut2);
835  for (i = 0; i < numvars; i++) {
836  if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
837  (void) fprintf(table->out,"%2d ",STOREDD(mom,i));
838  }
839  (void) fprintf(table->out,"\n");
840  for (i = 0; i < numvars; i++) {
841  if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
842  (void) fprintf(table->out,"%2d ",STOREDD(dad,i));
843  }
844  (void) fprintf(table->out,"\n");
845 #endif
846 
847  /* Initialize the inverse permutations: -1 means yet undetermined. */
848  for (i = 0; i < maxvar; i++) {
849  inv1[i] = -1;
850  inv2[i] = -1;
851  }
852 
853  /* Copy the portions whithin the cuts. */
854  for (i = cut1; i != cut2; i = (i == numvars-1) ? 0 : i+1) {
855  STOREDD(popsize,i) = STOREDD(dad,i);
856  inv1[STOREDD(popsize,i)] = i;
857  STOREDD(popsize+1,i) = STOREDD(mom,i);
858  inv2[STOREDD(popsize+1,i)] = i;
859  }
860 
861  /* Now apply the repair algorithm outside the cuts. */
862  for (i = cut2; i != cut1; i = (i == numvars-1 ) ? 0 : i+1) {
863  v = i;
864  do {
865  u = STOREDD(mom,v);
866  v = inv1[u];
867  } while (v != -1);
868  STOREDD(popsize,i) = u;
869  inv1[u] = i;
870  v = i;
871  do {
872  u = STOREDD(dad,v);
873  v = inv2[u];
874  } while (v != -1);
875  STOREDD(popsize+1,i) = u;
876  inv2[u] = i;
877  }
878 
879 #if 0
880  /* Print the results of crossover. */
881  for (i = 0; i < numvars; i++) {
882  if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
883  (void) fprintf(table->out,"%2d ",STOREDD(popsize,i));
884  }
885  (void) fprintf(table->out,"\n");
886  for (i = 0; i < numvars; i++) {
887  if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
888  (void) fprintf(table->out,"%2d ",STOREDD(popsize+1,i));
889  }
890  (void) fprintf(table->out,"\n");
891 #endif
892 
893  FREE(inv1);
894  FREE(inv2);
895  return(1);
896 
897 } /* end of PMX */
898 
899 
912 static int
914  int * p1,
915  int * p2)
916 {
917  double *wheel;
918  double spin;
919  int i;
920 
921  wheel = ALLOC(double,popsize);
922  if (wheel == NULL) {
923  return(0);
924  }
925 
926  /* The fitness of an individual is the reciprocal of its size. */
927  wheel[0] = 1.0 / (double) STOREDD(0,numvars);
928 
929  for (i = 1; i < popsize; i++) {
930  wheel[i] = wheel[i-1] + 1.0 / (double) STOREDD(i,numvars);
931  }
932 
933  /* Get a random number between 0 and wheel[popsize-1] (that is,
934  ** the sum of all fitness values. 2147483561 is the largest number
935  ** returned by Cudd_Random.
936  */
937  spin = wheel[numvars-1] * (double) Cudd_Random() / 2147483561.0;
938 
939  /* Find the lucky element by scanning the wheel. */
940  for (i = 0; i < popsize; i++) {
941  if (spin <= wheel[i]) break;
942  }
943  *p1 = i;
944 
945  /* Repeat the process for the second parent, making sure it is
946  ** distinct from the first.
947  */
948  do {
949  spin = wheel[popsize-1] * (double) Cudd_Random() / 2147483561.0;
950  for (i = 0; i < popsize; i++) {
951  if (spin <= wheel[i]) break;
952  }
953  } while (i == *p1);
954  *p2 = i;
955 
956  FREE(wheel);
957  return(1);
958 
959 } /* end of roulette */
960 
static int large
Definition: cuddGenetic.c:119
Definition: st.h:60
static int sift_up(DdManager *table, int x, int x_low)
Definition: cuddGenetic.c:516
int st_lookup_int(st_table *, void *, int *)
Definition: st.c:322
#define FREE(obj)
Definition: util.h:80
static int * storedd
Definition: cuddGenetic.c:116
int size
Definition: cuddInt.h:345
void st_free_table(st_table *)
Definition: st.c:252
static int roulette(int *p1, int *p2)
Definition: cuddGenetic.c:913
int cuddNextLow(DdManager *table, int x)
Definition: cuddReorder.c:737
int cuddSifting(DdManager *table, int lower, int upper)
Definition: cuddReorder.c:502
int populationSize
Definition: cuddInt.h:414
int cuddGa(DdManager *table, int lower, int upper)
Definition: cuddGenetic.c:188
static st_table * computed
Definition: cuddGenetic.c:117
int st_insert(st_table *, void *, void *)
Definition: st.c:358
static int array_hash(char *array, int modulus)
Definition: cuddGenetic.c:673
static int cross
Definition: cuddGenetic.c:122
long Cudd_Random(void)
Definition: cuddUtil.c:2710
static int find_best(void)
Definition: cuddGenetic.c:735
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
static int build_dd(DdManager *table, int num, int lower, int upper)
Definition: cuddGenetic.c:552
FILE * out
Definition: cuddInt.h:423
static int numvars
Definition: cuddGenetic.c:107
static int array_compare(const char *array1, const char *array2)
Definition: cuddGenetic.c:705
int numberXovers
Definition: cuddInt.h:415
static int popsize
Definition: cuddGenetic.c:106
st_table * st_init_table(ST_PFICPCP, ST_PFICPI)
Definition: st.c:163
static int largest(void)
Definition: cuddGenetic.c:623
#define ST_OUT_OF_MEM
Definition: st.h:41
int st_delete(st_table *, void *, void *)
Definition: st.c:634
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddReorder.c:760
static int * repeat
Definition: cuddGenetic.c:118
static int rand_int(int a)
Definition: cuddGenetic.c:652
int * invperm
Definition: cuddInt.h:371
static int result
Definition: cuddGenetic.c:121
int isolated
Definition: cuddInt.h:368
#define STOREDD(i, j)
Definition: cuddGenetic.c:131
int * perm
Definition: cuddInt.h:369
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
static int make_random(DdManager *table, int lower)
Definition: cuddGenetic.c:448
static int PMX(int maxvar)
Definition: cuddGenetic.c:793
static char rcsid [] DD_UNUSED
Definition: cuddGenetic.c:103