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