00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "metislib.h"
00014
00015
00024
00025 graph_t *CompressGraph(ctrl_t *ctrl, idx_t nvtxs, idx_t *xadj, idx_t *adjncy,
00026 idx_t *vwgt, idx_t *cptr, idx_t *cind)
00027 {
00028 idx_t i, ii, iii, j, jj, k, l, cnvtxs, cnedges;
00029 idx_t *cxadj, *cadjncy, *cvwgt, *mark, *map;
00030 ikv_t *keys;
00031 graph_t *graph=NULL;
00032
00033 mark = ismalloc(nvtxs, -1, "CompressGraph: mark");
00034 map = ismalloc(nvtxs, -1, "CompressGraph: map");
00035 keys = ikvmalloc(nvtxs, "CompressGraph: keys");
00036
00037
00038 for (i=0; i<nvtxs; i++) {
00039 k = 0;
00040 for (j=xadj[i]; j<xadj[i+1]; j++)
00041 k += adjncy[j];
00042 keys[i].key = k+i;
00043 keys[i].val = i;
00044 }
00045
00046 ikvsorti(nvtxs, keys);
00047
00048 l = cptr[0] = 0;
00049 for (cnvtxs=i=0; i<nvtxs; i++) {
00050 ii = keys[i].val;
00051 if (map[ii] == -1) {
00052 mark[ii] = i;
00053 for (j=xadj[ii]; j<xadj[ii+1]; j++)
00054 mark[adjncy[j]] = i;
00055
00056 map[ii] = cnvtxs;
00057 cind[l++] = ii;
00058
00059 for (j=i+1; j<nvtxs; j++) {
00060 iii = keys[j].val;
00061
00062 if (keys[i].key != keys[j].key || xadj[ii+1]-xadj[ii] != xadj[iii+1]-xadj[iii])
00063 break;
00064
00065 if (map[iii] == -1) {
00066 for (jj=xadj[iii]; jj<xadj[iii+1]; jj++) {
00067 if (mark[adjncy[jj]] != i)
00068 break;
00069 }
00070
00071 if (jj == xadj[iii+1]) {
00072 map[iii] = cnvtxs;
00073 cind[l++] = iii;
00074 }
00075 }
00076 }
00077
00078 cptr[++cnvtxs] = l;
00079 }
00080 }
00081
00082 IFSET(ctrl->dbglvl, METIS_DBG_INFO,
00083 printf(" Compression: reduction in # of vertices: %"PRIDX".\n", nvtxs-cnvtxs));
00084
00085
00086 if (cnvtxs < COMPRESSION_FRACTION*nvtxs) {
00087
00088
00089
00090 graph = CreateGraph();
00091
00092 cnedges = 0;
00093 for (i=0; i<cnvtxs; i++) {
00094 ii = cind[cptr[i]];
00095 cnedges += xadj[ii+1]-xadj[ii];
00096 }
00097
00098
00099 cxadj = graph->xadj = imalloc(cnvtxs+1, "CompressGraph: xadj");
00100 cvwgt = graph->vwgt = ismalloc(cnvtxs, 0, "CompressGraph: vwgt");
00101 cadjncy = graph->adjncy = imalloc(cnedges, "CompressGraph: adjncy");
00102 graph->adjwgt = ismalloc(cnedges, 1, "CompressGraph: adjwgt");
00103
00104
00105 iset(nvtxs, -1, mark);
00106 l = cxadj[0] = 0;
00107 for (i=0; i<cnvtxs; i++) {
00108 mark[i] = i;
00109 for (j=cptr[i]; j<cptr[i+1]; j++) {
00110 ii = cind[j];
00111
00112
00113 cvwgt[i] += (vwgt == NULL ? 1 : vwgt[ii]);
00114
00115
00116 for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) {
00117 k = map[adjncy[jj]];
00118 if (mark[k] != i) {
00119 mark[k] = i;
00120 cadjncy[l++] = k;
00121 }
00122 }
00123 }
00124 cxadj[i+1] = l;
00125 }
00126
00127 graph->nvtxs = cnvtxs;
00128 graph->nedges = l;
00129 graph->ncon = 1;
00130
00131 SetupGraph_tvwgt(graph);
00132 SetupGraph_label(graph);
00133 }
00134
00135 gk_free((void **)&keys, &map, &mark, LTERM);
00136
00137 return graph;
00138
00139 }
00140
00141
00142
00143
00149
00150 graph_t *PruneGraph(ctrl_t *ctrl, idx_t nvtxs, idx_t *xadj, idx_t *adjncy,
00151 idx_t *vwgt, idx_t *iperm, real_t factor)
00152 {
00153 idx_t i, j, k, l, nlarge, pnvtxs, pnedges;
00154 idx_t *pxadj, *padjncy, *padjwgt, *pvwgt;
00155 idx_t *perm;
00156 graph_t *graph=NULL;
00157
00158 perm = imalloc(nvtxs, "PruneGraph: perm");
00159
00160 factor = factor*xadj[nvtxs]/nvtxs;
00161
00162 pnvtxs = pnedges = nlarge = 0;
00163 for (i=0; i<nvtxs; i++) {
00164 if (xadj[i+1]-xadj[i] < factor) {
00165 perm[i] = pnvtxs;
00166 iperm[pnvtxs++] = i;
00167 pnedges += xadj[i+1]-xadj[i];
00168 }
00169 else {
00170 perm[i] = nvtxs - ++nlarge;
00171 iperm[nvtxs-nlarge] = i;
00172 }
00173 }
00174
00175 IFSET(ctrl->dbglvl, METIS_DBG_INFO,
00176 printf(" Pruned %"PRIDX" of %"PRIDX" vertices.\n", nlarge, nvtxs));
00177
00178
00179 if (nlarge > 0 && nlarge < nvtxs) {
00180
00181 graph = CreateGraph();
00182
00183
00184 pxadj = graph->xadj = imalloc(pnvtxs+1, "PruneGraph: xadj");
00185 pvwgt = graph->vwgt = imalloc(pnvtxs, "PruneGraph: vwgt");
00186 padjncy = graph->adjncy = imalloc(pnedges, "PruneGraph: adjncy");
00187 graph->adjwgt = ismalloc(pnedges, 1, "PruneGraph: adjwgt");
00188
00189 pxadj[0] = pnedges = l = 0;
00190 for (i=0; i<nvtxs; i++) {
00191 if (xadj[i+1]-xadj[i] < factor) {
00192 pvwgt[l] = (vwgt == NULL ? 1 : vwgt[i]);
00193
00194 for (j=xadj[i]; j<xadj[i+1]; j++) {
00195 k = perm[adjncy[j]];
00196 if (k < pnvtxs)
00197 padjncy[pnedges++] = k;
00198 }
00199 pxadj[++l] = pnedges;
00200 }
00201 }
00202
00203 graph->nvtxs = pnvtxs;
00204 graph->nedges = pnedges;
00205 graph->ncon = 1;
00206
00207 SetupGraph_tvwgt(graph);
00208 SetupGraph_label(graph);
00209 }
00210 else if (nlarge > 0 && nlarge == nvtxs) {
00211 IFSET(ctrl->dbglvl, METIS_DBG_INFO,
00212 printf(" Pruning is ignored as it removes all vertices.\n"));
00213 nlarge = 0;
00214 }
00215
00216
00217 gk_free((void **)&perm, LTERM);
00218
00219 return graph;
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
00229