69 if (grid->
level == 0) {
86 static void maximal_independent_vertex_set(
SparseMatrix A,
int randomize,
int **vset,
int *nvset,
int *nzc){
87 int i, ii, j, *ia, *ja, m, n, *p =
NULL;
101 for (i = 0; i < m; i++){
103 (*vset)[i] = (*nvset)++;
104 for (j = ia[i]; j < ia[i+1]; j++){
105 if (i == ja[j])
continue;
113 for (ii = 0; ii < m; ii++){
116 (*vset)[i] = (*nvset)++;
117 for (j = ia[i]; j < ia[i+1]; j++){
118 if (i == ja[j])
continue;
130 static void maximal_independent_vertex_set_RS(
SparseMatrix A,
int randomize,
int **vset,
int *nvset,
int *nzc){
138 int i, jj, ii, *p =
NULL, j, k, *ia, *ja, m, n, gain, removed, nf = 0;
149 for (i = 0; i < m; i++) {
158 for (i = 0; i < m; i++)
162 for (ii = 0; ii < m; ii++){
171 (*vset)[i] = (*nvset)++;
172 for (j = ia[i]; j < ia[i+1]; j++){
175 if (i == jj)
continue;
183 for (k = ia[jj]; k < ia[jj+1]; k++){
184 if (jj == ja[k])
continue;
202 static void maximal_independent_edge_set(
SparseMatrix A,
int randomize,
int **matching,
int *nmatch){
203 int i, ii, j, *ia, *ja, m, n, *p =
NULL;
211 *matching =
N_GNEW(m,
int);
212 for (i = 0; i < m; i++) (*matching)[i] = i;
216 for (i = 0; i < m; i++){
217 for (j = ia[i]; j < ia[i+1]; j++){
218 if (i == ja[j])
continue;
219 if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i){
220 (*matching)[ja[j]] = i;
221 (*matching)[i] = ja[j];
228 for (ii = 0; ii < m; ii++){
230 for (j = ia[i]; j < ia[i+1]; j++){
231 if (i == ja[j])
continue;
232 if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i){
233 (*matching)[ja[j]] = i;
234 (*matching)[i] = ja[j];
245 static void maximal_independent_edge_set_heavest_edge_pernode(
SparseMatrix A,
int randomize,
int **matching,
int *nmatch){
246 int i, ii, j, *ia, *ja, m, n, *p =
NULL;
248 int first =
TRUE, jamax = 0;
257 *matching =
N_GNEW(m,
int);
258 for (i = 0; i < m; i++) (*matching)[i] = i;
266 for (i = 0; i < m; i++){
268 for (j = ia[i]; j < ia[i+1]; j++){
269 if (i == ja[j])
continue;
270 if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i){
284 (*matching)[jamax] = i;
285 (*matching)[i] = jamax;
291 for (ii = 0; ii < m; ii++){
293 if ((*matching)[i] != i)
continue;
295 for (j = ia[i]; j < ia[i+1]; j++){
296 if (i == ja[j])
continue;
297 if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i){
311 (*matching)[jamax] = i;
312 (*matching)[i] = jamax;
324 #define node_degree(i) (ia[(i)+1] - ia[(i)])
326 static void maximal_independent_edge_set_heavest_edge_pernode_leaves_first(
SparseMatrix A,
int randomize,
int **cluster,
int **clusterp,
int *ncluster){
327 int i, ii, j, *ia, *ja, m, n, *p =
NULL, q;
329 int first =
TRUE, jamax = 0;
330 int *matched, nz, ncmax = 0, nz0, nzz,k ;
341 *clusterp =
N_GNEW((m+1),
int);
344 for (i = 0; i < m; i++) matched[i] = i;
354 for (i = 0; i < m; i++){
355 if (matched[i] == MATCHED ||
node_degree(i) != 1)
continue;
357 assert(matched[q] != MATCHED);
358 matched[q] = MATCHED;
359 (*cluster)[nz++] = q;
360 for (j = ia[q]; j < ia[q+1]; j++){
361 if (q == ja[j])
continue;
363 matched[ja[j]] = MATCHED;
364 (*cluster)[nz++] = ja[j];
367 ncmax =
MAX(ncmax, nz - (*clusterp)[*ncluster]);
368 nz0 = (*clusterp)[*ncluster];
370 (*clusterp)[++(*ncluster)] = nz;
372 (*clusterp)[++(*ncluster)] = ++nz0;
374 for (k = nz0; k < nz && nzz < nz; k++){
377 (*clusterp)[++(*ncluster)] = nzz;
384 fprintf(stderr,
"%d leaves and parents for %d clusters, largest cluster = %d\n",nz, *ncluster, ncmax);
386 for (i = 0; i < m; i++){
388 if (matched[i] == MATCHED)
continue;
389 for (j = ia[i]; j < ia[i+1]; j++){
390 if (i == ja[j])
continue;
391 if (matched[ja[j]] != MATCHED && matched[i] != MATCHED){
405 matched[jamax] = MATCHED;
406 matched[i] = MATCHED;
407 (*cluster)[nz++] = i;
408 (*cluster)[nz++] = jamax;
409 (*clusterp)[++(*ncluster)] = nz;
414 for (i = 0; i < m; i++){
415 if (matched[i] == i){
416 (*cluster)[nz++] = i;
417 (*clusterp)[++(*ncluster)] = nz;
424 for (ii = 0; ii < m; ii++){
426 if (matched[i] == MATCHED ||
node_degree(i) != 1)
continue;
428 assert(matched[q] != MATCHED);
429 matched[q] = MATCHED;
430 (*cluster)[nz++] = q;
431 for (j = ia[q]; j < ia[q+1]; j++){
432 if (q == ja[j])
continue;
434 matched[ja[j]] = MATCHED;
435 (*cluster)[nz++] = ja[j];
438 ncmax =
MAX(ncmax, nz - (*clusterp)[*ncluster]);
439 nz0 = (*clusterp)[*ncluster];
441 (*clusterp)[++(*ncluster)] = nz;
443 (*clusterp)[++(*ncluster)] = ++nz0;
445 for (k = nz0; k < nz && nzz < nz; k++){
448 (*clusterp)[++(*ncluster)] = nzz;
455 fprintf(stderr,
"%d leaves and parents for %d clusters, largest cluster = %d\n",nz, *ncluster, ncmax);
457 for (ii = 0; ii < m; ii++){
460 if (matched[i] == MATCHED)
continue;
461 for (j = ia[i]; j < ia[i+1]; j++){
462 if (i == ja[j])
continue;
463 if (matched[ja[j]] != MATCHED && matched[i] != MATCHED){
477 matched[jamax] = MATCHED;
478 matched[i] = MATCHED;
479 (*cluster)[nz++] = i;
480 (*cluster)[nz++] = jamax;
481 (*clusterp)[++(*ncluster)] = nz;
486 for (i = 0; i < m; i++){
487 if (matched[i] == i){
488 (*cluster)[nz++] = i;
489 (*clusterp)[++(*ncluster)] = nz;
501 static void maximal_independent_edge_set_heavest_edge_pernode_supernodes_first(
SparseMatrix A,
int randomize,
int **cluster,
int **clusterp,
int *ncluster){
502 int i, ii, j, *ia, *ja, m, n, *p =
NULL;
504 int first =
TRUE, jamax = 0;
505 int *matched, nz, nz0;
507 int nsuper, *super =
NULL, *superp =
NULL;
517 *clusterp =
N_GNEW((m+1),
int);
520 for (i = 0; i < m; i++) matched[i] = i;
532 for (i = 0; i < nsuper; i++){
533 if (superp[i+1] - superp[i] <= 1)
continue;
534 nz0 = (*clusterp)[*ncluster];
535 for (j = superp[i]; j < superp[i+1]; j++){
536 matched[super[j]] = MATCHED;
537 (*cluster)[nz++] = super[j];
539 (*clusterp)[++(*ncluster)] = nz;
543 if (nz > nz0) (*clusterp)[++(*ncluster)] = nz;
547 for (i = 0; i < m; i++){
549 if (matched[i] == MATCHED)
continue;
550 for (j = ia[i]; j < ia[i+1]; j++){
551 if (i == ja[j])
continue;
552 if (matched[ja[j]] != MATCHED && matched[i] != MATCHED){
566 matched[jamax] = MATCHED;
567 matched[i] = MATCHED;
568 (*cluster)[nz++] = i;
569 (*cluster)[nz++] = jamax;
570 (*clusterp)[++(*ncluster)] = nz;
575 for (i = 0; i < m; i++){
576 if (matched[i] == i){
577 (*cluster)[nz++] = i;
578 (*clusterp)[++(*ncluster)] = nz;
585 for (ii = 0; ii < m; ii++){
588 if (matched[i] == MATCHED)
continue;
589 for (j = ia[i]; j < ia[i+1]; j++){
590 if (i == ja[j])
continue;
591 if (matched[ja[j]] != MATCHED && matched[i] != MATCHED){
605 matched[jamax] = MATCHED;
606 matched[i] = MATCHED;
607 (*cluster)[nz++] = i;
608 (*cluster)[nz++] = jamax;
609 (*clusterp)[++(*ncluster)] = nz;
614 for (i = 0; i < m; i++){
615 if (matched[i] == i){
616 (*cluster)[nz++] = i;
617 (*clusterp)[++(*ncluster)] = nz;
631 static int scomp(
const void *
s1,
const void *s2){
636 if ((ss1)[1] > (ss2)[1]){
638 }
else if ((ss1)[1] < (ss2)[1]){
644 static void maximal_independent_edge_set_heavest_cluster_pernode_leaves_first(
SparseMatrix A,
int csize,
645 int randomize,
int **cluster,
int **clusterp,
int *ncluster){
646 int i, ii, j, *ia, *ja, m, n, *p =
NULL, q, iv;
648 int *matched, nz, nz0, nzz,k, nv;
660 *clusterp =
N_GNEW((m+1),
int);
664 for (i = 0; i < m; i++) matched[i] = i;
675 for (ii = 0; ii < m; ii++){
677 if (matched[i] == MATCHED ||
node_degree(i) != 1)
continue;
679 assert(matched[q] != MATCHED);
680 matched[q] = MATCHED;
681 (*cluster)[nz++] = q;
682 for (j = ia[q]; j < ia[q+1]; j++){
683 if (q == ja[j])
continue;
685 matched[ja[j]] = MATCHED;
686 (*cluster)[nz++] = ja[j];
689 nz0 = (*clusterp)[*ncluster];
691 (*clusterp)[++(*ncluster)] = nz;
693 (*clusterp)[++(*ncluster)] = ++nz0;
695 for (k = nz0; k < nz && nzz < nz; k++){
698 (*clusterp)[++(*ncluster)] = nzz;
703 for (ii = 0; ii < m; ii++){
705 if (matched[i] == MATCHED)
continue;
707 for (j = ia[i]; j < ia[i+1]; j++){
708 if (i == ja[j])
continue;
709 if (matched[ja[j]] != MATCHED && matched[i] != MATCHED){
711 vlist[2*nv+1] = a[j];
716 qsort(vlist, nv,
sizeof(
real)*2, scomp);
717 for (j = 0; j <
MIN(csize - 1, nv); j++){
718 iv = (
int) vlist[2*j];
719 matched[iv] = MATCHED;
720 (*cluster)[nz++] = iv;
722 matched[i] = MATCHED;
723 (*cluster)[nz++] = i;
724 (*clusterp)[++(*ncluster)] = nz;
729 for (i = 0; i < m; i++){
730 if (matched[i] == i){
731 (*cluster)[nz++] = i;
732 (*clusterp)[++(*ncluster)] = nz;
740 static void maximal_independent_edge_set_heavest_edge_pernode_scaled(
SparseMatrix A,
int randomize,
int **matching,
int *nmatch){
741 int i, ii, j, *ia, *ja, m, n, *p =
NULL;
743 int first =
TRUE, jamax = 0;
752 *matching =
N_GNEW(m,
int);
753 for (i = 0; i < m; i++) (*matching)[i] = i;
761 for (i = 0; i < m; i++){
763 for (j = ia[i]; j < ia[i+1]; j++){
764 if (i == ja[j])
continue;
765 if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i){
767 amax = a[j]/(ia[i+1]-ia[i])/(ia[ja[j]+1]-ia[ja[j]]);
771 if (a[j]/(ia[i+1]-ia[i])/(ia[ja[j]+1]-ia[ja[j]]) > amax){
772 amax = a[j]/(ia[i+1]-ia[i])/(ia[ja[j]+1]-ia[ja[j]]);
779 (*matching)[jamax] = i;
780 (*matching)[i] = jamax;
786 for (ii = 0; ii < m; ii++){
788 if ((*matching)[i] != i)
continue;
790 for (j = ia[i]; j < ia[i+1]; j++){
791 if (i == ja[j])
continue;
792 if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i){
794 amax = a[j]/(ia[i+1]-ia[i])/(ia[ja[j]+1]-ia[ja[j]]);
798 if (a[j]/(ia[i+1]-ia[i])/(ia[ja[j]+1]-ia[ja[j]]) > amax){
799 amax = a[j]/(ia[i+1]-ia[i])/(ia[ja[j]+1]-ia[ja[j]]);
806 (*matching)[jamax] = i;
807 (*matching)[i] = jamax;
823 int *assignment =
NULL;
825 int *
id = D->
ia, jd = D->
ja;
835 irn =
N_GNEW(ncluster,
int*);
836 jcn =
N_GNEW(ncluster,
int*);
838 assignment =
N_GNEW(n,
int);
839 nz =
N_GNEW(ncluster,
int);
841 nnodes =
N_GNEW(ncluster,
int);
847 for (i = 0; i < ncluster; i++) nz[i] = 0;
848 for (i = 0; i < ncluster; i++){
849 for (j = clusterp[i]; j < clusterp[i+1]; j++){
850 assert(clusterp[i+1] > clusterp[i]);
851 assignment[cluster[j]] = i;
855 for (i = 0; i < n; i++){
857 for (j =
id[i]; j <
id[i+1]; j++){
858 if (i != jd[j] && ic == assignment[jd[j]]) {
863 for (i = 0; i < ncluster; i++) {
864 irn[i] =
N_GNEW(nz[i],
int);
865 jcn[i] =
N_GNEW(nz[i],
int);
866 val[i] =
N_GNEW(nz[i],
int);
871 for (i = 0; i < ncluster; i++) nz[i] = 0;
872 for (i = 0; i < n; i++) mask[i] = -1;
873 for (i = 0; i < ncluster; i++) nnodes[i] = -1;
874 for (i = 0; i < n; i++){
878 mask[i] = ii = nnodes[ic];
881 for (j =
id[i]; j <
id[i+1]; j++){
882 jc = assignment[jd[j]];
883 if (i != jd[j] && ic == jc) {
886 mask[jd[j]] = jj = nnodes[jc];
889 irn[ic][nz[ic]] = ii;
890 jcn[ic][nz[ic]] = jj;
891 if (d) val[ic][nz[ic]] = d[j];
896 for (i = 0; i < ncluster; i++){
904 for (i = 0; i < ncluster; i++){
905 for (j = clusterp[i]; j < clusterp[i+1]; j++){
906 assert(clusterp[i+1] > clusterp[i]);
907 irn[nzc] = cluster[j];
921 for (i = 0; i < ncluster; i++){
951 int *matching =
NULL, nmatch = 0, nc, nzc, n, i;
955 int *vset =
NULL, nvset, ncov, j;
956 int *cluster=
NULL, *clusterp=
NULL, ncluster;
971 fprintf(stderr,
"hybrid scheme, try COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_LEAVES_FIRST first\n");
974 Multilevel_coarsen_internal(A, cA, D, cD, node_wgt, cnode_wgt, P, R, ctrl, coarsen_scheme_used);
979 fprintf(stderr,
"switching to COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_SUPERNODES_FIRST\n");
982 Multilevel_coarsen_internal(A, cA, D, cD, node_wgt, cnode_wgt, P, R, ctrl, coarsen_scheme_used);
988 fprintf(stderr,
"switching to COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_CLUSTER_PERNODE_LEAVES_FIRST\n");
991 Multilevel_coarsen_internal(A, cA, D, cD, node_wgt, cnode_wgt, P, R, ctrl, coarsen_scheme_used);
997 fprintf(stderr,
"switching to COARSEN_INDEPENDENT_VERTEX_SET\n");
1000 Multilevel_coarsen_internal(A, cA, D, cD, node_wgt, cnode_wgt, P, R, ctrl, coarsen_scheme_used);
1007 fprintf(stderr,
"switching to COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE\n");
1010 Multilevel_coarsen_internal(A, cA, D, cD, node_wgt, cnode_wgt, P, R, ctrl, coarsen_scheme_used);
1018 maximal_independent_edge_set_heavest_edge_pernode_leaves_first(A, ctrl->
randomize, &cluster, &clusterp, &ncluster);
1020 maximal_independent_edge_set_heavest_edge_pernode_supernodes_first(A, ctrl->
randomize, &cluster, &clusterp, &ncluster);
1022 maximal_independent_edge_set_heavest_cluster_pernode_leaves_first(A, 4, ctrl->
randomize, &cluster, &clusterp, &ncluster);
1029 fprintf(stderr,
"nc = %d, nf = %d, minsz = %d, coarsen_factor = %f coarsening stops\n",nc, n, ctrl->
minsize, ctrl->
min_coarsen_factor);
1037 for (i = 0; i < ncluster; i++){
1038 for (j = clusterp[i]; j < clusterp[i+1]; j++){
1039 assert(clusterp[i+1] > clusterp[i]);
1040 irn[nzc] = cluster[j];
1058 if (!*cA)
goto RETURN;
1070 maximal_independent_edge_set(A, ctrl->
randomize, &matching, &nmatch);
1073 maximal_independent_edge_set_heavest_edge_pernode(A, ctrl->
randomize, &matching, &nmatch);
1076 maximal_independent_edge_set_heavest_edge_pernode_scaled(A, ctrl->
randomize, &matching, &nmatch);
1081 fprintf(stderr,
"nc = %d, nf = %d, minsz = %d, coarsen_factor = %f coarsening stops\n",nc, n, ctrl->
minsize, ctrl->
min_coarsen_factor);
1089 for (i = 0; i < n; i++){
1090 if (matching[i] >= 0){
1091 if (matching[i] == i){
1099 irn[nzc] = matching[i];
1102 matching[matching[i]] = -1;
1118 if (!*cA)
goto RETURN;
1133 maximal_independent_vertex_set(A, ctrl->
randomize, &vset, &nvset, &nzc);
1135 maximal_independent_vertex_set_RS(A, ctrl->
randomize, &vset, &nvset, &nzc);
1143 fprintf(stderr,
"nc = %d, nf = %d, minsz = %d, coarsen_factor = %f coarsening stops\n",nc, n, ctrl->
minsize, ctrl->
min_coarsen_factor);
1151 for (i = 0; i < n; i++){
1154 for (j = ia[i]; j < ia[i+1]; j++){
1160 for (j = ia[i]; j < ia[i+1]; j++){
1163 jcn[nzc] = vset[ja[j]];
1164 val[nzc++] = 1./(double) ncov;
1178 if (!*cA)
goto RETURN;
1190 if (matching)
FREE(matching);
1191 if (vset)
FREE(vset);
1197 if(cluster)
FREE(cluster);
1198 if(clusterp)
FREE(clusterp);
1212 node_wgt = cnode_wgt0;
1213 Multilevel_coarsen_internal(A, &cA0, D, &cD0, node_wgt, &cnode_wgt0, &P0, &R0, ctrl, coarsen_scheme_used);
1217 if (
Verbose) fprintf(stderr,
"nc=%d n = %d\n",nc,n);
1239 if (*cnode_wgt)
FREE(*cnode_wgt);
1240 *cnode_wgt = cnode_wgt0;
1243 node_wgt = cnode_wgt0;
1251 for (i = 0; i < n; i++) fputs (
" ", stderr);
1255 int coarsen_scheme_used;
1262 fprintf(stderr,
"level -- %d, n = %d, nz = %d nz/n = %f\n", grid->
level, grid->
n, grid->
A->
nz, grid->
A->
nz/(
double) grid->
n);
1271 fprintf(stderr,
" maxlevel reached, coarsening stops\n");
1277 if (!cA)
return grid;
1279 cgrid = Multilevel_init(cA, cD, cnode_weights);
1289 cgrid = Multilevel_establish(cgrid, ctrl);
1305 grid = Multilevel_init(A, D, node_weights);
1306 grid = Multilevel_establish(grid, ctrl);
void s1(graph_t *, node_t *)
SparseMatrix SparseMatrix_multiply3(SparseMatrix A, SparseMatrix B, SparseMatrix C)
void Multilevel_coarsen(SparseMatrix A, SparseMatrix *cA, SparseMatrix D, SparseMatrix *cD, real *node_wgt, real **cnode_wgt, SparseMatrix *P, SparseMatrix *R, Multilevel_control ctrl, int *coarsen_scheme_used)
SparseMatrix SparseMatrix_symmetrize_nodiag(SparseMatrix A, int pattern_symmetric_only)
Multilevel Multilevel_get_coarsest(Multilevel grid)
PriorityQueue PriorityQueue_push(PriorityQueue q, int i, int gain)
int PriorityQueue_remove(PriorityQueue q, int i)
SparseMatrix SparseMatrix_remove_diagonal(SparseMatrix A)
void SparseMatrix_decompose_to_supervariables(SparseMatrix A, int *ncluster, int **cluster, int **clusterp)
int SparseMatrix_is_symmetric(SparseMatrix A, int test_pattern_symmetry_only)
Multilevel Multilevel_new(SparseMatrix A0, SparseMatrix D0, real *node_weights, Multilevel_control ctrl)
void SparseMatrix_multiply_vector(SparseMatrix A, real *v, real **res, int transposed)
void Multilevel_control_delete(Multilevel_control ctrl)
SparseMatrix DistanceMatrix_restrict_filtering(int *mask, int is_C, int is_F, SparseMatrix D)
SparseMatrix DistanceMatrix_restrict_cluster(int ncluster, int *clusterp, int *cluster, SparseMatrix P, SparseMatrix R, SparseMatrix D)
int * random_permutation(int n)
void print_padding(int n)
SparseMatrix DistanceMatrix_restrict_matching(int *matching, SparseMatrix D)
#define SparseMatrix_set_pattern_symmetric(A)
SparseMatrix SparseMatrix_get_real_adjacency_matrix_symmetrized(SparseMatrix A)
Multilevel_control Multilevel_control_new(int scheme, int mode)
PriorityQueue PriorityQueue_new(int n, int ngain)
void SparseMatrix_delete(SparseMatrix A)
if(aagss+aagstacksize-1<=aagssp)
SparseMatrix SparseMatrix_from_coordinate_arrays(int nz, int m, int n, int *irn, int *jcn, void *val0, int type, size_t sz)
EXTERN unsigned char Verbose
SparseMatrix SparseMatrix_multiply(SparseMatrix A, SparseMatrix B)
int PriorityQueue_pop(PriorityQueue q, int *i, int *gain)
void PriorityQueue_delete(PriorityQueue q)
#define SparseMatrix_known_strucural_symmetric(A)
SparseMatrix SparseMatrix_divide_row_by_degree(SparseMatrix A)
int PriorityQueue_get_gain(PriorityQueue q, int i)
#define SparseMatrix_set_symmetric(A)
SparseMatrix SparseMatrix_transpose(SparseMatrix A)
void Multilevel_delete(Multilevel grid)