91 static char rcsid[]
DD_UNUSED =
"$Id: cuddExact.c,v 1.30 2012/02/05 01:07:18 fabio Exp $";
95 static int ddTotalShuffles;
155 int maxBinomial, oldSubsets, newSubsets;
158 int unused, nvars, level,
result;
159 int upperBound, lowerBound, cost;
185 if (lower == upper)
return(1);
190 if (result == 0)
goto cuddExactOutOfMem;
193 (void) fprintf(table->
out,
"\n");
200 size = upper - lower + 1;
204 for (i = lower + 1; i < upper; i++) {
212 if (maxBinomial == -1)
goto cuddExactOutOfMem;
215 if (newOrder == NULL)
goto cuddExactOutOfMem;
217 newCost =
ALLOC(
int, maxBinomial);
218 if (newCost == NULL)
goto cuddExactOutOfMem;
221 if (oldOrder == NULL)
goto cuddExactOutOfMem;
223 oldCost =
ALLOC(
int, maxBinomial);
224 if (oldCost == NULL)
goto cuddExactOutOfMem;
227 if (bestOrder == NULL)
goto cuddExactOutOfMem;
229 mask =
ALLOC(
char, nvars);
230 if (mask == NULL)
goto cuddExactOutOfMem;
233 if (symmInfo == NULL)
goto cuddExactOutOfMem;
243 for (i = 0; i < size; i++) {
247 for (i = upper + 1; i < nvars; i++)
249 oldCost[0] = subsetCost;
254 for (k = 1; k <= size; k++) {
256 (void) fprintf(table->
out,
"Processing subsets of size %d\n", k);
262 for (i = 0; i < oldSubsets; i++) {
265 lowerBound =
computeLB(table, order, roots, cost, lower, upper,
267 if (lowerBound >= upperBound)
270 result =
ddShuffle(table, order, lower, upper);
271 if (result == 0)
goto cuddExactOutOfMem;
272 upperBound =
updateUB(table,upperBound,bestOrder,lower,upper);
274 for (j = level; j >= 0; j--) {
280 newSubsets =
updateEntry(table, order, level, subsetCost,
281 newOrder, newCost, newSubsets, mask,
289 result =
ddShuffle(table, order, lower, upper);
290 if (result == 0)
goto cuddExactOutOfMem;
291 upperBound =
updateUB(table,upperBound,bestOrder,lower,upper);
296 tmpOrder = oldOrder; tmpCost = oldCost;
297 oldOrder = newOrder; oldCost = newCost;
298 newOrder = tmpOrder; newCost = tmpCost;
300 ddTotalSubsets += newSubsets;
302 oldSubsets = newSubsets;
304 result =
ddShuffle(table, bestOrder, lower, upper);
305 if (result == 0)
goto cuddExactOutOfMem;
308 (void) fprintf(table->
out,
"\n");
310 (void) fprintf(table->
out,
"#:S_EXACT %8d: total subsets\n",
312 (void) fprintf(table->
out,
"#:H_EXACT %8d: total shuffles",
329 if (bestOrder != NULL)
FREE(bestOrder);
330 if (oldCost != NULL)
FREE(oldCost);
331 if (newCost != NULL)
FREE(newCost);
332 if (symmInfo != NULL)
FREE(symmInfo);
333 if (mask != NULL)
FREE(mask);
364 if (n < 0 || n > 33)
return(-1);
365 if (n < 2)
return(1);
367 for (result = (
double)((n+3)/2), i = result+1, j=2; i <= n; i++, j++) {
400 if (x == 0)
return(y);
401 if (y == 0)
return(x);
403 a = x; b = y; lsbMask = 1;
454 if (cols*rows == 0)
return(NULL);
456 if (matrix == NULL)
return(NULL);
458 if (matrix[0] == NULL) {
462 for (i = 1; i < rows; i++) {
463 matrix[i] = matrix[i-1] + cols;
513 isolated = table->
vars[x]->
ref == 1;
551 unsigned long localTime;
565 numvars = table->
size;
567 (void) fprintf(table->
out,
"%d:", ddTotalShuffles);
568 for (level = 0; level <
numvars; level++) {
569 (void) fprintf(table->
out,
" %d", table->
invperm[level]);
571 (void) fprintf(table->
out,
"\n");
574 for (level = 0; level <= upper - lower; level++) {
575 index = permutation[level];
576 position = table->
perm[index];
580 result =
ddSiftUp(table,position,level+lower);
581 if (!result)
return(0);
588 if (finalSize < initialSize) {
589 (void) fprintf(table->
out,
"-");
590 }
else if (finalSize > initialSize) {
591 (void) fprintf(table->
out,
"+");
593 (void) fprintf(table->
out,
"=");
595 if ((ddTotalShuffles & 63) == 0) (
void) fprintf(table->
out,
"\n");
664 if (newBound < oldBound) {
666 (void) fprintf(table->
out,
"New upper bound = %d\n", newBound);
669 for (i = lower; i <= upper; i++)
707 int maxlevel = lower;
709 for (i = lower; i <= upper; i++) {
712 for (j = 0; j < slots; j++) {
714 while (f != sentinel) {
728 if (table->
perm[
cuddT(f)->index] > maxlevel)
774 for (i = lower; i <= maxlevel; i++) {
777 for (j = 0; j < slots; j++) {
779 while (f != sentinel) {
829 for (i = 0; i < lower; i++) {
835 for (i = lower; i <= lower+level; i++) {
837 table->
vars[order[i-lower]]->
ref > 1;
843 if (lower+level+1 < table->
size) {
844 if (lower+level < upper)
845 ref = table->
vars[order[level+1]]->
ref;
854 lb += lb1 > lb2 ? lb1 : lb2;
889 int size = upper - lower + 1;
892 for (i = lower; i <= upper; i++)
894 for (i = level; i < size; i++)
898 for (i = 0; i < subsets; i++) {
900 for (j = level; j < size; j++) {
901 if (mask[subset[j]] == 0)
907 if (i == subsets || cost < costs[i]) {
908 for (j = 0; j < size; j++)
909 orders[i][j] = order[j];
911 subsets += (i == subsets);
939 for (i = j; i < level; i++) {
940 order[i] = order[i+1];
973 int level, index, next, nextindex;
977 if (symmInfo == NULL)
return(NULL);
979 for (level = lower; level <= upper; level++) {
982 nextindex = table->
invperm[next];
983 symmInfo[index] = nextindex;
1012 i = symmInfo[index];
1013 while (i != index) {
1014 if (index < i && table->perm[i] <= level)
int cuddExact(DdManager *table, int lower, int upper)
unsigned short DdHalfWord
static int ddShuffle(DdManager *table, DdHalfWord *permutation, int lower, int upper)
static int computeLB(DdManager *table, DdHalfWord *order, int roots, int cost, int lower, int upper, int level)
static void ddClearGlobal(DdManager *table, int lower, int maxlevel)
static void freeMatrix(DdHalfWord **matrix)
static int getMaxBinomial(int n)
static int getLevelKeys(DdManager *table, int l)
#define Cudd_IsConstant(node)
#define Cudd_Regular(node)
int cuddNextLow(DdManager *table, int x)
static void pushDown(DdHalfWord *order, int j, int level)
static int updateUB(DdManager *table, int oldBound, DdHalfWord *bestOrder, int lower, int upper)
int cuddSymmSiftingConv(DdManager *table, int lower, int upper)
#define Cudd_IsComplement(node)
static DdHalfWord ** getMatrix(int rows, int cols)
static char rcsid [] DD_UNUSED
static int checkSymmInfo(DdManager *table, DdHalfWord *symmInfo, int index, int level)
#define Cudd_Complement(node)
static int ddCountRoots(DdManager *table, int lower, int upper)
int cuddSwapInPlace(DdManager *table, int x, int y)
static DdHalfWord * initSymmInfo(DdManager *table, int lower, int upper)
static int updateEntry(DdManager *table, DdHalfWord *order, int level, int cost, DdHalfWord **orders, int *costs, int subsets, char *mask, int lower, int upper)
static int ddSiftUp(DdManager *table, int x, int xLow)