src/misc/espresso/pair.c File Reference

#include "espresso.h"
Include dependency graph for pair.c:

Go to the source code of this file.

Functions

void set_pair (pPLA PLA)
void set_pair1 (pPLA PLA, bool adjust_labels)
pcover pairvar (pcover A, ppair pair)
pcover delvar (pcover A, paired)
void find_optimal_pairing (pPLA PLA, int strategy)
int ** find_pairing_cost (pPLA PLA, int strategy)
 print_pair (ppair pair)
int greedy_best_cost (int **cost_array_local, ppair *pair_p)
ppair pair_best_cost (int **cost_array_local)
int find_best_cost (ppair pair)
 pair_all (pPLA PLA, int pair_strategy)
int minimize_pair (ppair pair)
 generate_all_pairs (ppair pair, int n, pset candidate, int(*action)())
ppair pair_new (int n)
ppair pair_save (ppair pair, int n)
int pair_free (ppair pair)

Variables

static int best_cost
static int ** cost_array
static ppair best_pair
static pset best_phase
static pPLA global_PLA
static pcover best_F
static pcover best_D
static pcover best_R
static int pair_minim_strategy

Function Documentation

pcover delvar ( pcover  A,
paired   
)

Definition at line 161 of file pair.c.

00164 {
00165     bool run;
00166     int first_run, run_length, var, offset = 0;
00167 
00168     run = FALSE; run_length = 0;
00169     for(var = 0; var < cube.num_binary_vars; var++)
00170         if (paired[var])
00171             if (run)
00172                 run_length += cube.part_size[var];
00173             else {
00174                 run = TRUE;
00175                 first_run = cube.first_part[var];
00176                 run_length = cube.part_size[var];
00177             }
00178         else
00179             if (run) {
00180                 A = sf_delcol(A, first_run-offset, run_length);
00181                 run = FALSE;
00182                 offset += run_length;
00183             }
00184     if (run)
00185         A = sf_delcol(A, first_run-offset, run_length);
00186     return A;
00187 }

int find_best_cost ( ppair  pair  ) 

Definition at line 440 of file pair.c.

00442 {
00443     register int i, cost;
00444 
00445     cost = 0;
00446     for(i = 0; i < pair->cnt; i++)
00447         cost += cost_array[pair->var1[i]-1][pair->var2[i]-1];
00448     if (cost > best_cost) {
00449         best_cost = cost;
00450         best_pair = pair_save(pair, pair->cnt);
00451     }
00452     if ((debug & MINCOV) && trace) {
00453         printf("cost is %d ", cost);
00454         print_pair(pair);
00455     }
00456 }

void find_optimal_pairing ( pPLA  PLA,
int  strategy 
)

Definition at line 222 of file pair.c.

00225 {
00226     int i, j, **cost_array;
00227 
00228     cost_array = find_pairing_cost(PLA, strategy);
00229 
00230     if (summary) {
00231         printf("    ");
00232         for(i = 0; i < cube.num_binary_vars; i++)
00233             printf("%3d ", i+1);
00234         printf("\n");
00235         for(i = 0; i < cube.num_binary_vars; i++) {
00236             printf("%3d ", i+1);
00237             for(j = 0; j < cube.num_binary_vars; j++)
00238                 printf("%3d ", cost_array[i][j]);
00239             printf("\n");
00240         }
00241     }
00242 
00243     if (cube.num_binary_vars <= 14) {
00244         PLA->pair = pair_best_cost(cost_array);
00245     } else {
00246         (void) greedy_best_cost(cost_array, &(PLA->pair));
00247     }
00248     printf("# ");
00249     print_pair(PLA->pair);
00250         
00251     for(i = 0; i < cube.num_binary_vars; i++)
00252         FREE(cost_array[i]);
00253     FREE(cost_array);
00254 
00255     set_pair(PLA);
00256     EXEC_S(PLA->F=espresso(PLA->F,PLA->D,PLA->R),"ESPRESSO  ",PLA->F);
00257 }

int** find_pairing_cost ( pPLA  PLA,
int  strategy 
)

Definition at line 259 of file pair.c.

00262 {
00263     int var1, var2, **cost_array;
00264     int i, j, xnum_binary_vars, xnum_vars, *xpart_size, cost;
00265     pcover T, Fsave, Dsave, Rsave;
00266     pset mask;
00267 /*    char *s;*/
00268 
00269     /* data is returned in the cost array */
00270     cost_array = ALLOC(int *, cube.num_binary_vars);
00271     for(i = 0; i < cube.num_binary_vars; i++)
00272         cost_array[i] = ALLOC(int, cube.num_binary_vars);
00273     for(i = 0; i < cube.num_binary_vars; i++)
00274         for(j = 0; j < cube.num_binary_vars; j++)
00275             cost_array[i][j] = 0;
00276 
00277     /* Setup the pair structure for pairing variables together */
00278     PLA->pair = pair_new(1);
00279     PLA->pair->cnt = 1;
00280 
00281     for(var1 = 0; var1 < cube.num_binary_vars-1; var1++) {
00282         for(var2 = var1+1; var2 < cube.num_binary_vars; var2++) {
00283             /* if anything but simple strategy, perform setup */
00284             if (strategy > 0) {
00285                 /* save the original covers */
00286                 Fsave = sf_save(PLA->F);
00287                 Dsave = sf_save(PLA->D);
00288                 Rsave = sf_save(PLA->R);
00289 
00290                 /* save the original cube structure */
00291                 xnum_binary_vars = cube.num_binary_vars;
00292                 xnum_vars = cube.num_vars;
00293                 xpart_size = ALLOC(int, cube.num_vars);
00294                 for(i = 0; i < cube.num_vars; i++)
00295                     xpart_size[i] = cube.part_size[i];
00296 
00297                 /* pair two variables together */
00298                 PLA->pair->var1[0] = var1 + 1;
00299                 PLA->pair->var2[0] = var2 + 1;
00300                 set_pair1(PLA, /* adjust_labels */ FALSE);
00301             }
00302 
00303 
00304             /* decide how to best estimate worth of this pairing */
00305             switch(strategy) {
00306                 case 3:
00307                     /*s = "exact minimization";*/
00308                     PLA->F = minimize_exact(PLA->F, PLA->D, PLA->R, 1);
00309                     cost = Fsave->count - PLA->F->count;
00310                     break;
00311                 case 2:
00312                     /*s = "full minimization";*/
00313                     PLA->F = espresso(PLA->F, PLA->D, PLA->R);
00314                     cost = Fsave->count - PLA->F->count;
00315                     break;
00316                 case 1:
00317                     /*s = "strong division";*/
00318                     PLA->F = reduce(PLA->F, PLA->D);
00319                     PLA->F = expand(PLA->F, PLA->R, FALSE);
00320                     PLA->F = irredundant(PLA->F, PLA->D);
00321                     cost = Fsave->count - PLA->F->count;
00322                     break;
00323                 case 0:
00324                     /*s = "weak division";*/
00325                     mask = new_cube();
00326                     set_or(mask, cube.var_mask[var1], cube.var_mask[var2]);
00327                     T = dist_merge(sf_save(PLA->F), mask);
00328                     cost = PLA->F->count - T->count;
00329                     sf_free(T);
00330                     set_free(mask);
00331             }
00332 
00333             cost_array[var1][var2] = cost;
00334 
00335             if (strategy > 0) {
00336                 /* restore the original cube structure -- free the new ones */
00337                 setdown_cube();
00338                 FREE(cube.part_size);
00339                 cube.num_binary_vars = xnum_binary_vars;
00340                 cube.num_vars = xnum_vars;
00341                 cube.part_size = xpart_size;
00342                 cube_setup();
00343 
00344                 /* restore the original cover(s) -- free the new ones */
00345                 sf_free(PLA->F);
00346                 sf_free(PLA->D);
00347                 sf_free(PLA->R);
00348                 PLA->F = Fsave;
00349                 PLA->D = Dsave;
00350                 PLA->R = Rsave;
00351             }
00352         }
00353     }
00354 
00355     pair_free(PLA->pair);
00356     PLA->pair = NULL;
00357     return cost_array;
00358 }

generate_all_pairs ( ppair  pair,
int  n,
pset  candidate,
int (*)()  action 
)

Definition at line 585 of file pair.c.

00590 {
00591     int i, j;
00592     pset recur_candidate;
00593     ppair recur_pair;
00594 
00595     if (set_ord(candidate) < 2) {
00596         (*action)(pair);
00597         return;
00598     }
00599 
00600     recur_pair = pair_save(pair, n);
00601     recur_candidate = set_save(candidate);
00602 
00603     /* Find first variable still in the candidate set */
00604     for(i = 0; i < n; i++)
00605         if (is_in_set(candidate, i))
00606             break;
00607 
00608     /* Try all pairs of i with other variables */
00609     for(j = i+1; j < n; j++)
00610         if (is_in_set(candidate, j)) {
00611             /* pair (i j) -- remove from candidate set for future pairings */
00612             set_remove(recur_candidate, i);
00613             set_remove(recur_candidate, j);
00614 
00615             /* add to the pair array */
00616             recur_pair->var1[recur_pair->cnt] = i+1;
00617             recur_pair->var2[recur_pair->cnt] = j+1;
00618             recur_pair->cnt++;
00619 
00620             /* recur looking for the end ... */
00621             generate_all_pairs(recur_pair, n, recur_candidate, action);
00622 
00623             /* now break this pair, and restore candidate set */
00624             recur_pair->cnt--;
00625             set_insert(recur_candidate, i);
00626             set_insert(recur_candidate, j);
00627         }
00628 
00629     /* if odd, generate all pairs which do NOT include i */
00630     if ((set_ord(candidate) % 2) == 1) {
00631         set_remove(recur_candidate, i);
00632         generate_all_pairs(recur_pair, n, recur_candidate, action);
00633     }
00634 
00635     pair_free(recur_pair);
00636     set_free(recur_candidate);
00637 }

int greedy_best_cost ( int **  cost_array_local,
ppair pair_p 
)

Definition at line 381 of file pair.c.

00384 {
00385     int i, j, besti, bestj, maxcost, total_cost;
00386     pset cand;
00387     ppair pair;
00388 
00389     pair = pair_new(cube.num_binary_vars);
00390     cand = set_full(cube.num_binary_vars);
00391     total_cost = 0;
00392 
00393     while (set_ord(cand) >= 2) {
00394         maxcost = -1;
00395         for(i = 0; i < cube.num_binary_vars; i++) {
00396             if (is_in_set(cand, i)) {
00397                 for(j = i+1; j < cube.num_binary_vars; j++) {
00398                     if (is_in_set(cand, j)) {
00399                         if (cost_array_local[i][j] > maxcost) {
00400                             maxcost = cost_array_local[i][j];
00401                             besti = i;
00402                             bestj = j;
00403                         }
00404                     }
00405                 }
00406             }
00407         }
00408         pair->var1[pair->cnt] = besti+1;
00409         pair->var2[pair->cnt] = bestj+1;
00410         pair->cnt++;
00411         set_remove(cand, besti);
00412         set_remove(cand, bestj);
00413         total_cost += maxcost;
00414     }
00415     set_free(cand);
00416     *pair_p = pair;
00417     return total_cost;
00418 }

int minimize_pair ( ppair  pair  ) 

Definition at line 510 of file pair.c.

00512 {
00513     pcover Fsave, Dsave, Rsave;
00514     int i, xnum_binary_vars, xnum_vars, *xpart_size;
00515 
00516     /* save the original covers */
00517     Fsave = sf_save(global_PLA->F);
00518     Dsave = sf_save(global_PLA->D);
00519     Rsave = sf_save(global_PLA->R);
00520 
00521     /* save the original cube structure */
00522     xnum_binary_vars = cube.num_binary_vars;
00523     xnum_vars = cube.num_vars;
00524     xpart_size = ALLOC(int, cube.num_vars);
00525     for(i = 0; i < cube.num_vars; i++)
00526         xpart_size[i] = cube.part_size[i];
00527 
00528     /* setup the paired variables */
00529     global_PLA->pair = pair;
00530     set_pair1(global_PLA, /* adjust_labels */ FALSE);
00531 
00532     /* call the minimizer */
00533     if (summary)
00534         print_pair(pair);
00535     switch(pair_minim_strategy) {
00536         case 2:
00537             EXEC_S(phase_assignment(global_PLA,0), "OPO       ", global_PLA->F);
00538             if (summary)
00539                 printf("# phase is %s\n", pc1(global_PLA->phase));
00540             break;
00541         case 1:
00542             EXEC_S(global_PLA->F = minimize_exact(global_PLA->F, global_PLA->D,
00543                 global_PLA->R, 1), "EXACT     ", global_PLA->F);
00544             break;
00545         case 0:
00546             EXEC_S(global_PLA->F = espresso(global_PLA->F, global_PLA->D,
00547                 global_PLA->R), "ESPRESSO  ", global_PLA->F);
00548             break;
00549         default:
00550             break;
00551     }
00552 
00553     /* see if we have a new best solution */
00554     if (global_PLA->F->count < best_cost) {
00555         best_cost = global_PLA->F->count;
00556         best_pair = pair_save(pair, pair->cnt);
00557         best_phase = global_PLA->phase!=NULL?set_save(global_PLA->phase):NULL;
00558         if (best_F != NULL) sf_free(best_F);
00559         if (best_D != NULL) sf_free(best_D);
00560         if (best_R != NULL) sf_free(best_R);
00561         best_F = sf_save(global_PLA->F);
00562         best_D = sf_save(global_PLA->D);
00563         best_R = sf_save(global_PLA->R);
00564     }
00565 
00566     /* restore the original cube structure -- free the new ones */
00567     setdown_cube();
00568     FREE(cube.part_size);
00569     cube.num_binary_vars = xnum_binary_vars;
00570     cube.num_vars = xnum_vars;
00571     cube.part_size = xpart_size;
00572     cube_setup();
00573 
00574     /* restore the original cover(s) -- free the new ones */
00575     sf_free(global_PLA->F);
00576     sf_free(global_PLA->D);
00577     sf_free(global_PLA->R);
00578     global_PLA->F = Fsave;
00579     global_PLA->D = Dsave;
00580     global_PLA->R = Rsave;
00581     global_PLA->pair = NULL;
00582     global_PLA->phase = NULL;
00583 }

pair_all ( pPLA  PLA,
int  pair_strategy 
)

Definition at line 467 of file pair.c.

00470 {
00471     ppair pair;
00472     pset candidate;
00473 
00474     global_PLA = PLA;
00475     pair_minim_strategy = pair_strategy;
00476     best_cost = PLA->F->count + 1;
00477     best_pair = NULL;
00478     best_phase = NULL;
00479     best_F = best_D = best_R = NULL;
00480     pair = pair_new(cube.num_binary_vars);
00481     candidate = set_fill(set_new(cube.num_binary_vars), cube.num_binary_vars);
00482 
00483     generate_all_pairs(pair, cube.num_binary_vars, candidate, minimize_pair);
00484 
00485     pair_free(pair);
00486     set_free(candidate);
00487 
00488     PLA->pair = best_pair;
00489     PLA->phase = best_phase;
00490 /* not really necessary
00491     if (phase != NULL)
00492         (void) set_phase(PLA->phase);
00493 */
00494     set_pair(PLA);
00495     printf("# ");
00496     print_pair(PLA->pair);
00497 
00498     sf_free(PLA->F);
00499     sf_free(PLA->D);
00500     sf_free(PLA->R);
00501     PLA->F = best_F;
00502     PLA->D = best_D;
00503     PLA->R = best_R;
00504 }

ppair pair_best_cost ( int **  cost_array_local  ) 

Definition at line 421 of file pair.c.

00423 {
00424     ppair pair;
00425     pset candidate;
00426 
00427     best_cost = -1;
00428     best_pair = NULL;
00429     cost_array = cost_array_local;
00430 
00431     pair = pair_new(cube.num_binary_vars);
00432     candidate = set_full(cube.num_binary_vars);
00433     generate_all_pairs(pair, cube.num_binary_vars, candidate, find_best_cost);
00434     pair_free(pair);
00435     set_free(candidate);
00436     return best_pair;
00437 }

int pair_free ( ppair  pair  ) 

Definition at line 669 of file pair.c.

00671 {
00672     FREE(pair->var1);
00673     FREE(pair->var2);
00674     FREE(pair);
00675 }

ppair pair_new ( int  n  ) 

Definition at line 639 of file pair.c.

00641 {
00642     register ppair pair1;
00643 
00644     pair1 = ALLOC(pair_t, 1);
00645     pair1->cnt = 0;
00646     pair1->var1 = ALLOC(int, n);
00647     pair1->var2 = ALLOC(int, n);
00648     return pair1;
00649 }

ppair pair_save ( ppair  pair,
int  n 
)

Definition at line 652 of file pair.c.

00655 {
00656     register int k;
00657     register ppair pair1;
00658 
00659     pair1 = pair_new(n);
00660     pair1->cnt = pair->cnt;
00661     for(k = 0; k < pair->cnt; k++) {
00662         pair1->var1[k] = pair->var1[k];
00663         pair1->var2[k] = pair->var2[k];
00664     }
00665     return pair1;
00666 }

pcover pairvar ( pcover  A,
ppair  pair 
)

Definition at line 121 of file pair.c.

00124 {
00125     register pcube last, p;
00126     register int val, p1, p2, b1, b0;
00127     int insert_col, pairnum;
00128 
00129     insert_col = cube.first_part[cube.num_vars - 1];
00130 
00131     /* stretch the cover matrix to make room for the paired variables */
00132     A = sf_delcol(A, insert_col, -4*pair->cnt);
00133 
00134     /* compute the paired values */
00135     foreach_set(A, last, p) {
00136         for(pairnum = 0; pairnum < pair->cnt; pairnum++) {
00137             p1 = cube.first_part[pair->var1[pairnum] - 1];
00138             p2 = cube.first_part[pair->var2[pairnum] - 1];
00139             b1 = is_in_set(p, p2+1);
00140             b0 = is_in_set(p, p2);
00141             val = insert_col + pairnum * 4;
00142             if (/* a0 */ is_in_set(p, p1)) {
00143                 if (b0)
00144                     set_insert(p, val + 3);
00145                 if (b1)
00146                     set_insert(p, val + 2);
00147             }
00148             if (/* a1 */ is_in_set(p, p1+1)) {
00149                 if (b0)
00150                     set_insert(p, val + 1);
00151                 if (b1)
00152                     set_insert(p, val);
00153             }
00154         }
00155     }
00156     return A;
00157 }

print_pair ( ppair  pair  ) 

Definition at line 369 of file pair.c.

00371 {
00372     int i;
00373 
00374     printf("pair is");
00375     for(i = 0; i < pair->cnt; i++)
00376         printf (" (%d %d)", pair->var1[i], pair->var2[i]);
00377     printf("\n");
00378 }

void set_pair ( pPLA  PLA  ) 

Definition at line 12 of file pair.c.

00014 {
00015     set_pair1(PLA, TRUE);
00016 }

void set_pair1 ( pPLA  PLA,
bool  adjust_labels 
)

Definition at line 18 of file pair.c.

00021 {
00022     int i, var, *paired, newvar;
00023     int old_num_vars, old_num_binary_vars, old_size, old_mv_start;
00024     int *new_part_size, new_num_vars, new_num_binary_vars, new_mv_start;
00025     ppair pair = PLA->pair;
00026     char scratch[1000], **oldlabel, *var1, *var1bar, *var2, *var2bar;
00027 
00028     if (adjust_labels)
00029         makeup_labels(PLA);
00030 
00031     /* Check the pair structure for valid entries and see which binary
00032         variables are left unpaired
00033     */
00034     paired = ALLOC(bool, cube.num_binary_vars);
00035     for(var = 0; var < cube.num_binary_vars; var++)
00036         paired[var] = FALSE;
00037     for(i = 0; i < pair->cnt; i++)
00038         if ((pair->var1[i] > 0 && pair->var1[i] <= cube.num_binary_vars) &&
00039              (pair->var2[i] > 0 && pair->var2[i] <= cube.num_binary_vars)) {
00040             paired[pair->var1[i]-1] = TRUE;
00041             paired[pair->var2[i]-1] = TRUE;
00042         } else
00043             fatal("can only pair binary-valued variables");
00044 
00045     PLA->F = delvar(pairvar(PLA->F, pair), paired);
00046     PLA->R = delvar(pairvar(PLA->R, pair), paired);
00047     PLA->D = delvar(pairvar(PLA->D, pair), paired);
00048 
00049     /* Now painfully adjust the cube size */
00050     old_size = cube.size;
00051     old_num_vars = cube.num_vars;
00052     old_num_binary_vars = cube.num_binary_vars;
00053     old_mv_start = cube.first_part[cube.num_binary_vars];
00054     /* Create the new cube.part_size vector and setup the cube structure */
00055     new_num_binary_vars = 0;
00056     for(var = 0; var < old_num_binary_vars; var++)
00057         new_num_binary_vars += (paired[var] == FALSE);
00058     new_num_vars = new_num_binary_vars + pair->cnt;
00059     new_num_vars += old_num_vars - old_num_binary_vars;
00060     new_part_size = ALLOC(int, new_num_vars);
00061     for(var = 0; var < pair->cnt; var++)
00062         new_part_size[new_num_binary_vars + var] = 4;
00063     for(var = 0; var < old_num_vars - old_num_binary_vars; var++)
00064         new_part_size[new_num_binary_vars + pair->cnt + var] =
00065             cube.part_size[old_num_binary_vars + var];
00066     setdown_cube();
00067     FREE(cube.part_size);
00068     cube.num_vars = new_num_vars;
00069     cube.num_binary_vars = new_num_binary_vars;
00070     cube.part_size = new_part_size;
00071     cube_setup();
00072 
00073     /* hack with the labels to get them correct */
00074     if (adjust_labels) {
00075         oldlabel = PLA->label;
00076         PLA->label = ALLOC(char *, cube.size);
00077         for(var = 0; var < pair->cnt; var++) {
00078             newvar = cube.num_binary_vars*2 + var*4;
00079             var1 = oldlabel[ (pair->var1[var]-1) * 2 + 1];
00080             var2 = oldlabel[ (pair->var2[var]-1) * 2 + 1];
00081             var1bar = oldlabel[ (pair->var1[var]-1) * 2];
00082             var2bar = oldlabel[ (pair->var2[var]-1) * 2];
00083             (void) sprintf(scratch, "%s+%s", var1bar, var2bar);
00084             PLA->label[newvar] = util_strsav(scratch);
00085             (void) sprintf(scratch, "%s+%s", var1bar, var2);
00086             PLA->label[newvar+1] = util_strsav(scratch);
00087             (void) sprintf(scratch, "%s+%s", var1, var2bar);
00088             PLA->label[newvar+2] = util_strsav(scratch);
00089             (void) sprintf(scratch, "%s+%s", var1, var2);
00090             PLA->label[newvar+3] = util_strsav(scratch);
00091         }
00092         /* Copy the old labels for the unpaired binary vars */
00093         i = 0;
00094         for(var = 0; var < old_num_binary_vars; var++) {
00095             if (paired[var] == FALSE) {
00096                 PLA->label[2*i] = oldlabel[2*var];
00097                 PLA->label[2*i+1] = oldlabel[2*var+1];
00098                 oldlabel[2*var] = oldlabel[2*var+1] = (char *) NULL;
00099                 i++;
00100             }
00101         }
00102         /* Copy the old labels for the remaining unpaired vars */
00103         new_mv_start = cube.num_binary_vars*2 + pair->cnt*4;
00104         for(i = old_mv_start; i < old_size; i++) {
00105             PLA->label[new_mv_start + i - old_mv_start] = oldlabel[i];
00106             oldlabel[i] = (char *) NULL;
00107         }
00108         /* free remaining entries in oldlabel */
00109         for(i = 0; i < old_size; i++)
00110             if (oldlabel[i] != (char *) NULL)
00111                 FREE(oldlabel[i]);
00112         FREE(oldlabel);
00113     }
00114 
00115     /* the paired variables should not be sparse (cf. mv_reduce/raise_in)*/
00116     for(var = 0; var < pair->cnt; var++)
00117         cube.sparse[cube.num_binary_vars + var] = 0;
00118     FREE(paired);
00119 }


Variable Documentation

int best_cost [static]

Definition at line 360 of file pair.c.

pcover best_D [static]

Definition at line 365 of file pair.c.

pcover best_F [static]

Definition at line 365 of file pair.c.

ppair best_pair [static]

Definition at line 362 of file pair.c.

pset best_phase [static]

Definition at line 363 of file pair.c.

pcover best_R [static]

Definition at line 365 of file pair.c.

int** cost_array [static]

Definition at line 361 of file pair.c.

pPLA global_PLA [static]

Definition at line 364 of file pair.c.

int pair_minim_strategy [static]

Definition at line 366 of file pair.c.


Generated on Tue Jan 5 12:19:12 2010 for abc70930 by  doxygen 1.6.1