/* maximizeGain.c */
#include "../Tree.h"
/*--------------------------------------------------------------------*/
/*
-------------------------------------------------------
purpose --
given a gain value assigned to each node,
find a set of nodes, no two in a child-ancestor
relationship, that maximizes the total gain.
this problem arises in finding the optimal domain/schur
complement partition for a semi-implicit factorization.
created -- 98jun20, cca
-------------------------------------------------------
*/
IV *
Tree_maximizeGainIV (
Tree *tree,
IV *gainIV,
int *ptotalgain,
int msglvl,
FILE *msgFile
) {
char *mark ;
int I, J, K, n, ndom, sum, totalgain ;
int *compids, *fch, *gain, *par, *sib, *subtreeGain ;
IV *compidsIV ;
/*
---------------
check the input
---------------
*/
if ( tree == NULL || gainIV == NULL || ptotalgain == NULL
|| (msglvl > 0 && msgFile == NULL) ) {
fprintf(stderr, "\n fatal error in Tree_maximizeGainIV()"
"\n bad input\n") ;
exit(-1) ;
}
n = tree->n ;
par = tree->par ;
fch = tree->fch ;
sib = tree->sib ;
if ( n != IV_size(gainIV) ) {
fprintf(stderr, "\n fatal error in Tree_maximizeGainIV()"
"\n tree size = %d, gain size = %d",
tree->n, IV_size(gainIV)) ;
exit(-1) ;
}
gain = IV_entries(gainIV) ;
/*
--------------------------------------------------
compute the subtree gains and mark candidate roots
--------------------------------------------------
*/
mark = CVinit(n, 'N') ;
subtreeGain = IVinit(n, 0) ;
for ( J = Tree_postOTfirst(tree) ;
J != -1 ;
J = Tree_postOTnext(tree, J) ) {
if ( fch[J] == -1 ) {
mark[J] = 'R' ;
subtreeGain[J] = gain[J] ;
} else {
for ( I = fch[J], sum = 0 ; I != -1 ; I = sib[I] ) {
sum += subtreeGain[I] ;
}
if ( gain[J] >= sum ) {
subtreeGain[J] = gain[J] ;
mark[J] = 'R' ;
} else {
subtreeGain[J] = sum ;
}
}
}
/*
----------------------
compute the total gain
----------------------
*/
for ( J = tree->root, totalgain = 0 ; J != -1 ; J = sib[J] ) {
totalgain += subtreeGain[J] ;
}
*ptotalgain = totalgain ;
/*
----------------------------------------------
create and initialize the component ids vector
----------------------------------------------
*/
compidsIV = IV_new() ;
IV_init(compidsIV, n, NULL) ;
IV_fill(compidsIV, 0) ;
compids = IV_entries(compidsIV) ;
/*
----------------------------------------------
fix the component ids of the nodes in the tree
----------------------------------------------
*/
for ( J = Tree_preOTfirst(tree), ndom = 0 ;
J != -1 ;
J = Tree_preOTnext(tree, J) ) {
if ( mark[J] == 'R' ) {
if ( (K = par[J]) != -1 && compids[K] != 0 ) {
compids[J] = compids[K] ;
} else {
compids[J] = ++ndom ;
}
} else if ( (K = par[J]) != -1 ) {
compids[J] = compids[K] ;
}
}
/*
------------------------
free the working storage
------------------------
*/
IVfree(subtreeGain) ;
CVfree(mark) ;
return(compidsIV) ; }
/*--------------------------------------------------------------------*/
syntax highlighted by Code2HTML, v. 0.9.1