/* * Copyright(C) 1999-2020 National Technology & Engineering Solutions * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with * NTESS, the U.S. Government retains certain rights in this software. * * See packages/seacas/LICENSE for details */ #include "defs.h" // for FALSE, TRUE #include "structs.h" // for vtx_data /* Find a maximal matching in a graph using simple greedy algorithm. */ /* Randomly permute vertices, and then have each select an unmatched */ /* neighbor. */ int maxmatch1(struct vtx_data **graph, /* array of vtx data for graph */ int nvtxs, /* number of vertices in graph */ int *mflag, /* flag indicating vtx selected or not */ int using_ewgts /* are edge weights being used? */ ) { extern int HEAVY_MATCH; /* choose heavy edges in matching? */ float ewgt_max; /* largest edge weight seen so far */ int *jptr; /* loops through integer arrays */ int vtx; /* vertex to process next */ int neighbor; /* neighbor of a vertex */ int nmerged; /* number of edges in matching */ int matched; /* is a vertex matched yet? */ int jsave; /* best matching edge found so far */ int i, j; /* loop counters */ double drandom(void); /* Initialize mflag array. */ jptr = mflag; for (i = nvtxs; i; i--) { *(++jptr) = 0; } nmerged = 0; /* Select random starting point in list of vertices. */ vtx = 1 + drandom() * nvtxs; if (!using_ewgts || !HEAVY_MATCH) { /* Choose first neighbor */ for (i = nvtxs; i; i--) { if (mflag[vtx] == 0) { /* Not already matched. */ /* Select first free edge. */ matched = FALSE; for (j = 1; !matched && j < graph[vtx]->nedges; j++) { neighbor = graph[vtx]->edges[j]; if (mflag[neighbor] == 0) { mflag[vtx] = neighbor; mflag[neighbor] = vtx; matched = TRUE; nmerged++; } } } if (++vtx > nvtxs) { vtx = 1; } } } else { /* Choose heavy edge neighbor */ for (i = nvtxs; i; i--) { if (mflag[vtx] == 0) { /* Not already matched. */ /* Select heaviest free edge. */ jsave = 0; ewgt_max = 0; for (j = 1; j < graph[vtx]->nedges; j++) { neighbor = graph[vtx]->edges[j]; if (mflag[neighbor] == 0 && graph[vtx]->ewgts[j] > ewgt_max) { ewgt_max = graph[vtx]->ewgts[j]; jsave = j; } } if (jsave > 0) { neighbor = graph[vtx]->edges[jsave]; mflag[vtx] = neighbor; mflag[neighbor] = vtx; nmerged++; } } if (++vtx > nvtxs) { vtx = 1; } } } return (nmerged); }