00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "metislib.h"
00012
00013
00014
00016
00017 void Refine2Way(ctrl_t *ctrl, graph_t *orggraph, graph_t *graph, real_t *tpwgts)
00018 {
00019
00020 IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->UncoarsenTmr));
00021
00022
00023 Compute2WayPartitionParams(ctrl, graph);
00024
00025 for (;;) {
00026 ASSERT(CheckBnd(graph));
00027
00028 IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->RefTmr));
00029
00030 Balance2Way(ctrl, graph, tpwgts);
00031
00032 FM_2WayRefine(ctrl, graph, tpwgts, ctrl->niter);
00033
00034 IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->RefTmr));
00035
00036 if (graph == orggraph)
00037 break;
00038
00039 graph = graph->finer;
00040 IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->ProjectTmr));
00041 Project2WayPartition(ctrl, graph);
00042 IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->ProjectTmr));
00043 }
00044
00045 IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->UncoarsenTmr));
00046 }
00047
00048
00049
00051
00052 void Allocate2WayPartitionMemory(ctrl_t *ctrl, graph_t *graph)
00053 {
00054 idx_t nvtxs, ncon;
00055
00056 nvtxs = graph->nvtxs;
00057 ncon = graph->ncon;
00058
00059 graph->pwgts = imalloc(2*ncon, "Allocate2WayPartitionMemory: pwgts");
00060 graph->where = imalloc(nvtxs, "Allocate2WayPartitionMemory: where");
00061 graph->bndptr = imalloc(nvtxs, "Allocate2WayPartitionMemory: bndptr");
00062 graph->bndind = imalloc(nvtxs, "Allocate2WayPartitionMemory: bndind");
00063 graph->id = imalloc(nvtxs, "Allocate2WayPartitionMemory: id");
00064 graph->ed = imalloc(nvtxs, "Allocate2WayPartitionMemory: ed");
00065 }
00066
00067
00068
00070
00071 void Compute2WayPartitionParams(ctrl_t *ctrl, graph_t *graph)
00072 {
00073 idx_t i, j, nvtxs, ncon, nbnd, mincut, istart, iend, tid, ted, me;
00074 idx_t *xadj, *vwgt, *adjncy, *adjwgt, *pwgts;
00075 idx_t *where, *bndptr, *bndind, *id, *ed;
00076
00077 nvtxs = graph->nvtxs;
00078 ncon = graph->ncon;
00079 xadj = graph->xadj;
00080 vwgt = graph->vwgt;
00081 adjncy = graph->adjncy;
00082 adjwgt = graph->adjwgt;
00083
00084 where = graph->where;
00085 id = graph->id;
00086 ed = graph->ed;
00087
00088 pwgts = iset(2*ncon, 0, graph->pwgts);
00089 bndptr = iset(nvtxs, -1, graph->bndptr);
00090 bndind = graph->bndind;
00091
00092
00093 if (ncon == 1) {
00094 for (i=0; i<nvtxs; i++) {
00095 ASSERT(where[i] >= 0 && where[i] <= 1);
00096 pwgts[where[i]] += vwgt[i];
00097 }
00098 ASSERT(pwgts[0]+pwgts[1] == graph->tvwgt[0]);
00099 }
00100 else {
00101 for (i=0; i<nvtxs; i++) {
00102 me = where[i];
00103 for (j=0; j<ncon; j++)
00104 pwgts[me*ncon+j] += vwgt[i*ncon+j];
00105 }
00106 }
00107
00108
00109
00110 for (nbnd=0, mincut=0, i=0; i<nvtxs; i++) {
00111 istart = xadj[i];
00112 iend = xadj[i+1];
00113
00114 me = where[i];
00115 tid = ted = 0;
00116
00117 for (j=istart; j<iend; j++) {
00118 if (me == where[adjncy[j]])
00119 tid += adjwgt[j];
00120 else
00121 ted += adjwgt[j];
00122 }
00123 id[i] = tid;
00124 ed[i] = ted;
00125
00126 if (ted > 0 || istart == iend) {
00127 BNDInsert(nbnd, bndind, bndptr, i);
00128 mincut += ted;
00129 }
00130 }
00131
00132 graph->mincut = mincut/2;
00133 graph->nbnd = nbnd;
00134
00135 }
00136
00137
00138
00140
00141 void Project2WayPartition(ctrl_t *ctrl, graph_t *graph)
00142 {
00143 idx_t i, j, istart, iend, nvtxs, nbnd, me, tid, ted;
00144 idx_t *xadj, *adjncy, *adjwgt;
00145 idx_t *cmap, *where, *bndptr, *bndind;
00146 idx_t *cwhere, *cbndptr;
00147 idx_t *id, *ed;
00148 graph_t *cgraph;
00149
00150 Allocate2WayPartitionMemory(ctrl, graph);
00151
00152 cgraph = graph->coarser;
00153 cwhere = cgraph->where;
00154 cbndptr = cgraph->bndptr;
00155
00156 nvtxs = graph->nvtxs;
00157 cmap = graph->cmap;
00158 xadj = graph->xadj;
00159 adjncy = graph->adjncy;
00160 adjwgt = graph->adjwgt;
00161
00162 where = graph->where;
00163 id = graph->id;
00164 ed = graph->ed;
00165
00166 bndptr = iset(nvtxs, -1, graph->bndptr);
00167 bndind = graph->bndind;
00168
00169
00170
00171 for (i=0; i<nvtxs; i++) {
00172 j = cmap[i];
00173 where[i] = cwhere[j];
00174 cmap[i] = cbndptr[j];
00175 }
00176
00177
00178 for (nbnd=0, i=0; i<nvtxs; i++) {
00179 istart = xadj[i];
00180 iend = xadj[i+1];
00181
00182 tid = ted = 0;
00183 if (cmap[i] == -1) {
00184 for (j=istart; j<iend; j++)
00185 tid += adjwgt[j];
00186 }
00187 else {
00188 me = where[i];
00189 for (j=istart; j<iend; j++) {
00190 if (me == where[adjncy[j]])
00191 tid += adjwgt[j];
00192 else
00193 ted += adjwgt[j];
00194 }
00195 }
00196 id[i] = tid;
00197 ed[i] = ted;
00198
00199 if (ted > 0 || istart == iend)
00200 BNDInsert(nbnd, bndind, bndptr, i);
00201 }
00202 graph->mincut = cgraph->mincut;
00203 graph->nbnd = nbnd;
00204
00205
00206 icopy(2*graph->ncon, cgraph->pwgts, graph->pwgts);
00207
00208 FreeGraph(&graph->coarser);
00209 graph->coarser = NULL;
00210 }
00211