Main Page | Alphabetical List | Class List | File List | Class Members | File Members

bary_functions.c

Go to the documentation of this file.
00001 #include "bary.h"
00002 #include <stdlib.h>
00003 #define STATIC 
00004 
00005 
00006 STATIC int compare_bary 
00007 (const GNODE * a, const GNODE * b)
00008 { 
00009     if ((((*a)->bary) == 0.0) || (((*b)->bary) == 0.0)) return (0); 
00010     if (((*a)->bary) > ((*b)->bary)) return (1); 
00011     if (((*a)->bary) < ((*b)->bary)) return (-1); 
00012     return (0);
00013 }
00014 
00015 
00016 
00017 //resort_up_down_layer and resort_down_up_layer could be merged if we know what operation to perform first :
00018 //add in a direction parameter, and if the direction is up, go up, else go down. 
00019 STATIC void resort_up_down_layer (int level)
00020 { int change; int i; change = 1;
00021  if (level > 0) { for (i = level - 1; i >= 0; i--) {// INDEX2
00022      change = resort_up_layer (i); // branch up
00023      if (!change) break; } }
00024  if (level <= maxdepth) { for (i = level; i <= maxdepth; i++) {// INDEX1
00025      change = resort_down_layer (i); // branch down
00026      if (!change) break; } }}
00027 
00028 STATIC void resort_down_up_layer (int level)
00029 { int change; int i; change = 1;
00030  if (level <= maxdepth) { for (i = level; i <= maxdepth; i++) { // INDEX1
00031      change = resort_down_layer (i); // branch down
00032      if (!change) break; } }
00033  if (level > 0) { for (i = level - 1; i >= 0; i--) {// INDEX2
00034      change = resort_up_layer (i); // brach up
00035      if (!change) break; } }
00036 }
00037 
00038 
00039 /*
00040   SORT THE SUCCLIST by the nhorder field
00041 
00042   get the succ list from a node in the layer
00043   for each item :
00044        fill the sort array
00045        set the bary field from the nhorder field
00046   sort the array by bary
00047   put the array back into the succ list, but in a sorted order
00048  */
00049 void apply_horder (int i)
00050 { 
00051     GNLIST hn; 
00052     int j;
00053     hn = ((tmp_layer[i]).succlist); 
00054     j = 0; 
00055 
00056     while (hn)     { 
00057         if (((((hn)->node))->nhorder) >= 0) 
00058         { 
00059             sort_array[j++] = ((hn)->node); 
00060             ((((hn)->node))->bary) = ((((hn)->node))->nhorder); 
00061         } 
00062         hn = ((hn)->next); 
00063     } 
00064     if (j) qsort (sort_array, j, sizeof (GNODE), (int (*)(const void *, const void *)) compare_bary); 
00065     hn = ((tmp_layer[i]).succlist); 
00066     j = 0; 
00067 
00068     while (hn) { 
00069         if (((((hn)->node))->nhorder) >= 0) 
00070             ((hn)->node) = sort_array[j++]; 
00071         hn = ((hn)->next); 
00072     }
00073 }
00074 
00075 
00076 
00077 //recursive function
00078 //calculates bary for horder functions
00079 
00080 STATIC void mark_all_nodes (GNODE node, int i)
00081 {
00082     ADJEDGE e;
00083     if (((node)->bary)) return; 
00084     if (((node)->nhorder) >= 0)
00085         ((node)->bary) = (float) i *(float) (max_horder_num + 1) + (float) ((node)->nhorder); 
00086     else 
00087         ((node)->bary) = (float) i *(float) (max_horder_num + 1); 
00088     e = ((node)->succ); 
00089     while (e) { 
00090         mark_all_nodes ((((((e)->kante))->end)), i); 
00091         e = ((e)->next); 
00092     } 
00093 
00094     e = ((node)->pred); 
00095     while (e) { 
00096         mark_all_nodes ((((((e)->kante))->start)), i); 
00097         e = ((e)->next); 
00098     }
00099 
00100 }
00101 
00102 STATIC void phase1_down (void){ 
00103     int i;
00104     gs_wait_message ('b'); 
00105     for (i = 0; i <= maxdepth; i++) 
00106         (void) resort_down_layer (i);
00107 }
00108 
00109 STATIC void phase1_up (void){ 
00110     int i;
00111     gs_wait_message ('b'); 
00112     for (i = maxdepth; i >= 0; i--)
00113         (void) resort_up_layer (i);
00114 }
00115 
00116 
00117 
00118 
00119 // cycle/rotates the array!
00120 // this has got to be slow!
00121 // siz > j
00122 // sort_array
00123 
00124 // j goes from 0 to the size of the layer
00125 // 
00126 STATIC int cycle_sort_array (int siz)
00127 { 
00128     int j, k; 
00129     int original_sit; 
00130     int start_region; 
00131     GNODE h; 
00132     original_sit = 1; // is there no change?
00133     start_region = -1;  // is there a run
00134     for (j = 0; j < siz - 1; j++) { 
00135 
00136         // is there a run in the array?
00137         if (((sort_array[j])->bary) == ((sort_array[j + 1])->bary)) { 
00138 
00139             // set the start region to be the beginning of the run
00140             if (start_region == -1) 
00141                 start_region = j; 
00142         } 
00143         else if (start_region != -1) // there is a run already?
00144         { 
00145             // void runsort(j,start_region,original_sit) 
00146             h = sort_array[j]; 
00147 
00148             //k=j .down.to..> start region
00149             for (k = j; k > start_region; k--) 
00150                 sort_array[k] = sort_array[k - 1]; 
00151 
00152             sort_array[start_region] = h; // the beginning of the start region
00153         
00154             // set the flag
00155             start_region = -1; 
00156             original_sit = 0; 
00157 
00158         } 
00159     } 
00160 
00161     if (start_region != -1) 
00162     { 
00163         // void runsort(j,start_region,original_sit) 
00164         h = sort_array[j]; 
00165         for (k = j; k > start_region; k--) 
00166             sort_array[k] = sort_array[k - 1]; 
00167         sort_array[start_region] = h; 
00168         original_sit = 0; 
00169     } 
00170 
00171     return (!original_sit);
00172 }
00173 
00174 
00175 
00176 // uses a set of temp variables :
00177 // 1. weights per edge
00178 // 2. marking
00179 // these variables can be stored in a vector and disposed of easier than with a list
00180 // uses list traversals, these can also be represented with an array.
00181 // todo : create an iterator abstraction so that the representation can be abstracted.
00182 STATIC void tree_horizontal_order (void)
00183 { 
00184     GNLIST li; 
00185     int i, prio; 
00186     GNODE node; 
00187     ADJEDGE a; 
00188     GEDGE e; 
00189     double maxbary;
00190 
00191     //  init each layer, following the succ list , setting the weights to 0
00192     for (i = 0; i <= maxdepth + 1; i++){  
00193         // for each successor in the list 1
00194         li = ((tmp_layer[i]).succlist);  // for each layer
00195         while (li){ 
00196             a = li->node->succ;
00197             while (a){ a->kante->weights=0;a = a->next; }  // follow the next in the succ list of the node
00198             li = li->next; 
00199         } // follow the next in the succ list of the layer
00200     }
00201 
00202 // for each depth, and in the order of priority,
00203 // visit each node in the graph
00204 // get each edge, and the end of the edge,
00205 // mark the node if not marked, and the set the weight edge to 1
00206 
00207     for (i = 0; i <= maxdepth + 1; i++) { 
00208         for (prio = max_eprio; prio >= 0; prio--) {  // for each prio
00209         // for each successor in the list 2
00210             li = ((tmp_layer[i]).succlist);  // start to follow the succ list
00211             while (li) { 
00212                 a = ((((li)->node))->succ); // follow the node succ list
00213                 while (a) { 
00214                     e = ((a)->kante); 
00215                     if (((e)->priority) == prio) { // check the priority
00216                         node = (((((a)->kante))->end));  // get the end node
00217                         if (!((node)->markiert)) { 
00218                             ((node)->markiert) = 1;  // mark the node
00219                             ((e)->weights) = 1; // set the weights to 1
00220                         } 
00221                     } 
00222                     a = ((a)->next); 
00223                 } 
00224                 li = ((li)->next); 
00225             }
00226         }
00227     }
00228  
00229     // second passs
00230     for (i = 1; i <= maxdepth + 1; i++) { 
00231         level_to_array (i, 'd');  // convers the level to an array
00232         maxbary = 0.1; 
00233 
00234         // for each successor in the list 3
00235         li = ((tmp_layer[i]).succlist); 
00236         while (li) { 
00237             node = ((li)->node); 
00238             ((node)->bary) = predbary (node);  // calc the predbary
00239             if (((node)->bary) > maxbary) maxbary = ((node)->bary); // calc the maxbary 
00240             li = ((li)->next); 
00241         }
00242 
00243         maxbary = maxbary + 1.0; 
00244 
00245         // for each successor in the list 4
00246         li = ((tmp_layer[i - 1]).succlist); 
00247         while (li) { 
00248             a = ((((li)->node))->succ); 
00249             while (a) { 
00250                 e = ((a)->kante); 
00251                 if (((e)->weights)) { // marked by this algorithm
00252                     node = (((((a)->kante))->end)); 
00253                     ((node)->bary) = (double) (((((li)->node))->position)) + ((node)->bary) / maxbary;  // scale the bary down by the max and the position
00254                 } 
00255                 a = ((a)->next); 
00256             } 
00257             li = ((li)->next); 
00258         } 
00259         
00260         
00261         if (((layer[i]).anz)) 
00262             qsort (sort_array, ((layer[i]).anz), sizeof (GNODE), (int (*)(const void *, const void *)) compare_bary); 
00263     } 
00264     array_to_level (i); 
00265     
00266     // set the marking to 0
00267     for (i = 0; i <= maxdepth + 1; i++) 
00268     { 
00269         li = ((tmp_layer[i]).succlist); 
00270         while (li) { 
00271             ((((li)->node))->markiert) = 0; li = ((li)->next); 
00272         } 
00273     } 
00274 
00275     // copy the layers from tmp to main
00276     copy_layers (layer, tmp_layer);
00277 }
00278 
00279 STATIC void unmerge_connected_parts (void){ 
00280     GNLIST li; 
00281     int i, j; 
00282     int part_is_missing; 
00283     GNODE node; int act_graph;
00284 
00285 
00286     // set bary to 0
00287     for (i = 0; i <= maxdepth + 1; i++) { 
00288         li = ((tmp_layer[i]).succlist); 
00289         while (li) { 
00290             ((((li)->node))->bary) = 0; li = ((li)->next); 
00291         } 
00292     } 
00293     act_graph = 1; 
00294     part_is_missing = 1; 
00295     while (part_is_missing) { 
00296         gs_wait_message ('u'); part_is_missing = 0; node = (GNODE) 0; act_graph++; 
00297         for (i = 0; i <= maxdepth + 1; i++) { 
00298             li = ((layer[i]).succlist); 
00299             while (li) { 
00300                 if (((((li)->node))->bary) == 0) { 
00301                     node = ((li)->node); break; 
00302                 } 
00303                 li = ((li)->next); 
00304             } 
00305             if (node) break; 
00306         } 
00307         if (node) { 
00308             part_is_missing = 1; mark_all_nodes (node, act_graph); 
00309         } 
00310     } 
00311     for (i = 0; i <= maxdepth + 1; i++) { 
00312         li = ((tmp_layer[i]).succlist); j = 0; 
00313         while (li) { 
00314             sort_array[j++] = ((li)->node); li = ((li)->next); 
00315         } 
00316         
00317         if (((layer[i]).anz)) qsort (sort_array, ((layer[i]).anz), sizeof (GNODE), (int (*)(const void *, const void *)) compare_bary); 
00318         array_to_level (i); 
00319     } 
00320     copy_layers (layer, tmp_layer);
00321 }
00322 
00323 int mark_all_nodes_merger;
00324 
00325 
00326 static void copy_layers (DEPTH * l1, DEPTH * l2)
00327 { 
00328     int i; 
00329     GNLIST h1, h2; 
00330     for (i = 0; i <= maxdepth + 1; i++) 
00331     { 
00332         ((l1[i]).cross) = ((l2[i]).cross); 
00333         h1 = ((l1[i]).succlist); 
00334         h2 = ((l2[i]).succlist); 
00335         if (((l1[i]).anz) == ((l2[i]).anz)) 
00336         { 
00337             while (h2) { 
00338                 ((h1)->node) = ((h2)->node); 
00339                 h1 = ((h1)->next); 
00340                 h2 = ((h2)->next); 
00341             } 
00342         } 
00343         else 
00344         { 
00345             while (h2) { 
00346                 ((h1)->node) = ((h2)->node); 
00347                 h2 = ((h2)->next); 
00348                 if (h2 && !((h1)->next)) 
00349                     ((h1)->next) = tmpnodelist_alloc (); 
00350                 h1 = ((h1)->next); 
00351             } 
00352             ((l1[i]).anz) = ((l2[i]).anz); 
00353         } 
00354     }
00355 }
00356 
00357 
00358 STATIC void save_level (int i){ 
00359     int j; GNLIST hn; ; j = 0; 
00360     hn = ((tmp_layer[i]).succlist); 
00361     while (hn) { 
00362         save_array[j++] = ((hn)->node); 
00363         hn = ((hn)->next); 
00364     } 
00365 }
00366 
00367 STATIC void restore_level (int i){
00368     int j; GNLIST hn; ; j = 0; 
00369     hn = ((tmp_layer[i]).succlist); 
00370     while (hn) { 
00371         ((hn)->node) = save_array[j++]; 
00372         hn = ((hn)->next); 
00373     }
00374 }
00375 
00376 STATIC int have_alternative;
00377 STATIC int phase1_allowed; 
00378 STATIC void  init_barycentering (void){ 
00379     have_alternative = 0; 
00380     phase1_allowed = 1;
00381 }
00382 
00383 void barycentering (void)
00384 {
00385     int alt; 
00386     int cross; 
00387     int changed; 
00388     int tmp_startlevel, alt_startlevel; 
00389     tmp_startlevel = alt_startlevel = 0; 
00390     changed = 1; 
00391     while (phase1_allowed && changed) 
00392     { 
00393         nr_bary_iterations++; 
00394         if (nr_bary_iterations >= max_baryiterations) 
00395         { 
00396             gs_wait_message ('t'); 
00397             break; 
00398         } 
00399         if (G_timelimit > 0) if (test_timelimit (60))  
00400         { 
00401             gs_wait_message ('t'); 
00402             break; 
00403         } 
00404         changed = 0; 
00405         phase1_down (); 
00406         cross = graph_crossings (); 
00407         alt = 0; 
00408         if ((cross < nr_crossings) || (nr_bary_iterations < min_baryiterations))  
00409         { 
00410             changed = 1; 
00411             copy_layers (layer, tmp_layer); 
00412             nr_crossings = cross; 
00413             alt_startlevel = tmp_startlevel;        
00414         } 
00415         else if (have_alternative)  
00416         { 
00417             copy_layers (tmp_layer, layer); 
00418             phase1_down (); 
00419             cross = graph_crossings (); 
00420             if (cross < nr_crossings)  
00421             { 
00422                 changed = 1; 
00423                 copy_layers (layer, tmp_layer); 
00424                 nr_crossings = cross; 
00425                 alt_startlevel = tmp_startlevel; 
00426             } 
00427             else if (cross > nr_crossings)  
00428             { 
00429                 copy_layers (tmp_layer, layer); 
00430                 tmp_startlevel = alt_startlevel; 
00431             } 
00432             else 
00433                 alt = 1; 
00434         } else if (cross == nr_crossings) 
00435             alt = 1; 
00436         else  
00437         {          
00438             copy_layers (tmp_layer, layer); 
00439             tmp_startlevel = alt_startlevel; 
00440         } 
00441         have_alternative = alt; 
00442         phase1_up (); 
00443         cross = graph_crossings (); 
00444         alt = 0; 
00445         if ((cross < nr_crossings) || (nr_bary_iterations < min_baryiterations))  
00446         {          
00447             changed = 1;     
00448             copy_layers (layer, tmp_layer); 
00449             nr_crossings = cross; 
00450             alt_startlevel = tmp_startlevel; 
00451         } 
00452         else if (have_alternative)  
00453         { 
00454             copy_layers (tmp_layer, layer); 
00455             phase1_up (); 
00456             cross = graph_crossings (); 
00457             if (cross < nr_crossings)  
00458             { 
00459                 changed = 1;                
00460                 copy_layers (layer, tmp_layer); 
00461                 nr_crossings = cross; 
00462                 alt_startlevel = tmp_startlevel; 
00463             } 
00464             else if (cross > nr_crossings)  
00465             { 
00466                 copy_layers (tmp_layer, layer); 
00467                 tmp_startlevel = alt_startlevel;                
00468             } 
00469             else 
00470                 alt = 1; 
00471         } else if (cross == nr_crossings) 
00472             alt = 1; 
00473         else  
00474         {           
00475             copy_layers (tmp_layer, layer); 
00476             tmp_startlevel = alt_startlevel; 
00477         } 
00478         have_alternative = alt; 
00479 
00480         if (nr_crossings == 0) 
00481             return; 
00482  
00483     } 
00484     if (nr_crossings == 0) 
00485         return; 
00486  
00487     if (skip_baryphase2) 
00488         return; 
00489  
00490     phase1_allowed = 0; 
00491     tmp_startlevel = alt_startlevel = 0; 
00492     changed = 1; 
00493     while (changed)  
00494     { 
00495         nr_bary_iterations++; 
00496         if (nr_bary_iterations >= max_baryiterations)  
00497         { 
00498             gs_wait_message ('t'); 
00499             break; 
00500         } 
00501         if (G_timelimit > 0) if (test_timelimit (60))  
00502         { 
00503             gs_wait_message ('t'); 
00504             break; 
00505         } 
00506         changed = 0; 
00507         phase2_startlevel = tmp_startlevel; 
00508         phase2_down (); 
00509         tmp_startlevel = phase2_startlevel; 
00510         
00511         if (tmp_startlevel > maxdepth) tmp_startlevel = 0; 
00512         cross = graph_crossings (); 
00513         alt = 0; 
00514         
00515         if (cross < nr_crossings)  
00516         { 
00517             changed = 1; 
00518             copy_layers (layer, tmp_layer); 
00519             nr_crossings = cross; 
00520             alt_startlevel = tmp_startlevel; 
00521         } 
00522         else if (have_alternative)  
00523         { 
00524             copy_layers (tmp_layer, layer); 
00525             phase2_startlevel = tmp_startlevel = alt_startlevel; 
00526             phase2_down (); 
00527             tmp_startlevel = phase2_startlevel; 
00528             if (tmp_startlevel > maxdepth) tmp_startlevel = 0; 
00529             cross = graph_crossings (); 
00530             if (cross < nr_crossings)  
00531             { 
00532                 changed = 1; 
00533                 copy_layers (layer, tmp_layer); 
00534                 nr_crossings = cross; 
00535                 alt_startlevel = tmp_startlevel; 
00536             } 
00537             else if (cross > nr_crossings)  
00538             { 
00539                 copy_layers (tmp_layer, layer); 
00540                 tmp_startlevel = alt_startlevel; 
00541             } 
00542             else alt = 1; 
00543         } else if (cross == nr_crossings) alt = 1; 
00544         else  
00545         {          
00546             copy_layers (tmp_layer, layer);         
00547             tmp_startlevel = alt_startlevel; 
00548         } 
00549         have_alternative = alt; 
00550         
00551         if (nr_crossings == 0) 
00552             return;     
00553     } 
00554 
00555     tmp_startlevel = alt_startlevel = maxdepth + 1; 
00556     changed = 1; 
00557     while (changed)  
00558     { 
00559         nr_bary_iterations++; 
00560         if (nr_bary_iterations >= max_baryiterations)  
00561         { 
00562             gs_wait_message ('t'); 
00563             break; 
00564         } if (G_timelimit > 0) if (test_timelimit (60))  
00565         { 
00566             gs_wait_message ('t'); 
00567             break; 
00568         } changed = 0; 
00569         phase2_startlevel = tmp_startlevel; 
00570         phase2_up (); 
00571         tmp_startlevel = phase2_startlevel; 
00572         if (tmp_startlevel < 0) tmp_startlevel = maxdepth; 
00573         cross = graph_crossings (); 
00574         alt = 0; 
00575         if (cross < nr_crossings)  
00576         { 
00577             changed = 1; 
00578             copy_layers (layer, tmp_layer); 
00579             nr_crossings = cross; 
00580             alt_startlevel = tmp_startlevel; 
00581         } else if (have_alternative)    { 
00582 
00583             copy_layers (tmp_layer, layer); 
00584             phase2_startlevel = tmp_startlevel = alt_startlevel; 
00585             phase2_up (); 
00586             tmp_startlevel = phase2_startlevel; 
00587             if (tmp_startlevel < 0) tmp_startlevel = maxdepth; 
00588             cross = graph_crossings (); 
00589             if (cross < nr_crossings)  
00590             { 
00591                 changed = 1; 
00592                 copy_layers (layer, tmp_layer); 
00593                 nr_crossings = cross; 
00594                 alt_startlevel = tmp_startlevel; 
00595             } 
00596             else if (cross > nr_crossings)  
00597             { 
00598                 copy_layers (tmp_layer, layer); 
00599                 tmp_startlevel = alt_startlevel; 
00600             } 
00601             else 
00602                 alt = 1; 
00603         } else if (cross == nr_crossings) alt = 1; 
00604         else  
00605         { 
00606             copy_layers (tmp_layer, layer); 
00607             tmp_startlevel = alt_startlevel; 
00608         } 
00609         have_alternative = alt; 
00610         if (nr_crossings == 0) 
00611             return; 
00612     }
00613 }

Generated on Sat Aug 6 11:49:18 2005 for VCGIntrospector by doxygen 1.3.6