⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ometis.c

📁 多层权核k均值算法
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 1997, Regents of the University of Minnesota * * ometis.c * * This file contains the top level routines for the multilevel recursive * bisection algorithm PMETIS. * * Started 7/24/97 * George * * $Id: ometis.c,v 1.1 1998/11/27 17:59:27 karypis Exp $ * */#include <metis.h>/************************************************************************** This function is the entry point for OEMETIS**************************************************************************/void METIS_EdgeND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options,                   idxtype *perm, idxtype *iperm) {  int i, j;  GraphType graph;  CtrlType ctrl;  if (*numflag == 1)    Change2CNumbering(*nvtxs, xadj, adjncy);  SetUpGraph(&graph, OP_OEMETIS, *nvtxs, 1, xadj, adjncy, NULL, NULL, 0);  if (options[0] == 0) {  /* Use the default parameters */    ctrl.CType = OEMETIS_CTYPE;    ctrl.IType = OEMETIS_ITYPE;    ctrl.RType = OEMETIS_RTYPE;    ctrl.dbglvl = OEMETIS_DBGLVL;  }  else {    ctrl.CType = options[OPTION_CTYPE];    ctrl.IType = options[OPTION_ITYPE];    ctrl.RType = options[OPTION_RTYPE];    ctrl.dbglvl = options[OPTION_DBGLVL];  }  ctrl.oflags  = 0;  ctrl.pfactor = -1;  ctrl.nseps   = 1;  ctrl.optype = OP_OEMETIS;  ctrl.CoarsenTo = 20;  ctrl.maxvwgt = (int) 1.5*(idxsum(*nvtxs, graph.vwgt)/ctrl.CoarsenTo);  InitRandom(-1);  AllocateWorkSpace(&ctrl, &graph, 2);  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));  MlevelNestedDissection(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, *nvtxs);  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));  for (i=0; i<*nvtxs; i++)    perm[iperm[i]] = i;  FreeWorkSpace(&ctrl, &graph);  if (*numflag == 1)    Change2FNumberingOrder(*nvtxs, xadj, adjncy, perm, iperm);}/************************************************************************** This function is the entry point for ONCMETIS**************************************************************************/void METIS_NodeND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options,                   idxtype *perm, idxtype *iperm) {  int i, ii, j, l, wflag, nflag;  GraphType graph;  CtrlType ctrl;  idxtype *cptr, *cind, *piperm;  if (*numflag == 1)    Change2CNumbering(*nvtxs, xadj, adjncy);  if (options[0] == 0) {  /* Use the default parameters */    ctrl.CType   = ONMETIS_CTYPE;    ctrl.IType   = ONMETIS_ITYPE;    ctrl.RType   = ONMETIS_RTYPE;    ctrl.dbglvl  = ONMETIS_DBGLVL;    ctrl.oflags  = ONMETIS_OFLAGS;    ctrl.pfactor = ONMETIS_PFACTOR;    ctrl.nseps   = ONMETIS_NSEPS;  }  else {    ctrl.CType   = options[OPTION_CTYPE];    ctrl.IType   = options[OPTION_ITYPE];    ctrl.RType   = options[OPTION_RTYPE];    ctrl.dbglvl  = options[OPTION_DBGLVL];    ctrl.oflags  = options[OPTION_OFLAGS];    ctrl.pfactor = options[OPTION_PFACTOR];    ctrl.nseps   = options[OPTION_NSEPS];  }  if (ctrl.nseps < 1)    ctrl.nseps = 1;  ctrl.optype = OP_ONMETIS;  ctrl.CoarsenTo = 100;  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));  InitRandom(-1);  if (ctrl.pfactor > 0) {     /*============================================================    * Prune the dense columns    ==============================================================*/    piperm = idxmalloc(*nvtxs, "ONMETIS: piperm");    PruneGraph(&ctrl, &graph, *nvtxs, xadj, adjncy, piperm, (float)(0.1*ctrl.pfactor));  }  else if (ctrl.oflags&OFLAG_COMPRESS) {    /*============================================================    * Compress the graph     ==============================================================*/    cptr = idxmalloc(*nvtxs+1, "ONMETIS: cptr");    cind = idxmalloc(*nvtxs, "ONMETIS: cind");    CompressGraph(&ctrl, &graph, *nvtxs, xadj, adjncy, cptr, cind);    if (graph.nvtxs >= COMPRESSION_FRACTION*(*nvtxs)) {      ctrl.oflags--; /* We actually performed no compression */      GKfree((void**) &cptr, (void**) &cind, LTERM);    }    else if (2*graph.nvtxs < *nvtxs && ctrl.nseps == 1)      ctrl.nseps = 2;  }  else {    SetUpGraph(&graph, OP_ONMETIS, *nvtxs, 1, xadj, adjncy, NULL, NULL, 0);  }  /*=============================================================  * Do the nested dissection ordering   --=============================================================*/  ctrl.maxvwgt = (int) 1.5*(idxsum(graph.nvtxs, graph.vwgt)/ctrl.CoarsenTo);  AllocateWorkSpace(&ctrl, &graph, 2);  if (ctrl.oflags&OFLAG_CCMP)     MlevelNestedDissectionCC(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, graph.nvtxs);  else    MlevelNestedDissection(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, graph.nvtxs);  FreeWorkSpace(&ctrl, &graph);  if (ctrl.pfactor > 0) { /* Order any prunned vertices */    if (graph.nvtxs < *nvtxs) {       idxcopy(graph.nvtxs, iperm, perm);  /* Use perm as an auxiliary array */      for (i=0; i<graph.nvtxs; i++)        iperm[piperm[i]] = perm[i];      for (i=graph.nvtxs; i<*nvtxs; i++)        iperm[piperm[i]] = i;    }    GKfree((void**) (void**) &piperm, LTERM);  }  else if (ctrl.oflags&OFLAG_COMPRESS) { /* Uncompress the ordering */    if (graph.nvtxs < COMPRESSION_FRACTION*(*nvtxs)) {       /* construct perm from iperm */      for (i=0; i<graph.nvtxs; i++)        perm[iperm[i]] = i;       for (l=ii=0; ii<graph.nvtxs; ii++) {        i = perm[ii];        for (j=cptr[i]; j<cptr[i+1]; j++)          iperm[cind[j]] = l++;      }    }    GKfree((void**) &cptr, (void**) &cind, LTERM);  }  for (i=0; i<*nvtxs; i++)    perm[iperm[i]] = i;  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));  if (*numflag == 1)    Change2FNumberingOrder(*nvtxs, xadj, adjncy, perm, iperm);}/************************************************************************** This function is the entry point for ONWMETIS. It requires weights on the* vertices. It is for the case that the matrix has been pre-compressed.**************************************************************************/void METIS_NodeWND(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag,                    int *options, idxtype *perm, idxtype *iperm) {  int i, j, tvwgt;  GraphType graph;  CtrlType ctrl;  if (*numflag == 1)    Change2CNumbering(*nvtxs, xadj, adjncy);  SetUpGraph(&graph, OP_ONMETIS, *nvtxs, 1, xadj, adjncy, vwgt, NULL, 2);  if (options[0] == 0) {  /* Use the default parameters */    ctrl.CType = ONMETIS_CTYPE;    ctrl.IType = ONMETIS_ITYPE;    ctrl.RType = ONMETIS_RTYPE;    ctrl.dbglvl = ONMETIS_DBGLVL;  }  else {    ctrl.CType = options[OPTION_CTYPE];    ctrl.IType = options[OPTION_ITYPE];    ctrl.RType = options[OPTION_RTYPE];    ctrl.dbglvl = options[OPTION_DBGLVL];  }  ctrl.oflags  = OFLAG_COMPRESS;  ctrl.pfactor = 0;  ctrl.nseps = 2;  ctrl.optype = OP_ONMETIS;  ctrl.CoarsenTo = 100;  ctrl.maxvwgt = (int) 1.5*(idxsum(*nvtxs, graph.vwgt)/ctrl.CoarsenTo);  InitRandom(-1);  AllocateWorkSpace(&ctrl, &graph, 2);  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));  MlevelNestedDissection(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, *nvtxs);  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));  for (i=0; i<*nvtxs; i++)    perm[iperm[i]] = i;  FreeWorkSpace(&ctrl, &graph);  if (*numflag == 1)    Change2FNumberingOrder(*nvtxs, xadj, adjncy, perm, iperm);}/************************************************************************** This function takes a graph and produces a bisection of it**************************************************************************/void MlevelNestedDissection(CtrlType *ctrl, GraphType *graph, idxtype *order, float ubfactor, int lastvtx){  int i, j, nvtxs, nbnd, tvwgt, tpwgts2[2];  idxtype *label, *bndind;  GraphType lgraph, rgraph;  nvtxs = graph->nvtxs;  /* Determine the weights of the partitions */  tvwgt = idxsum(nvtxs, graph->vwgt);  tpwgts2[0] = tvwgt/2;  tpwgts2[1] = tvwgt-tpwgts2[0];  switch (ctrl->optype) {    case OP_OEMETIS:      MlevelEdgeBisection(ctrl, graph, tpwgts2, ubfactor);      IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SepTmr));      ConstructMinCoverSeparator(ctrl, graph, ubfactor);      IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SepTmr));      break;    case OP_ONMETIS:      MlevelNodeBisectionMultiple(ctrl, graph, tpwgts2, ubfactor);      IFSET(ctrl->dbglvl, DBG_SEPINFO, printf("Nvtxs: %6d, [%6d %6d %6d]\n", graph->nvtxs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2]));      break;  }  /* Order the nodes in the separator */  nbnd = graph->nbnd;  bndind = graph->bndind;  label = graph->label;  for (i=0; i<nbnd; i++)     order[label[bndind[i]]] = --lastvtx;  SplitGraphOrder(ctrl, graph, &lgraph, &rgraph);  /* Free the memory of the top level graph */  GKfree((void**) &graph->gdata, (void**) &graph->rdata, (void**) &graph->label, LTERM);  if (rgraph.nvtxs > MMDSWITCH)     MlevelNestedDissection(ctrl, &rgraph, order, ubfactor, lastvtx);  else {    MMDOrder(ctrl, &rgraph, order, lastvtx);     GKfree((void**) &rgraph.gdata, (void**) &rgraph.rdata, (void**) &rgraph.label, LTERM);  }  if (lgraph.nvtxs > MMDSWITCH)     MlevelNestedDissection(ctrl, &lgraph, order, ubfactor, lastvtx-rgraph.nvtxs);  else {    MMDOrder(ctrl, &lgraph, order, lastvtx-rgraph.nvtxs);     GKfree((void**) &lgraph.gdata, (void**) &lgraph.rdata, (void**) &lgraph.label, LTERM);  }}/************************************************************************** This function takes a graph and produces a bisection of it**************************************************************************/void MlevelNestedDissectionCC(CtrlType *ctrl, GraphType *graph, idxtype *order, float ubfactor, int lastvtx){  int i, j, nvtxs, nbnd, tvwgt, tpwgts2[2], nsgraphs, ncmps, rnvtxs;  idxtype *label, *bndind;  idxtype *cptr, *cind;  GraphType *sgraphs;  nvtxs = graph->nvtxs;  /* Determine the weights of the partitions */  tvwgt = idxsum(nvtxs, graph->vwgt);  tpwgts2[0] = tvwgt/2;  tpwgts2[1] = tvwgt-tpwgts2[0];  MlevelNodeBisectionMultiple(ctrl, graph, tpwgts2, ubfactor);  IFSET(ctrl->dbglvl, DBG_SEPINFO, printf("Nvtxs: %6d, [%6d %6d %6d]\n", graph->nvtxs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2]));  /* Order the nodes in the separator */  nbnd = graph->nbnd;  bndind = graph->bndind;  label = graph->label;  for (i=0; i<nbnd; i++)     order[label[bndind[i]]] = --lastvtx;  cptr = idxmalloc(nvtxs, "MlevelNestedDissectionCC: cptr");  cind = idxmalloc(nvtxs, "MlevelNestedDissectionCC: cind");  ncmps = FindComponents(ctrl, graph, cptr, cind);/*  if (ncmps > 2)    printf("[%5d] has %3d components\n", nvtxs, ncmps);*/  sgraphs = (GraphType *)GKmalloc(ncmps*sizeof(GraphType), "MlevelNestedDissectionCC: sgraphs");  nsgraphs = SplitGraphOrderCC(ctrl, graph, sgraphs, ncmps, cptr, cind);  GKfree((void**) &cptr, (void**) &cind, LTERM);  /* Free the memory of the top level graph */  GKfree((void**) &graph->gdata, (void**) &graph->rdata, (void**) &graph->label, LTERM);  /* Go and process the subgraphs */  for (rnvtxs=i=0; i<nsgraphs; i++) {    if (sgraphs[i].adjwgt == NULL) {      MMDOrder(ctrl, sgraphs+i, order, lastvtx-rnvtxs);      GKfree((void**) &sgraphs[i].gdata, (void**) &sgraphs[i].label, LTERM);    }    else {      MlevelNestedDissectionCC(ctrl, sgraphs+i, order, ubfactor, lastvtx-rnvtxs);    }    rnvtxs += sgraphs[i].nvtxs;  }  free(sgraphs);}/************************************************************************** This function performs multilevel bisection. It performs multiple 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -