/**Function******************************************************************** Synopsis [Implementation of Rudell's sifting algorithm.] Description [Implementation of Rudell's sifting algorithm. Assumes that no dead nodes are present. <ol> <li> Order all the variables according to the number of entries in each unique table. <li> Sift the variable up and down, remembering each time the total size of the DD heap. <li> Select the best permutation. <li> Repeat 3 and 4 for all variables. </ol> Returns 1 if successful; 0 otherwise.] SideEffects [None] SeeAlso [] ******************************************************************************/ int cuddZddSifting( DdManager * table, int lower, int upper) { int i; int *var; int size; int x; int result; #ifdef DD_STATS int previousSize; #endif size = table->sizeZ; /* Find order in which to sift variables. */ var = NULL; zdd_entry = ALLOC(int, size); if (zdd_entry == NULL) { table->errorCode = CUDD_MEMORY_OUT; goto cuddZddSiftingOutOfMem; } var = ALLOC(int, size); if (var == NULL) { table->errorCode = CUDD_MEMORY_OUT; goto cuddZddSiftingOutOfMem; } for (i = 0; i < size; i++) { x = table->permZ[i]; zdd_entry[i] = table->subtableZ[x].keys; var[i] = i; } qsort((void *)var, size, sizeof(int), (int (*)(const void *, const void *))cuddZddUniqueCompare); /* Now sift. */ for (i = 0; i < ddMin(table->siftMaxVar, size); i++) { if (zddTotalNumberSwapping >= table->siftMaxSwap) break; x = table->permZ[var[i]]; if (x < lower || x > upper) continue; #ifdef DD_STATS previousSize = table->keysZ; #endif result = cuddZddSiftingAux(table, x, lower, upper); if (!result) goto cuddZddSiftingOutOfMem; #ifdef DD_STATS if (table->keysZ < (unsigned) previousSize) { (void) fprintf(table->out,"-"); } else if (table->keysZ > (unsigned) previousSize) { (void) fprintf(table->out,"+"); /* should never happen */ (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]); } else { (void) fprintf(table->out,"="); } fflush(table->out); #endif } FREE(var); FREE(zdd_entry); return(1); cuddZddSiftingOutOfMem: if (zdd_entry != NULL) FREE(zdd_entry); if (var != NULL) FREE(var); return(0); } /* end of cuddZddSifting */
/** @brief Implementation of Rudell's sifting algorithm. @details Assumes that no dead nodes are present. <ol> <li> Order all the variables according to the number of entries in each unique table. <li> Sift the variable up and down, remembering each time the total size of the %DD heap. <li> Select the best permutation. <li> Repeat 3 and 4 for all variables. </ol> @return 1 if successful; 0 otherwise. @sideeffect None */ int cuddZddSifting( DdManager * table, int lower, int upper) { int i; IndexKey *var; int size; int x; int result; #ifdef DD_STATS int previousSize; #endif size = table->sizeZ; /* Find order in which to sift variables. */ var = ALLOC(IndexKey, size); if (var == NULL) { table->errorCode = CUDD_MEMORY_OUT; goto cuddZddSiftingOutOfMem; } for (i = 0; i < size; i++) { x = table->permZ[i]; var[i].index = i; var[i].keys = table->subtableZ[x].keys; } util_qsort(var, size, sizeof(IndexKey), cuddZddUniqueCompare); /* Now sift. */ for (i = 0; i < ddMin(table->siftMaxVar, size); i++) { if (table->zddTotalNumberSwapping >= table->siftMaxSwap) break; if (util_cpu_time() - table->startTime > table->timeLimit) { table->autoDynZ = 0; /* prevent further reordering */ break; } if (table->terminationCallback != NULL && table->terminationCallback(table->tcbArg)) { table->autoDynZ = 0; /* prevent further reordering */ break; } x = table->permZ[var[i].index]; if (x < lower || x > upper) continue; #ifdef DD_STATS previousSize = table->keysZ; #endif result = cuddZddSiftingAux(table, x, lower, upper); if (!result) goto cuddZddSiftingOutOfMem; #ifdef DD_STATS if (table->keysZ < (unsigned) previousSize) { (void) fprintf(table->out,"-"); } else if (table->keysZ > (unsigned) previousSize) { (void) fprintf(table->out,"+"); /* should never happen */ (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i].index); } else { (void) fprintf(table->out,"="); } fflush(table->out); #endif } FREE(var); return(1); cuddZddSiftingOutOfMem: if (var != NULL) FREE(var); return(0); } /* end of cuddZddSifting */