SVF
Macros | Functions | Variables
cuddAnneal.c File Reference
#include "CUDD/util.h"
#include "CUDD/cuddInt.h"

Go to the source code of this file.

Macros

#define BETA   0.6
 
#define ALPHA   0.90
 
#define EXC_PROB   0.4
 
#define JUMP_UP_PROB   0.36
 
#define MAXGEN_RATIO   15.0
 
#define STOP_TEMP   1.0
 

Functions

static int stopping_criterion (int c1, int c2, int c3, int c4, double temp)
 
static double random_generator (void)
 
static int ddExchange (DdManager *table, int x, int y, double temp)
 
static int ddJumpingAux (DdManager *table, int x, int x_low, int x_high, double temp)
 
static MoveddJumpingUp (DdManager *table, int x, int x_low, int initial_size)
 
static MoveddJumpingDown (DdManager *table, int x, int x_high, int initial_size)
 
static int siftBackwardProb (DdManager *table, Move *moves, int size, double temp)
 
static void copyOrder (DdManager *table, int *array, int lower, int upper)
 
static int restoreOrder (DdManager *table, int *array, int lower, int upper)
 
int cuddAnnealing (DdManager *table, int lower, int upper)
 

Variables

static char rcsid [] DD_UNUSED = "$Id: cuddAnneal.c,v 1.15 2012/02/05 01:07:18 fabio Exp $"
 

Macro Definition Documentation

◆ ALPHA

#define ALPHA   0.90

Definition at line 74 of file cuddAnneal.c.

◆ BETA

#define BETA   0.6

CFile***********************************************************************

FileName [cuddAnneal.c]

PackageName [cudd]

Synopsis [Reordering of DDs based on simulated annealing]

Description [Internal procedures included in this file:

Static procedures included in this file:

]

SeeAlso []

Author [Jae-Young Jang, Jorgen Sivesind]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 73 of file cuddAnneal.c.

◆ EXC_PROB

#define EXC_PROB   0.4

Definition at line 75 of file cuddAnneal.c.

◆ JUMP_UP_PROB

#define JUMP_UP_PROB   0.36

Definition at line 76 of file cuddAnneal.c.

◆ MAXGEN_RATIO

#define MAXGEN_RATIO   15.0

Definition at line 77 of file cuddAnneal.c.

◆ STOP_TEMP

#define STOP_TEMP   1.0

Definition at line 78 of file cuddAnneal.c.

Function Documentation

◆ copyOrder()

static void copyOrder ( DdManager table,
int *  array,
int  lower,
int  upper 
)
static

Function********************************************************************

Synopsis [Copies the current variable order to array.]

Description [Copies the current variable order to array. At the same time inverts the permutation.]

SideEffects [None]

SeeAlso []

Definition at line 758 of file cuddAnneal.c.

763 {
764  int i;
765  int nvars;
766 
767  nvars = upper - lower + 1;
768  for (i = 0; i < nvars; i++) {
769  array[i] = table->invperm[i+lower];
770  }
771 
772 } /* end of copyOrder */
int * invperm
Definition: cuddInt.h:371

◆ cuddAnnealing()

int cuddAnnealing ( DdManager table,
int  lower,
int  upper 
)

AutomaticEnd Function********************************************************************

Synopsis [Get new variable-order by simulated annealing algorithm.]

Description [Get x, y by random selection. Choose either exchange or jump randomly. In case of jump, choose between jump_up and jump_down randomly. Do exchange or jump and get optimal case. Loop until there is no improvement or temperature reaches minimum. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 154 of file cuddAnneal.c.

158 {
159  int nvars;
160  int size;
161  int x,y;
162  int result;
163  int c1, c2, c3, c4;
164  int BestCost;
165  int *BestOrder;
166  double NewTemp, temp;
167  double rand1;
168  int innerloop, maxGen;
169  int ecount, ucount, dcount;
170 
171  nvars = upper - lower + 1;
172 
173  result = cuddSifting(table,lower,upper);
174 #ifdef DD_STATS
175  (void) fprintf(table->out,"\n");
176 #endif
177  if (result == 0) return(0);
178 
179  size = table->keys - table->isolated;
180 
181  /* Keep track of the best order. */
182  BestCost = size;
183  BestOrder = ALLOC(int,nvars);
184  if (BestOrder == NULL) {
185  table->errorCode = CUDD_MEMORY_OUT;
186  return(0);
187  }
188  copyOrder(table,BestOrder,lower,upper);
189 
190  temp = BETA * size;
191  maxGen = (int) (MAXGEN_RATIO * nvars);
192 
193  c1 = size + 10;
194  c2 = c1 + 10;
195  c3 = size;
196  c4 = c2 + 10;
197  ecount = ucount = dcount = 0;
198 
199  while (!stopping_criterion(c1, c2, c3, c4, temp)) {
200 #ifdef DD_STATS
201  (void) fprintf(table->out,"temp=%f\tsize=%d\tgen=%d\t",
202  temp,size,maxGen);
203  tosses = acceptances = 0;
204 #endif
205  for (innerloop = 0; innerloop < maxGen; innerloop++) {
206  /* Choose x, y randomly. */
207  x = (int) Cudd_Random() % nvars;
208  do {
209  y = (int) Cudd_Random() % nvars;
210  } while (x == y);
211  x += lower;
212  y += lower;
213  if (x > y) {
214  int tmp = x;
215  x = y;
216  y = tmp;
217  }
218 
219  /* Choose move with roulette wheel. */
220  rand1 = random_generator();
221  if (rand1 < EXC_PROB) {
222  result = ddExchange(table,x,y,temp); /* exchange */
223  ecount++;
224 #if 0
225  (void) fprintf(table->out,
226  "Exchange of %d and %d: size = %d\n",
227  x,y,table->keys - table->isolated);
228 #endif
229  } else if (rand1 < EXC_PROB + JUMP_UP_PROB) {
230  result = ddJumpingAux(table,y,x,y,temp); /* jumping_up */
231  ucount++;
232 #if 0
233  (void) fprintf(table->out,
234  "Jump up of %d to %d: size = %d\n",
235  y,x,table->keys - table->isolated);
236 #endif
237  } else {
238  result = ddJumpingAux(table,x,x,y,temp); /* jumping_down */
239  dcount++;
240 #if 0
241  (void) fprintf(table->out,
242  "Jump down of %d to %d: size = %d\n",
243  x,y,table->keys - table->isolated);
244 #endif
245  }
246 
247  if (!result) {
248  FREE(BestOrder);
249  return(0);
250  }
251 
252  size = table->keys - table->isolated; /* keep current size */
253  if (size < BestCost) { /* update best order */
254  BestCost = size;
255  copyOrder(table,BestOrder,lower,upper);
256  }
257  }
258  c1 = c2;
259  c2 = c3;
260  c3 = c4;
261  c4 = size;
262  NewTemp = ALPHA * temp;
263  if (NewTemp >= 1.0) {
264  maxGen = (int)(log(NewTemp) / log(temp) * maxGen);
265  }
266  temp = NewTemp; /* control variable */
267 #ifdef DD_STATS
268  (void) fprintf(table->out,"uphill = %d\taccepted = %d\n",
269  tosses,acceptances);
270  fflush(table->out);
271 #endif
272  }
273 
274  result = restoreOrder(table,BestOrder,lower,upper);
275  FREE(BestOrder);
276  if (!result) return(0);
277 #ifdef DD_STATS
278  fprintf(table->out,"#:N_EXCHANGE %8d : total exchanges\n",ecount);
279  fprintf(table->out,"#:N_JUMPUP %8d : total jumps up\n",ucount);
280  fprintf(table->out,"#:N_JUMPDOWN %8d : total jumps down",dcount);
281 #endif
282  return(1);
283 
284 } /* end of cuddAnnealing */
#define FREE(obj)
Definition: util.h:80
static int stopping_criterion(int c1, int c2, int c3, int c4, double temp)
Definition: cuddAnneal.c:305
static void copyOrder(DdManager *table, int *array, int lower, int upper)
Definition: cuddAnneal.c:758
static double random_generator(void)
Definition: cuddAnneal.c:335
#define ALPHA
Definition: cuddAnneal.c:74
int cuddSifting(DdManager *table, int lower, int upper)
Definition: cuddReorder.c:502
static int restoreOrder(DdManager *table, int *array, int lower, int upper)
Definition: cuddAnneal.c:788
static int ddExchange(DdManager *table, int x, int y, double temp)
Definition: cuddAnneal.c:355
#define BETA
Definition: cuddAnneal.c:73
long Cudd_Random(void)
Definition: cuddUtil.c:2710
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
#define EXC_PROB
Definition: cuddAnneal.c:75
static int ddJumpingAux(DdManager *table, int x, int x_low, int x_high, double temp)
Definition: cuddAnneal.c:504
#define JUMP_UP_PROB
Definition: cuddAnneal.c:76
static int result
Definition: cuddGenetic.c:121
int isolated
Definition: cuddInt.h:368
#define MAXGEN_RATIO
Definition: cuddAnneal.c:77
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ ddExchange()

static int ddExchange ( DdManager table,
int  x,
int  y,
double  temp 
)
static

Function********************************************************************

Synopsis [This function is for exchanging two variables, x and y.]

Description [This is the same funcion as ddSwapping except for comparison expression. Use probability function, exp(-size_change/temp).]

SideEffects [None]

SeeAlso []

Definition at line 355 of file cuddAnneal.c.

360 {
361  Move *move,*moves;
362  int tmp;
363  int x_ref,y_ref;
364  int x_next,y_next;
365  int size, result;
366  int initial_size, limit_size;
367 
368  x_ref = x;
369  y_ref = y;
370 
371  x_next = cuddNextHigh(table,x);
372  y_next = cuddNextLow(table,y);
373  moves = NULL;
374  initial_size = limit_size = table->keys - table->isolated;
375 
376  for (;;) {
377  if (x_next == y_next) {
378  size = cuddSwapInPlace(table,x,x_next);
379  if (size == 0) goto ddExchangeOutOfMem;
380  move = (Move *)cuddDynamicAllocNode(table);
381  if (move == NULL) goto ddExchangeOutOfMem;
382  move->x = x;
383  move->y = x_next;
384  move->size = size;
385  move->next = moves;
386  moves = move;
387  size = cuddSwapInPlace(table,y_next,y);
388  if (size == 0) goto ddExchangeOutOfMem;
389  move = (Move *)cuddDynamicAllocNode(table);
390  if (move == NULL) goto ddExchangeOutOfMem;
391  move->x = y_next;
392  move->y = y;
393  move->size = size;
394  move->next = moves;
395  moves = move;
396  size = cuddSwapInPlace(table,x,x_next);
397  if (size == 0) goto ddExchangeOutOfMem;
398  move = (Move *)cuddDynamicAllocNode(table);
399  if (move == NULL) goto ddExchangeOutOfMem;
400  move->x = x;
401  move->y = x_next;
402  move->size = size;
403  move->next = moves;
404  moves = move;
405 
406  tmp = x;
407  x = y;
408  y = tmp;
409  } else if (x == y_next) {
410  size = cuddSwapInPlace(table,x,x_next);
411  if (size == 0) goto ddExchangeOutOfMem;
412  move = (Move *)cuddDynamicAllocNode(table);
413  if (move == NULL) goto ddExchangeOutOfMem;
414  move->x = x;
415  move->y = x_next;
416  move->size = size;
417  move->next = moves;
418  moves = move;
419  tmp = x;
420  x = y;
421  y = tmp;
422  } else {
423  size = cuddSwapInPlace(table,x,x_next);
424  if (size == 0) goto ddExchangeOutOfMem;
425  move = (Move *)cuddDynamicAllocNode(table);
426  if (move == NULL) goto ddExchangeOutOfMem;
427  move->x = x;
428  move->y = x_next;
429  move->size = size;
430  move->next = moves;
431  moves = move;
432  size = cuddSwapInPlace(table,y_next,y);
433  if (size == 0) goto ddExchangeOutOfMem;
434  move = (Move *)cuddDynamicAllocNode(table);
435  if (move == NULL) goto ddExchangeOutOfMem;
436  move->x = y_next;
437  move->y = y;
438  move->size = size;
439  move->next = moves;
440  moves = move;
441  x = x_next;
442  y = y_next;
443  }
444 
445  x_next = cuddNextHigh(table,x);
446  y_next = cuddNextLow(table,y);
447  if (x_next > y_ref) break;
448 
449  if ((double) size > DD_MAX_REORDER_GROWTH * (double) limit_size) {
450  break;
451  } else if (size < limit_size) {
452  limit_size = size;
453  }
454  }
455 
456  if (y_next>=x_ref) {
457  size = cuddSwapInPlace(table,y_next,y);
458  if (size == 0) goto ddExchangeOutOfMem;
459  move = (Move *)cuddDynamicAllocNode(table);
460  if (move == NULL) goto ddExchangeOutOfMem;
461  move->x = y_next;
462  move->y = y;
463  move->size = size;
464  move->next = moves;
465  moves = move;
466  }
467 
468  /* move backward and stop at best position or accept uphill move */
469  result = siftBackwardProb(table,moves,initial_size,temp);
470  if (!result) goto ddExchangeOutOfMem;
471 
472  while (moves != NULL) {
473  move = moves->next;
474  cuddDeallocMove(table, moves);
475  moves = move;
476  }
477  return(1);
478 
479 ddExchangeOutOfMem:
480  while (moves != NULL) {
481  move = moves->next;
482  cuddDeallocMove(table, moves);
483  moves = move;
484  }
485  return(0);
486 
487 } /* end of ddExchange */
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
int cuddNextLow(DdManager *table, int x)
Definition: cuddReorder.c:737
unsigned int keys
Definition: cuddInt.h:353
DdHalfWord x
Definition: cuddInt.h:470
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:405
int cuddNextHigh(DdManager *table, int x)
Definition: cuddReorder.c:715
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddReorder.c:760
static int siftBackwardProb(DdManager *table, Move *moves, int size, double temp)
Definition: cuddAnneal.c:694
DdHalfWord y
Definition: cuddInt.h:471
#define DD_MAX_REORDER_GROWTH
Definition: cuddInt.h:151
struct Move * next
Definition: cuddInt.h:474
static int result
Definition: cuddGenetic.c:121
int isolated
Definition: cuddInt.h:368
int size
Definition: cuddInt.h:473

◆ ddJumpingAux()

static int ddJumpingAux ( DdManager table,
int  x,
int  x_low,
int  x_high,
double  temp 
)
static

Function********************************************************************

Synopsis [Moves a variable to a specified position.]

Description [If x==x_low, it executes jumping_down. If x==x_high, it executes jumping_up. This funcion is similar to ddSiftingAux. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 504 of file cuddAnneal.c.

510 {
511  Move *move;
512  Move *moves; /* list of moves */
513  int initial_size;
514  int result;
515 
516  initial_size = table->keys - table->isolated;
517 
518 #ifdef DD_DEBUG
519  assert(table->subtables[x].keys > 0);
520 #endif
521 
522  moves = NULL;
523 
524  if (cuddNextLow(table,x) < x_low) {
525  if (cuddNextHigh(table,x) > x_high) return(1);
526  moves = ddJumpingDown(table,x,x_high,initial_size);
527  /* after that point x --> x_high unless early termination */
528  if (moves == NULL) goto ddJumpingAuxOutOfMem;
529  /* move backward and stop at best position or accept uphill move */
530  result = siftBackwardProb(table,moves,initial_size,temp);
531  if (!result) goto ddJumpingAuxOutOfMem;
532  } else if (cuddNextHigh(table,x) > x_high) {
533  moves = ddJumpingUp(table,x,x_low,initial_size);
534  /* after that point x --> x_low unless early termination */
535  if (moves == NULL) goto ddJumpingAuxOutOfMem;
536  /* move backward and stop at best position or accept uphill move */
537  result = siftBackwardProb(table,moves,initial_size,temp);
538  if (!result) goto ddJumpingAuxOutOfMem;
539  } else {
540  (void) fprintf(table->err,"Unexpected condition in ddJumping\n");
541  goto ddJumpingAuxOutOfMem;
542  }
543  while (moves != NULL) {
544  move = moves->next;
545  cuddDeallocMove(table, moves);
546  moves = move;
547  }
548  return(1);
549 
550 ddJumpingAuxOutOfMem:
551  while (moves != NULL) {
552  move = moves->next;
553  cuddDeallocMove(table, moves);
554  moves = move;
555  }
556  return(0);
557 
558 } /* end of ddJumpingAux */
unsigned int keys
Definition: cuddInt.h:314
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
int cuddNextLow(DdManager *table, int x)
Definition: cuddReorder.c:737
FILE * err
Definition: cuddInt.h:424
DdSubtable * subtables
Definition: cuddInt.h:349
unsigned int keys
Definition: cuddInt.h:353
static Move * ddJumpingUp(DdManager *table, int x, int x_low, int initial_size)
Definition: cuddAnneal.c:575
int cuddNextHigh(DdManager *table, int x)
Definition: cuddReorder.c:715
static int siftBackwardProb(DdManager *table, Move *moves, int size, double temp)
Definition: cuddAnneal.c:694
static Move * ddJumpingDown(DdManager *table, int x, int x_high, int initial_size)
Definition: cuddAnneal.c:634
struct Move * next
Definition: cuddInt.h:474
static int result
Definition: cuddGenetic.c:121
int isolated
Definition: cuddInt.h:368

◆ ddJumpingDown()

static Move * ddJumpingDown ( DdManager table,
int  x,
int  x_high,
int  initial_size 
)
static

Function********************************************************************

Synopsis [This function is for jumping down.]

Description [This is a simplified version of ddSiftingDown. It does not use lower bounding. Returns the set of moves in case of success; NULL if memory is full.]

SideEffects [None]

SeeAlso []

Definition at line 634 of file cuddAnneal.c.

639 {
640  Move *moves;
641  Move *move;
642  int y;
643  int size;
644  int limit_size = initial_size;
645 
646  moves = NULL;
647  y = cuddNextHigh(table,x);
648  while (y <= x_high) {
649  size = cuddSwapInPlace(table,x,y);
650  if (size == 0) goto ddJumpingDownOutOfMem;
651  move = (Move *)cuddDynamicAllocNode(table);
652  if (move == NULL) goto ddJumpingDownOutOfMem;
653  move->x = x;
654  move->y = y;
655  move->size = size;
656  move->next = moves;
657  moves = move;
658  if ((double) size > table->maxGrowth * (double) limit_size) {
659  break;
660  } else if (size < limit_size) {
661  limit_size = size;
662  }
663  x = y;
664  y = cuddNextHigh(table,x);
665  }
666  return(moves);
667 
668 ddJumpingDownOutOfMem:
669  while (moves != NULL) {
670  move = moves->next;
671  cuddDeallocMove(table, moves);
672  moves = move;
673  }
674  return(NULL);
675 
676 } /* end of ddJumpingDown */
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
double maxGrowth
Definition: cuddInt.h:397
DdHalfWord x
Definition: cuddInt.h:470
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:405
int cuddNextHigh(DdManager *table, int x)
Definition: cuddReorder.c:715
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddReorder.c:760
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
int size
Definition: cuddInt.h:473

◆ ddJumpingUp()

static Move * ddJumpingUp ( DdManager table,
int  x,
int  x_low,
int  initial_size 
)
static

Function********************************************************************

Synopsis [This function is for jumping up.]

Description [This is a simplified version of ddSiftingUp. It does not use lower bounding. Returns the set of moves in case of success; NULL if memory is full.]

SideEffects [None]

SeeAlso []

Definition at line 575 of file cuddAnneal.c.

580 {
581  Move *moves;
582  Move *move;
583  int y;
584  int size;
585  int limit_size = initial_size;
586 
587  moves = NULL;
588  y = cuddNextLow(table,x);
589  while (y >= x_low) {
590  size = cuddSwapInPlace(table,y,x);
591  if (size == 0) goto ddJumpingUpOutOfMem;
592  move = (Move *)cuddDynamicAllocNode(table);
593  if (move == NULL) goto ddJumpingUpOutOfMem;
594  move->x = y;
595  move->y = x;
596  move->size = size;
597  move->next = moves;
598  moves = move;
599  if ((double) size > table->maxGrowth * (double) limit_size) {
600  break;
601  } else if (size < limit_size) {
602  limit_size = size;
603  }
604  x = y;
605  y = cuddNextLow(table,x);
606  }
607  return(moves);
608 
609 ddJumpingUpOutOfMem:
610  while (moves != NULL) {
611  move = moves->next;
612  cuddDeallocMove(table, moves);
613  moves = move;
614  }
615  return(NULL);
616 
617 } /* end of ddJumpingUp */
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
int cuddNextLow(DdManager *table, int x)
Definition: cuddReorder.c:737
double maxGrowth
Definition: cuddInt.h:397
DdHalfWord x
Definition: cuddInt.h:470
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:405
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddReorder.c:760
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
int size
Definition: cuddInt.h:473

◆ random_generator()

static double random_generator ( void  )
static

Function********************************************************************

Synopsis [Random number generator.]

Description [Returns a double precision value between 0.0 and 1.0.]

SideEffects [None]

SeeAlso []

Definition at line 335 of file cuddAnneal.c.

336 {
337  return((double)(Cudd_Random() / 2147483561.0));
338 
339 } /* end of random_generator */
long Cudd_Random(void)
Definition: cuddUtil.c:2710

◆ restoreOrder()

static int restoreOrder ( DdManager table,
int *  array,
int  lower,
int  upper 
)
static

Function********************************************************************

Synopsis [Restores the variable order in array by a series of sifts up.]

Description [Restores the variable order in array by a series of sifts up. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 788 of file cuddAnneal.c.

793 {
794  int i, x, y, size;
795  int nvars = upper - lower + 1;
796 
797  for (i = 0; i < nvars; i++) {
798  x = table->perm[array[i]];
799 #ifdef DD_DEBUG
800  assert(x >= lower && x <= upper);
801 #endif
802  y = cuddNextLow(table,x);
803  while (y >= i + lower) {
804  size = cuddSwapInPlace(table,y,x);
805  if (size == 0) return(0);
806  x = y;
807  y = cuddNextLow(table,x);
808  }
809  }
810 
811  return(1);
812 
813 } /* end of restoreOrder */
#define assert(ex)
Definition: util.h:141
int cuddNextLow(DdManager *table, int x)
Definition: cuddReorder.c:737
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddReorder.c:760
int * perm
Definition: cuddInt.h:369

◆ siftBackwardProb()

static int siftBackwardProb ( DdManager table,
Move moves,
int  size,
double  temp 
)
static

Function********************************************************************

Synopsis [Returns the DD to the best position encountered during sifting if there was improvement.]

Description [Otherwise, "tosses a coin" to decide whether to keep the current configuration or return the DD to the original one. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 694 of file cuddAnneal.c.

699 {
700  Move *move;
701  int res;
702  int best_size = size;
703  double coin, threshold;
704 
705  /* Look for best size during the last sifting */
706  for (move = moves; move != NULL; move = move->next) {
707  if (move->size < best_size) {
708  best_size = move->size;
709  }
710  }
711 
712  /* If best_size equals size, the last sifting did not produce any
713  ** improvement. We now toss a coin to decide whether to retain
714  ** this change or not.
715  */
716  if (best_size == size) {
717  coin = random_generator();
718 #ifdef DD_STATS
719  tosses++;
720 #endif
721  threshold = exp(-((double)(table->keys - table->isolated - size))/temp);
722  if (coin < threshold) {
723 #ifdef DD_STATS
724  acceptances++;
725 #endif
726  return(1);
727  }
728  }
729 
730  /* Either there was improvement, or we have decided not to
731  ** accept the uphill move. Go to best position.
732  */
733  res = table->keys - table->isolated;
734  for (move = moves; move != NULL; move = move->next) {
735  if (res == best_size) return(1);
736  res = cuddSwapInPlace(table,(int)move->x,(int)move->y);
737  if (!res) return(0);
738  }
739 
740  return(1);
741 
742 } /* end of sift_backward_prob */
static double random_generator(void)
Definition: cuddAnneal.c:335
Definition: cuddInt.h:469
unsigned int keys
Definition: cuddInt.h:353
DdHalfWord x
Definition: cuddInt.h:470
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddReorder.c:760
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
int isolated
Definition: cuddInt.h:368
int size
Definition: cuddInt.h:473

◆ stopping_criterion()

static int stopping_criterion ( int  c1,
int  c2,
int  c3,
int  c4,
double  temp 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Checks termination condition.]

Description [If temperature is STOP_TEMP or there is no improvement then terminates. Returns 1 if the termination criterion is met; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 305 of file cuddAnneal.c.

311 {
312  if (STOP_TEMP < temp) {
313  return(0);
314  } else if ((c1 == c2) && (c1 == c3) && (c1 == c4)) {
315  return(1);
316  } else {
317  return(0);
318  }
319 
320 } /* end of stopping_criterion */
#define STOP_TEMP
Definition: cuddAnneal.c:78

Variable Documentation

◆ DD_UNUSED

char rcsid [] DD_UNUSED = "$Id: cuddAnneal.c,v 1.15 2012/02/05 01:07:18 fabio Exp $"
static

Definition at line 95 of file cuddAnneal.c.