src/common/tree_decomp.cc

00001 
00002 /*
00003 
00004 This tree decomposition based library was written by 
00005 Kyle Ellrott (kellrott@csbl.bmb.uga.edu)
00006 and is distributed under the GPL v2.0 license
00007 
00008 */
00009 
00010 
00011 #include <stdlib.h>
00012 #include <stdio.h>
00013 #include <string.h>
00014 
00015 #include "tree_decomp.h"
00016 
00017 td_graph * td_graph_init( long vertex_count, long *state_count, char **matrix ) {
00018         td_graph *graph = (td_graph *)malloc(sizeof(td_graph));
00019         
00020         long edge_count = 0;
00021         for (int i = 0; i < vertex_count; i++) {
00022                 for (int j = i+1; j < vertex_count; j++) {
00023                         if ( matrix[i][j] )
00024                                 edge_count++;
00025                 }
00026         }
00027         
00028         
00029         graph->vertex_count = vertex_count;
00030         graph->edge_count = edge_count;
00031         
00032         if ( state_count !=  NULL ) {
00033                 long cur_loc = 0;
00034                 graph->state_count = (long *)malloc(sizeof(long) * vertex_count);
00035                 for (int i = 0; i < vertex_count; i++) {
00036                         graph->state_count[i] = state_count[i];
00037                         cur_loc += state_count[i];
00038                 }
00039                 graph->vertex_score = (double **)malloc(sizeof(double *) * vertex_count );
00040                 graph->vertex_score[0] = (double *)malloc(sizeof(double) * cur_loc );
00041                 cur_loc = 0;
00042                 for (int i = 0; i < vertex_count; i++) {
00043                         graph->vertex_score[i] = graph->vertex_score[0] + cur_loc;
00044                         cur_loc += graph->state_count[i];
00045                 }
00046                 graph->edge_score = (double ***)malloc(sizeof(double **) * vertex_count * vertex_count );
00047                 for (int i = 0; i < vertex_count; i++) {
00048                         for (int j = 0; j < vertex_count; j++) {
00049                                 long offset = td_edge_offset( graph, i, j ); 
00050                                 if (i < j) {
00051                                         if ( matrix[i][j] ) {
00052                                                 graph->edge_score[ offset ] = (double **)malloc(sizeof(double *) * state_count[i] );
00053                                                 graph->edge_score[ offset ][0] = (double *)malloc(sizeof(double) * state_count[i] * state_count[j]);
00054                                                 for (int k = 0; k < state_count[i]; k++) {
00055                                                         graph->edge_score[ offset ][k] = graph->edge_score[ offset ][0] + k * state_count[j];
00056                                                 }
00057                                         } else {
00058                                                 graph->edge_score[ offset ] = NULL;
00059                                         }
00060                                 } else {
00061                                         graph->edge_score[ offset ] = NULL;
00062                                 }
00063                         }
00064                 }
00065         }
00066         graph->matrix = matrix;
00067         return graph;
00068 }
00069 
00070 
00071 char **td_matrix_init( long vertex_count ) {
00072         char **matrix = (char **)malloc(sizeof(char *) * vertex_count );
00073         matrix[0] = (char *)malloc(sizeof(char) * vertex_count * vertex_count);
00074         for (int i = 0; i < vertex_count; i++) {
00075                 matrix[i] = matrix[0] + vertex_count * i;
00076                 for (int j = 0; j < vertex_count; j++) {
00077                         matrix[i][j] = 0;
00078                 }
00079         }       
00080         return matrix;  
00081 }
00082 
00083 
00084 
00085 void td_matrix_free( char ** graph) {
00086         free( graph[0] );
00087         free( graph );
00088 }
00089 
00090 
00091 void  td_graph_free( td_graph *graph) {
00092         free( graph->vertex_score[0] );
00093         free( graph->vertex_score );
00094         free( graph->state_count );
00095         for (int i = 0; i < graph->vertex_count; i++) {
00096                 for (int j = 0; j < graph->vertex_count; j++) {
00097                         if ( graph->edge_score[i][j] ) {
00098                                 free( graph->edge_score[ td_edge_offset(graph, i,j) ][0] );
00099                                 free( graph->edge_score[ td_edge_offset(graph, i,j) ] );
00100                         }
00101                 }       
00102         }       
00103 }
00104 
00105 
00106 
00107 long td_dist_count(char **matrix, long matrix_size, long cur_node, long source) {
00108         int i;
00109         long dist = 0, new_dist;
00110         for (i = 0; i < matrix_size; i++) {
00111                 if (cur_node != i && i != source && matrix[cur_node][i]) {
00112                         new_dist = td_dist_count(matrix, matrix_size, i, cur_node);
00113                         if (new_dist > dist)
00114                                 dist = new_dist;
00115                 }
00116         }
00117         return dist + 1;        
00118 }
00119 
00120 void td_tree_clean_direction( td_decomp *decomp, int cur_bag, int parent) {
00121         for (int i=0; i < decomp->bag_count; i++) {
00122                 if ( decomp->bag_matrix[cur_bag][i] ) {
00123                         if ( i == cur_bag || i == parent ) {
00124                                 decomp->bag_matrix[cur_bag][i] = 0;
00125                         } else {
00126                                 td_tree_clean_direction(decomp, i, cur_bag);
00127                         }
00128                 }
00129         }       
00130 }
00131 
00132 
00133 
00134 
00135 int bag_intersect( td_decomp *decomp, int bag_1, int bag_2, char *answer ) {
00136         char mask[ decomp->graph->vertex_count ];
00137         int count = 0;  
00138         memset(mask, 0x00, decomp->graph->vertex_count );       
00139         if (answer != NULL) {
00140                 memset(answer, 0x00, decomp->graph->vertex_count );     
00141         }
00142         if ( bag_1 != -1) {
00143                 for (int i = 0; i < decomp->bag_size[bag_1]; i++) {
00144                         mask[ decomp->bag[bag_1][i] ] |= 0x01;
00145                 }
00146         }
00147         if ( bag_2 != -1 ) {
00148                 for (int i = 0; i < decomp->bag_size[bag_2]; i++) {
00149                         mask[ decomp->bag[bag_2][i] ] |= 0x02;
00150                 }       
00151         }
00152         for (int i = 0; i < decomp->graph->vertex_count; i++) {
00153                 if (mask[i] == 0x03) {
00154                         if (answer != NULL)
00155                                 answer[i] = 0x01;
00156                         count++;
00157                 }
00158         }       
00159         return count;
00160 }
00161 
00162 
00163 char bag_contains_intersect(  td_decomp *decomp, int bag_mid, int bag_1, int bag_2 ) {  
00164         char mask[ decomp->graph->vertex_count ];
00165         memset(mask, 0x00, decomp->graph->vertex_count );       
00166         for (int i = 0; i < decomp->bag_size[bag_1]; i++) {
00167                 mask[ decomp->bag[bag_1][i] ] |= 0x01;
00168         }
00169         for (int i = 0; i < decomp->bag_size[bag_2]; i++) {
00170                 mask[ decomp->bag[bag_2][i] ] |= 0x02;
00171         }       
00172         for (int i = 0; i < decomp->bag_size[bag_mid]; i++) {
00173                 mask[ decomp->bag[bag_2][i] ] |= 0x04;
00174         }               
00175         
00176         for (int i = 0; i < decomp->graph->vertex_count; i++) {
00177                 if (mask[i] == 0x03) {
00178                         return 0;
00179                 }               
00180         }
00181         return 1;
00182 }
00183 
00184 td_decomp * td_graph_decomp_tri( td_graph *graph ) {
00185         td_decomp *decomp = (td_decomp *)malloc(sizeof(td_decomp));
00186         
00187         
00188         char **connect_matrix = td_matrix_init( graph->vertex_count );  
00189         for (int i = 0; i < graph->vertex_count; i++) {
00190                 for (int j = 0; j < graph->vertex_count; j++) {
00191                         connect_matrix[i][j] = graph->matrix[i][j];
00192                 }
00193         }
00194         
00195         char *active_vertex = (char *)malloc(sizeof(char) * graph->vertex_count);
00196         for (int i = 0; i < graph->vertex_count; i++) {
00197                 active_vertex[i] = 1;
00198         }
00199         
00200         long **bag_list = (long **)malloc(sizeof(long *) * graph->vertex_count);
00201         long *bag_size = (long *)malloc(sizeof(long) * graph->vertex_count);
00202         bag_list[0]  =(long *)malloc(sizeof(long) * graph->vertex_count * graph->vertex_count );
00203         for (int i = 0; i < graph->vertex_count; i++) {
00204                 bag_size[i] = 0;
00205                 bag_list[i] = bag_list[0] + i * (graph->vertex_count);
00206         }
00207         
00208         long active_vertex_count = graph->vertex_count;
00209         long bag_count = 0;
00210         long least_edge, least_count;
00211         do {
00212                 //find the edge with the least number of connections
00213                 least_edge = -1;
00214                 least_count = 0;
00215                 for (int i = 0; i < graph->vertex_count; i++) {
00216                         if (active_vertex[i]) {
00217                                 int connect_count = 0;
00218                                 for (int j = 0; j < graph->vertex_count; j++) {
00219                                         if (active_vertex[j] && i != j && connect_matrix[i][j]) {
00220                                                 connect_count++;
00221                                         }
00222                                 }
00223                                 if (least_edge == -1 || least_count > connect_count) {
00224                                         least_edge = i;
00225                                         least_count = connect_count;
00226                                 }
00227                         }
00228                 }
00229                 
00230                 if (least_edge != -1 && active_vertex_count > least_count) {
00231                         active_vertex[least_edge] = 0;
00232                         int l = 0;
00233                         //begin removing vertex
00234                         //fprintf(stderr, "%d: %d", bag_count, least_edge);
00235                         bag_list[ bag_count ][0] = least_edge;
00236                         active_vertex_count--;
00237                         l++;
00238                         //list connected edges, and connect them to each other
00239                         for (int i = 0; i < graph->vertex_count; i++) {
00240                                 if (active_vertex[i] && connect_matrix[i][least_edge]) {
00241                                         //fprintf(stderr, " %d", i);
00242                                         bag_list[ bag_count ][ l  ] = i;
00243                                         l++;
00244                                         for (int j = 0; j < graph->vertex_count; j++) {
00245                                                 if (active_vertex[j] && i != j && connect_matrix[j][least_edge]) {
00246                                                         connect_matrix[i][j] = 1;
00247                                                         connect_matrix[j][i] = 1;
00248                                                 }
00249                                         }
00250                                 }
00251                         }
00252                         //fprintf(stderr, "\n");
00253                         bag_size[bag_count] = l;
00254                         bag_count++;
00255                 }               
00256         } while (least_edge != -1 && active_vertex_count > least_count);
00257         free(active_vertex);
00258         char **bag_matrix = td_matrix_init( bag_count );
00259         
00260         decomp->bag_matrix = bag_matrix;
00261         decomp->bag = bag_list;
00262         decomp->bag_size = bag_size;
00263         decomp->bag_count = bag_count;  
00264         decomp->graph = graph;
00265         
00266 
00267         char *active_bag = (char *)malloc(sizeof(char) * bag_count);
00268         memset(active_bag, 0, sizeof(char) * bag_count);
00269         
00270         int active_bag_count = 1;
00271         active_bag[0] = 1;
00272         while ( active_bag_count < bag_count ) {
00273                 //find the bag that has the maximal cardinality of the seperator set with one of the bags already in the active set             
00274                 int max_src = -1, max_dst = -1, max_count = 0;
00275                 for (int i = 0; i < bag_count; i++) {
00276                         if ( active_bag[i] ) {
00277                                 for (int j = 0; j < bag_count; j++) {
00278                                         if ( !active_bag[j] ) {
00279                                                 int set_size = bag_intersect( decomp, i, j, NULL );
00280                                                 if ( set_size > max_count ) {
00281                                                         max_src = i;
00282                                                         max_dst = j;
00283                                                         max_count = set_size;
00284                                                 }
00285                                         }
00286                                 }
00287                         }                       
00288                 }
00289                 if (max_count > 0) {
00290                         active_bag[ max_dst ] = 1;
00291                         decomp->bag_matrix[max_src][max_dst] = 1;
00292                         decomp->bag_matrix[max_dst][max_src] = 1;
00293                         active_bag_count++;
00294                 } else {
00295                         if ( active_bag_count < bag_count ) {
00296                                 //we should only reach this point if there are disconnected bags on the graph
00297                                 //we're going to attach one of them at an arbitrary point
00298                                 for (int i = 0; i < bag_count; i++) {
00299                                         if ( !active_bag[i] ) {
00300                                                 for (int j = 0; j < bag_count; j++) {
00301                                                         if (active_bag[j]) {
00302                                                                 active_bag[i] = 1;
00303                                                                 decomp->bag_matrix[i][j] = 1;
00304                                                                 decomp->bag_matrix[j][i] = 1;
00305                                                                 active_bag_count++;
00306                                                                 i = bag_count;
00307                                                                 j = bag_count;
00308                                                         }
00309                                                 }                                               
00310                                         }
00311                                 }                               
00312                         }
00313                 }
00314         }
00315         free(active_bag);
00316                 
00317         //pick the root
00318 
00319         long dist = -1;
00320         for (int i = 0; i < bag_count; i++) {
00321                 int k = td_dist_count(bag_matrix, bag_count, i, -1);
00322                 if (dist == -1 || k < dist) {
00323                         decomp->root = i;
00324                         dist = k;
00325                 }
00326         }
00327 
00328         decomp->root = 0;
00329         
00330         //make the connection matrix respect the directions
00331         td_tree_clean_direction( decomp, decomp->root, -1);     
00332         
00333         return decomp;
00334 }
00335 
00336 
00337 long mask_enum( td_decomp *decomp, char *mask, long *set_pos) {
00338         long out = 0;
00339         long row_size = 1;
00340         int mask_count = 0;
00341         for (int i = 0; i < decomp->graph->vertex_count; i++) {
00342                 if (mask[i]) {
00343                         out += set_pos[i] * row_size;
00344                         row_size *= decomp->graph->state_count[i];
00345                         mask_count++;
00346                 }
00347         }       
00348         if (mask_count == 0) {
00349                 return -1;
00350         }
00351         return out;
00352 }
00353 
00354 void  mask_de_enum( td_decomp *decomp, char *mask, long pos, long *set_pos) {
00355         long in_pos = pos;
00356         for (int i = 0; i < decomp->graph->vertex_count; i++) {
00357                 if (mask[i]) {
00358                         set_pos[i] = in_pos % decomp->graph->state_count[i];
00359                         in_pos = in_pos / decomp->graph->state_count[i];
00360                 } else {
00361                         set_pos[i] = 0;
00362                 }
00363         }       
00364 }
00365 
00366 
00367 typedef struct td_row {
00368         int chosen;
00369         double  val;
00370 } td_row;
00371 
00372 
00373 
00374 int td_graph_decomp_extract( td_decomp *decomp, int cur_bag, int parent, td_row **tables, long *sol ) {
00375         if ( parent != -1 ) {           
00376                 char isec_mask[ decomp->graph->vertex_count ];
00377                 bag_intersect( decomp, cur_bag, parent, isec_mask );
00378                 long chosen = mask_enum( decomp, isec_mask, sol ); 
00379                 //printf("bag %d - %d\n", cur_bag, chosen);
00380                 char uniq_mask[ decomp->graph->vertex_count ];
00381                 memcpy( uniq_mask, isec_mask, decomp->graph->vertex_count );
00382                 for (int i = 0; i < decomp->bag_size[ cur_bag ]; i++) {
00383                         if ( ! uniq_mask[ decomp->bag[cur_bag][i] ] ) {
00384                                 uniq_mask[ decomp->bag[cur_bag][i] ] = 1;
00385                         } else {
00386                                 uniq_mask[ decomp->bag[cur_bag][i] ] = 0;
00387                         }
00388                 }
00389                 for (int i = 0; i < decomp->bag_size[ parent ]; i++) {
00390                         uniq_mask[ decomp->bag[parent][i] ] = 0;
00391                 }
00392                 long sel_pos[ decomp->graph->vertex_count ];
00393                 mask_de_enum( decomp, uniq_mask, tables[ cur_bag ][ chosen ].chosen, sel_pos);
00394                 for (int i = 0; i < decomp->graph->vertex_count; i++) {
00395                         if ( uniq_mask[i] )
00396                                 sol[i] = sel_pos[i];
00397                 }
00398                 //now determine for children
00399                 for (int i = 0; i < decomp->bag_count; i++) {
00400                         if ( decomp->bag_matrix[cur_bag][i] ) {
00401                                 td_graph_decomp_extract( decomp, i, cur_bag, tables, sol);
00402                         }
00403                 }
00404         } else {
00405                 char uniq_mask[ decomp->graph->vertex_count ];
00406                 memset(uniq_mask, 0x00, decomp->graph->vertex_count );
00407                 for (int i = 0; i < decomp->bag_size[ cur_bag ]; i++) {
00408                         uniq_mask[ decomp->bag[cur_bag][i] ] = 1;
00409                 }
00410                 long cur_pos[ decomp->graph->vertex_count ];
00411                 mask_de_enum( decomp, uniq_mask, tables[ cur_bag ][0].chosen, cur_pos ); 
00412                 /*
00413                 printf("::bag %d - ", cur_bag);
00414                 for (int i = 0; i < decomp->graph->vertex_count; i++) {
00415                         if ( uniq_mask[i] )
00416                                 printf("%d(%d) ", i, cur_pos[i]);
00417                 }
00418                 printf("\n");
00419                  */
00420                 for (int i = 0; i < decomp->graph->vertex_count; i++) {
00421                         if (uniq_mask[i])
00422                                 sol[i] = cur_pos[i];
00423                 }                         
00424                 for (int i = 0; i < decomp->bag_count; i++) {
00425                         if ( decomp->bag_matrix[cur_bag][i] ) {
00426                                 td_graph_decomp_extract( decomp, i, cur_bag, tables, sol);
00427                         }
00428                 }
00429         }
00430 }
00431 
00432 
00433 
00434 int td_graph_decomp_solve_explore( td_decomp *decomp, int cur_bag, int parent, td_row **tables ) {
00435         //first solve the children
00436         for (int i = 0; i < decomp->bag_count; i++) {
00437                 if ( decomp->bag_matrix[cur_bag][i] ) {
00438                         td_graph_decomp_solve_explore( decomp, i, cur_bag, tables );
00439                 }
00440         }       
00441         
00442         //start by find intersections with the parent, if we don't have any,
00443         //or we don't have a parent, special steps will be taken
00444         char isec_mask[ decomp->graph->vertex_count ];
00445         int isec_count = bag_intersect( decomp, cur_bag, parent, isec_mask );
00446         long row_count = 1;
00447         //if these is no intersection with the parent, we only have one row, which is the
00448         //basis of the answer
00449         if ( isec_count > 0 ) {
00450                 //figure out how many rows it will take to enumerate all the combinations
00451                 //of the vertices that intersect with out parent
00452                 row_count = 1;
00453                 for (int i = 0; i < decomp->graph->vertex_count; i++) {
00454                         if ( isec_mask[i] ) {
00455                                 row_count *= decomp->graph->state_count[ i ];
00456                         }
00457                 }
00458         } 
00459                 
00460         tables[ cur_bag ] = (td_row *)malloc( sizeof(td_row) * row_count );
00461         //figure out what vertices this bag has that it parent doesnt
00462         //we will have to find the best combination of these for each of the  
00463         //rows in the table of shared vertices combinations
00464         char uniq_mask[ decomp->graph->vertex_count ];
00465         memcpy( uniq_mask, isec_mask, decomp->graph->vertex_count );
00466         for (int i = 0; i < decomp->bag_size[ cur_bag ]; i++) {
00467                 if ( ! uniq_mask[ decomp->bag[cur_bag][i] ] ) {
00468                         uniq_mask[ decomp->bag[cur_bag][i] ] = 1;
00469                 } else {
00470                         uniq_mask[ decomp->bag[cur_bag][i] ] = 0;
00471                 }
00472         }
00473         if ( parent != -1) {
00474                 for (int i = 0; i < decomp->bag_size[ parent ]; i++) {
00475                         uniq_mask[ decomp->bag[parent][i] ] = 0;
00476                 }
00477         }
00478         int uniq_count = 0; 
00479         for (int i = 0; i < decomp->graph->vertex_count; i++) {
00480                 if (uniq_mask[i])
00481                         uniq_count++;
00482         }
00483         //figure out the unique row count, for ever row in the table
00484         //this is how many possibilities we will have to search
00485         long uniq_row_count = 1;
00486         for (int i = 0; i < decomp->graph->vertex_count; i++) {
00487                 if ( uniq_mask[i] ) {
00488                         uniq_row_count *= decomp->graph->state_count[ i  ];
00489                 }
00490         }
00491         
00492         //printf("Bag %d : (rows: %d)  (uniq_rows: %d) \n", cur_bag, row_count, uniq_row_count );
00493         
00494         //setup the children
00495         //we will be looking at them when we try to figure out the best combination of 
00496         //vertices that don't occur in the parent
00497         //remember, each bag has a table that enumerate all possible combinations
00498         //of vertices that occur in the parent annd the child, in this case, the parent would be the 
00499         //current bag
00500         char **child_isec = (char **)malloc(sizeof(char *) * decomp->bag_count );               
00501         int child_count = 0;
00502         for (int i = 0; i < decomp->bag_count; i++) {
00503                 if ( decomp->bag_matrix[cur_bag][i] ) {
00504                         child_isec[i] = (char *)malloc(sizeof(char) * decomp->graph->vertex_count);
00505                         bag_intersect( decomp, cur_bag, i, child_isec[ i ] );
00506                         child_count++;
00507                 } else {
00508                         child_isec[i] = NULL;
00509                 }
00510         }
00511         
00512         //fill in the rows 
00513         //remember, for each row, find the best combination of vertices that don't occur in the parent
00514         //each row is a different combination of vertices that do occur in the parent
00515         for (int i = 0; i < row_count; i++) {
00516                 long cur_pos[ decomp->graph->vertex_count ];
00517                 if ( isec_count > 0 )
00518                         mask_de_enum( decomp, isec_mask, i, cur_pos );
00519                 else 
00520                         mask_de_enum( decomp, uniq_mask, i, cur_pos );
00521                 
00522                 int min = -1;
00523                 double min_val = 1e20; //make the assumption that the min val will be less then 1e20
00524                 for (int j = 0; j < uniq_row_count; j++) {
00525                         //figure out what enumeration the current row is eqivelant to
00526                         //and add those scores into the value
00527                         long row_pos[ decomp->graph->vertex_count ];
00528                         mask_de_enum( decomp, uniq_mask, j, row_pos );
00529                         double val = 0;
00530                         for (int k = 0; k < decomp->graph->vertex_count; k++) {
00531                                 if (uniq_mask[k]) {
00532                                         val = decomp->graph->vertex_score[k][ row_pos[k] ];
00533                                         for (int l = k+1; l < decomp->graph->vertex_count; l++) {
00534                                                 if ( uniq_mask[l] ) {
00535                                                         if ( decomp->graph->matrix[k][l] ) {
00536                                                                 int offset = td_edge_offset( decomp->graph, k, l);
00537                                                                 val += decomp->graph->edge_score[ offset ][ row_pos[k] ][ row_pos[l] ];
00538                                                                 //val += td_edge_get( decomp->graph, k, l, row_pos[k], row_pos[l] );
00539                                                         }
00540                                                 }
00541                                         }
00542                                 }
00543                         }
00544                         //for each of the children, look at the child row that corresponds to the current row
00545                         for (int k = 0; k < decomp->bag_count; k++) {
00546                                 if ( decomp->bag_matrix[cur_bag][k] ) {
00547                                         int child_row_num = mask_enum( decomp, child_isec[k], cur_pos);
00548                                         if ( child_row_num != -1 )
00549                                                 val += tables[ k ][ child_row_num ].val;                                        
00550                                 }
00551                         }
00552                         if ( val < min_val ) {
00553                                 min = j;
00554                                 min_val = val;
00555                         }                               
00556                 }
00557                 tables[ cur_bag ][ i ].chosen = min;
00558                 tables[ cur_bag ][ i ].val = min_val;
00559         }
00560         
00561         for (int i = 0; i < decomp->bag_count; i++) {
00562                 if (child_isec[i] != NULL) {
00563                         free(child_isec[i]);
00564                 }
00565         }
00566         free(child_isec);
00567 }
00568 
00569 
00570 long *td_graph_decomp_solve( td_decomp *decomp  ) {
00571         if ( decomp->bag_count == 0)
00572                 return NULL;
00573         
00574         td_row **tables = (td_row **)malloc(sizeof(td_row *) * decomp->bag_count );
00575         for (int i = 0; i < decomp->bag_count; i++) {
00576                 tables[i] = NULL;
00577         }       
00578         td_graph_decomp_solve_explore( decomp, decomp->root, -1, tables );
00579         long *solution = (long *)malloc(sizeof(long) *decomp->graph->vertex_count );
00580         for (int i = 0; i <  decomp->graph->vertex_count ; i++) {
00581                 solution[i] = -1;
00582         }
00583         td_graph_decomp_extract( decomp, decomp->root, -1, tables, solution );  
00584         /*
00585         printf("solution: ");
00586         for (int i = 0; i < decomp->graph->vertex_count; i++) {
00587                 printf("%d(%d) ", i, solution[i]); 
00588         }
00589         printf("\n");   
00590          */
00591         for (int i = 0; i < decomp->bag_count; i++) {
00592                 if ( tables[i] != NULL) {
00593                         free( tables[i] );
00594                 }
00595         }       
00596         return solution;
00597 }

Generated on Wed Apr 11 16:50:50 2007 for open_prospect by  doxygen 1.4.6