#include "espresso.h"
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 |
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 }
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 | ) |
ppair pair_new | ( | int | n | ) |
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 | ) |
void set_pair | ( | pPLA | PLA | ) |
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 }
pset best_phase [static] |
int** cost_array [static] |
pPLA global_PLA [static] |
int pair_minim_strategy [static] |