aboutsummaryrefslogtreecommitdiff
path: root/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mincover.c
diff options
context:
space:
mode:
Diffstat (limited to 'benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mincover.c')
-rw-r--r--benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mincover.c259
1 files changed, 259 insertions, 0 deletions
diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mincover.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mincover.c
new file mode 100644
index 0000000..789022b
--- /dev/null
+++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mincover.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright 1997, Regents of the University of Minnesota
+ *
+ * mincover.c
+ *
+ * This file implements the minimum cover algorithm
+ *
+ * Started 8/1/97
+ * George
+ *
+ * $Id: mincover.c,v 1.1 2003/07/16 15:55:09 karypis Exp $
+ */
+
+#include <metis.h>
+
+/*************************************************************************
+* Constants used by mincover algorithm
+**************************************************************************/
+#define INCOL 10
+#define INROW 20
+#define VC 1
+#define SC 2
+#define HC 3
+#define VR 4
+#define SR 5
+#define HR 6
+
+
+/*************************************************************************
+* This function returns the min-cover of a bipartite graph.
+* The algorithm used is due to Hopcroft and Karp as modified by Duff etal
+* adj: the adjacency list of the bipartite graph
+* asize: the number of vertices in the first part of the bipartite graph
+* bsize-asize: the number of vertices in the second part
+* 0..(asize-1) > A vertices
+* asize..bsize > B vertices
+*
+* Returns:
+* cover : the actual cover (array)
+* csize : the size of the cover
+**************************************************************************/
+void MinCover(idxtype *xadj, idxtype *adjncy, int asize, int bsize, idxtype *cover, int *csize)
+{
+ int i, j;
+ idxtype *mate, *queue, *flag, *level, *lst;
+ int fptr, rptr, lstptr;
+ int row, maxlevel, col;
+
+ mate = idxsmalloc(bsize, -1, "MinCover: mate");
+ flag = idxmalloc(bsize, "MinCover: flag");
+ level = idxmalloc(bsize, "MinCover: level");
+ queue = idxmalloc(bsize, "MinCover: queue");
+ lst = idxmalloc(bsize, "MinCover: lst");
+
+ /* Get a cheap matching */
+ for (i=0; i<asize; i++) {
+ for (j=xadj[i]; j<xadj[i+1]; j++) {
+ if (mate[adjncy[j]] == -1) {
+ mate[i] = adjncy[j];
+ mate[adjncy[j]] = i;
+ break;
+ }
+ }
+ }
+
+ /* Get into the main loop */
+ while (1) {
+ /* Initialization */
+ fptr = rptr = 0; /* Empty Queue */
+ lstptr = 0; /* Empty List */
+ for (i=0; i<bsize; i++) {
+ level[i] = -1;
+ flag[i] = 0;
+ }
+ maxlevel = bsize;
+
+ /* Insert free nodes into the queue */
+ for (i=0; i<asize; i++)
+ if (mate[i] == -1) {
+ queue[rptr++] = i;
+ level[i] = 0;
+ }
+
+ /* Perform the BFS */
+ while (fptr != rptr) {
+ row = queue[fptr++];
+ if (level[row] < maxlevel) {
+ flag[row] = 1;
+ for (j=xadj[row]; j<xadj[row+1]; j++) {
+ col = adjncy[j];
+ if (!flag[col]) { /* If this column has not been accessed yet */
+ flag[col] = 1;
+ if (mate[col] == -1) { /* Free column node was found */
+ maxlevel = level[row];
+ lst[lstptr++] = col;
+ }
+ else { /* This column node is matched */
+ if (flag[mate[col]])
+ printf("\nSomething wrong, flag[%d] is 1",mate[col]);
+ queue[rptr++] = mate[col];
+ level[mate[col]] = level[row] + 1;
+ }
+ }
+ }
+ }
+ }
+
+ if (lstptr == 0)
+ break; /* No free columns can be reached */
+
+ /* Perform restricted DFS from the free column nodes */
+ for (i=0; i<lstptr; i++)
+ MinCover_Augment(xadj, adjncy, lst[i], mate, flag, level, maxlevel);
+ }
+
+ MinCover_Decompose(xadj, adjncy, asize, bsize, mate, cover, csize);
+
+ GKfree(&mate, &flag, &level, &queue, &lst, LTERM);
+
+}
+
+
+/*************************************************************************
+* This function perfoms a restricted DFS and augments matchings
+**************************************************************************/
+int MinCover_Augment(idxtype *xadj, idxtype *adjncy, int col, idxtype *mate, idxtype *flag, idxtype *level, int maxlevel)
+{
+ int i;
+ int row = -1;
+ int status;
+
+ flag[col] = 2;
+ for (i=xadj[col]; i<xadj[col+1]; i++) {
+ row = adjncy[i];
+
+ if (flag[row] == 1) { /* First time through this row node */
+ if (level[row] == maxlevel) { /* (col, row) is an edge of the G^T */
+ flag[row] = 2; /* Mark this node as being visited */
+ if (maxlevel != 0)
+ status = MinCover_Augment(xadj, adjncy, mate[row], mate, flag, level, maxlevel-1);
+ else
+ status = 1;
+
+ if (status) {
+ mate[col] = row;
+ mate[row] = col;
+ return 1;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+
+/*************************************************************************
+* This function performs a coarse decomposition and determines the
+* min-cover.
+* REF: Pothen ACMTrans. on Amth Software
+**************************************************************************/
+void MinCover_Decompose(idxtype *xadj, idxtype *adjncy, int asize, int bsize, idxtype *mate, idxtype *cover, int *csize)
+{
+ int i, k;
+ idxtype *where;
+ int card[10];
+
+ where = idxmalloc(bsize, "MinCover_Decompose: where");
+ for (i=0; i<10; i++)
+ card[i] = 0;
+
+ for (i=0; i<asize; i++)
+ where[i] = SC;
+ for (; i<bsize; i++)
+ where[i] = SR;
+
+ for (i=0; i<asize; i++)
+ if (mate[i] == -1)
+ MinCover_ColDFS(xadj, adjncy, i, mate, where, INCOL);
+ for (; i<bsize; i++)
+ if (mate[i] == -1)
+ MinCover_RowDFS(xadj, adjncy, i, mate, where, INROW);
+
+ for (i=0; i<bsize; i++)
+ card[where[i]]++;
+
+ k = 0;
+ if (abs(card[VC]+card[SC]-card[HR]) < abs(card[VC]-card[SR]-card[HR])) { /* S = VC+SC+HR */
+ /* printf("%d %d ",vc+sc, hr); */
+ for (i=0; i<bsize; i++)
+ if (where[i] == VC || where[i] == SC || where[i] == HR)
+ cover[k++] = i;
+ }
+ else { /* S = VC+SR+HR */
+ /* printf("%d %d ",vc, hr+sr); */
+ for (i=0; i<bsize; i++)
+ if (where[i] == VC || where[i] == SR || where[i] == HR)
+ cover[k++] = i;
+ }
+
+ *csize = k;
+ free(where);
+
+}
+
+
+/*************************************************************************
+* This function perfoms a dfs starting from an unmatched col node
+* forming alternate paths
+**************************************************************************/
+void MinCover_ColDFS(idxtype *xadj, idxtype *adjncy, int root, idxtype *mate, idxtype *where, int flag)
+{
+ int i;
+
+ if (flag == INCOL) {
+ if (where[root] == HC)
+ return;
+ where[root] = HC;
+ for (i=xadj[root]; i<xadj[root+1]; i++)
+ MinCover_ColDFS(xadj, adjncy, adjncy[i], mate, where, INROW);
+ }
+ else {
+ if (where[root] == HR)
+ return;
+ where[root] = HR;
+ if (mate[root] != -1)
+ MinCover_ColDFS(xadj, adjncy, mate[root], mate, where, INCOL);
+ }
+
+}
+
+/*************************************************************************
+* This function perfoms a dfs starting from an unmatched col node
+* forming alternate paths
+**************************************************************************/
+void MinCover_RowDFS(idxtype *xadj, idxtype *adjncy, int root, idxtype *mate, idxtype *where, int flag)
+{
+ int i;
+
+ if (flag == INROW) {
+ if (where[root] == VR)
+ return;
+ where[root] = VR;
+ for (i=xadj[root]; i<xadj[root+1]; i++)
+ MinCover_RowDFS(xadj, adjncy, adjncy[i], mate, where, INCOL);
+ }
+ else {
+ if (where[root] == VC)
+ return;
+ where[root] = VC;
+ if (mate[root] != -1)
+ MinCover_RowDFS(xadj, adjncy, mate[root], mate, where, INROW);
+ }
+
+}
+
+
+