00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "metislib.h"
00016
00017
00018
00019
00020
00021 void ConstructSeparator(ctrl_t *ctrl, graph_t *graph)
00022 {
00023 idx_t i, j, k, nvtxs, nbnd;
00024 idx_t *xadj, *where, *bndind;
00025
00026 WCOREPUSH;
00027
00028 nvtxs = graph->nvtxs;
00029 xadj = graph->xadj;
00030 nbnd = graph->nbnd;
00031 bndind = graph->bndind;
00032
00033 where = icopy(nvtxs, graph->where, iwspacemalloc(ctrl, nvtxs));
00034
00035
00036 for (i=0; i<nbnd; i++) {
00037 j = bndind[i];
00038 if (xadj[j+1]-xadj[j] > 0)
00039 where[j] = 2;
00040 }
00041
00042 FreeRData(graph);
00043
00044 Allocate2WayNodePartitionMemory(ctrl, graph);
00045 icopy(nvtxs, where, graph->where);
00046
00047 WCOREPOP;
00048
00049 ASSERT(IsSeparable(graph));
00050
00051 Compute2WayNodePartitionParams(ctrl, graph);
00052
00053 ASSERT(CheckNodePartitionParams(graph));
00054
00055 FM_2WayNodeRefine2Sided(ctrl, graph, 1);
00056 FM_2WayNodeRefine1Sided(ctrl, graph, 4);
00057
00058 ASSERT(IsSeparable(graph));
00059
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069 void ConstructMinCoverSeparator(ctrl_t *ctrl, graph_t *graph)
00070 {
00071 idx_t i, ii, j, jj, k, l, nvtxs, nbnd, bnvtxs[3], bnedges[2], csize;
00072 idx_t *xadj, *adjncy, *bxadj, *badjncy;
00073 idx_t *where, *bndind, *bndptr, *vmap, *ivmap, *cover;
00074
00075 WCOREPUSH;
00076
00077 nvtxs = graph->nvtxs;
00078 xadj = graph->xadj;
00079 adjncy = graph->adjncy;
00080
00081 nbnd = graph->nbnd;
00082 bndind = graph->bndind;
00083 bndptr = graph->bndptr;
00084 where = graph->where;
00085
00086 vmap = iwspacemalloc(ctrl, nvtxs);
00087 ivmap = iwspacemalloc(ctrl, nbnd);
00088 cover = iwspacemalloc(ctrl, nbnd);
00089
00090 if (nbnd > 0) {
00091
00092 bnvtxs[0] = bnvtxs[1] = bnedges[0] = bnedges[1] = 0;
00093 for (i=0; i<nbnd; i++) {
00094 j = bndind[i];
00095 k = where[j];
00096 if (xadj[j+1]-xadj[j] > 0) {
00097 bnvtxs[k]++;
00098 bnedges[k] += xadj[j+1]-xadj[j];
00099 }
00100 }
00101
00102 bnvtxs[2] = bnvtxs[0]+bnvtxs[1];
00103 bnvtxs[1] = bnvtxs[0];
00104 bnvtxs[0] = 0;
00105
00106 bxadj = iwspacemalloc(ctrl, bnvtxs[2]+1);
00107 badjncy = iwspacemalloc(ctrl, bnedges[0]+bnedges[1]+1);
00108
00109
00110 ASSERT(iset(nvtxs, -1, vmap) == vmap);
00111 for (i=0; i<nbnd; i++) {
00112 j = bndind[i];
00113 k = where[j];
00114 if (xadj[j+1]-xadj[j] > 0) {
00115 vmap[j] = bnvtxs[k];
00116 ivmap[bnvtxs[k]++] = j;
00117 }
00118 }
00119
00120
00121 bnvtxs[1] = bnvtxs[0];
00122 bnvtxs[0] = 0;
00123 bxadj[0] = l = 0;
00124 for (k=0; k<2; k++) {
00125 for (ii=0; ii<nbnd; ii++) {
00126 i = bndind[ii];
00127 if (where[i] == k && xadj[i] < xadj[i+1]) {
00128 for (j=xadj[i]; j<xadj[i+1]; j++) {
00129 jj = adjncy[j];
00130 if (where[jj] != k) {
00131 ASSERT(bndptr[jj] != -1);
00132 ASSERTP(vmap[jj] != -1, ("%"PRIDX" %"PRIDX" %"PRIDX"\n", jj, vmap[jj], graph->bndptr[jj]));
00133 badjncy[l++] = vmap[jj];
00134 }
00135 }
00136 bxadj[++bnvtxs[k]] = l;
00137 }
00138 }
00139 }
00140
00141 ASSERT(l <= bnedges[0]+bnedges[1]);
00142
00143 MinCover(bxadj, badjncy, bnvtxs[0], bnvtxs[1], cover, &csize);
00144
00145 IFSET(ctrl->dbglvl, METIS_DBG_SEPINFO,
00146 printf("Nvtxs: %6"PRIDX", [%5"PRIDX" %5"PRIDX"], Cut: %6"PRIDX", SS: [%6"PRIDX" %6"PRIDX"], Cover: %6"PRIDX"\n", nvtxs, graph->pwgts[0], graph->pwgts[1], graph->mincut, bnvtxs[0], bnvtxs[1]-bnvtxs[0], csize));
00147
00148 for (i=0; i<csize; i++) {
00149 j = ivmap[cover[i]];
00150 where[j] = 2;
00151 }
00152 }
00153 else {
00154 IFSET(ctrl->dbglvl, METIS_DBG_SEPINFO,
00155 printf("Nvtxs: %6"PRIDX", [%5"PRIDX" %5"PRIDX"], Cut: %6"PRIDX", SS: [%6"PRIDX" %6"PRIDX"], Cover: %6"PRIDX"\n", nvtxs, graph->pwgts[0], graph->pwgts[1], graph->mincut, (idx_t)0, (idx_t)0, (idx_t)0));
00156 }
00157
00158
00159 icopy(nvtxs, graph->where, vmap);
00160
00161 FreeRData(graph);
00162
00163 Allocate2WayNodePartitionMemory(ctrl, graph);
00164 icopy(nvtxs, vmap, graph->where);
00165
00166 WCOREPOP;
00167
00168 Compute2WayNodePartitionParams(ctrl, graph);
00169
00170 ASSERT(CheckNodePartitionParams(graph));
00171
00172 FM_2WayNodeRefine1Sided(ctrl, graph, ctrl->niter);
00173
00174 ASSERT(IsSeparable(graph));
00175 }
00176