00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "metislib.h"
00015
00016
00017
00018
00019 #define INCOL 10
00020 #define INROW 20
00021 #define VC 1
00022 #define SC 2
00023 #define HC 3
00024 #define VR 4
00025 #define SR 5
00026 #define HR 6
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 void MinCover(idx_t *xadj, idx_t *adjncy, idx_t asize, idx_t bsize, idx_t *cover, idx_t *csize)
00043 {
00044 idx_t i, j;
00045 idx_t *mate, *queue, *flag, *level, *lst;
00046 idx_t fptr, rptr, lstptr;
00047 idx_t row, maxlevel, col;
00048
00049 mate = ismalloc(bsize, -1, "MinCover: mate");
00050 flag = imalloc(bsize, "MinCover: flag");
00051 level = imalloc(bsize, "MinCover: level");
00052 queue = imalloc(bsize, "MinCover: queue");
00053 lst = imalloc(bsize, "MinCover: lst");
00054
00055
00056 for (i=0; i<asize; i++) {
00057 for (j=xadj[i]; j<xadj[i+1]; j++) {
00058 if (mate[adjncy[j]] == -1) {
00059 mate[i] = adjncy[j];
00060 mate[adjncy[j]] = i;
00061 break;
00062 }
00063 }
00064 }
00065
00066
00067 while (1) {
00068
00069 fptr = rptr = 0;
00070 lstptr = 0;
00071 for (i=0; i<bsize; i++) {
00072 level[i] = -1;
00073 flag[i] = 0;
00074 }
00075 maxlevel = bsize;
00076
00077
00078 for (i=0; i<asize; i++)
00079 if (mate[i] == -1) {
00080 queue[rptr++] = i;
00081 level[i] = 0;
00082 }
00083
00084
00085 while (fptr != rptr) {
00086 row = queue[fptr++];
00087 if (level[row] < maxlevel) {
00088 flag[row] = 1;
00089 for (j=xadj[row]; j<xadj[row+1]; j++) {
00090 col = adjncy[j];
00091 if (!flag[col]) {
00092 flag[col] = 1;
00093 if (mate[col] == -1) {
00094 maxlevel = level[row];
00095 lst[lstptr++] = col;
00096 }
00097 else {
00098 if (flag[mate[col]])
00099 printf("\nSomething wrong, flag[%"PRIDX"] is 1",mate[col]);
00100 queue[rptr++] = mate[col];
00101 level[mate[col]] = level[row] + 1;
00102 }
00103 }
00104 }
00105 }
00106 }
00107
00108 if (lstptr == 0)
00109 break;
00110
00111
00112 for (i=0; i<lstptr; i++)
00113 MinCover_Augment(xadj, adjncy, lst[i], mate, flag, level, maxlevel);
00114 }
00115
00116 MinCover_Decompose(xadj, adjncy, asize, bsize, mate, cover, csize);
00117
00118 gk_free((void **)&mate, &flag, &level, &queue, &lst, LTERM);
00119
00120 }
00121
00122
00123
00124
00125
00126 idx_t MinCover_Augment(idx_t *xadj, idx_t *adjncy, idx_t col, idx_t *mate, idx_t *flag, idx_t *level, idx_t maxlevel)
00127 {
00128 idx_t i;
00129 idx_t row = -1;
00130 idx_t status;
00131
00132 flag[col] = 2;
00133 for (i=xadj[col]; i<xadj[col+1]; i++) {
00134 row = adjncy[i];
00135
00136 if (flag[row] == 1) {
00137 if (level[row] == maxlevel) {
00138 flag[row] = 2;
00139 if (maxlevel != 0)
00140 status = MinCover_Augment(xadj, adjncy, mate[row], mate, flag, level, maxlevel-1);
00141 else
00142 status = 1;
00143
00144 if (status) {
00145 mate[col] = row;
00146 mate[row] = col;
00147 return 1;
00148 }
00149 }
00150 }
00151 }
00152
00153 return 0;
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163 void MinCover_Decompose(idx_t *xadj, idx_t *adjncy, idx_t asize, idx_t bsize, idx_t *mate, idx_t *cover, idx_t *csize)
00164 {
00165 idx_t i, k;
00166 idx_t *where;
00167 idx_t card[10];
00168
00169 where = imalloc(bsize, "MinCover_Decompose: where");
00170 for (i=0; i<10; i++)
00171 card[i] = 0;
00172
00173 for (i=0; i<asize; i++)
00174 where[i] = SC;
00175 for (; i<bsize; i++)
00176 where[i] = SR;
00177
00178 for (i=0; i<asize; i++)
00179 if (mate[i] == -1)
00180 MinCover_ColDFS(xadj, adjncy, i, mate, where, INCOL);
00181 for (; i<bsize; i++)
00182 if (mate[i] == -1)
00183 MinCover_RowDFS(xadj, adjncy, i, mate, where, INROW);
00184
00185 for (i=0; i<bsize; i++)
00186 card[where[i]]++;
00187
00188 k = 0;
00189 if (iabs(card[VC]+card[SC]-card[HR]) < iabs(card[VC]-card[SR]-card[HR])) {
00190
00191 for (i=0; i<bsize; i++)
00192 if (where[i] == VC || where[i] == SC || where[i] == HR)
00193 cover[k++] = i;
00194 }
00195 else {
00196
00197 for (i=0; i<bsize; i++)
00198 if (where[i] == VC || where[i] == SR || where[i] == HR)
00199 cover[k++] = i;
00200 }
00201
00202 *csize = k;
00203 gk_free((void **)&where, LTERM);
00204
00205 }
00206
00207
00208
00209
00210
00211
00212 void MinCover_ColDFS(idx_t *xadj, idx_t *adjncy, idx_t root, idx_t *mate, idx_t *where, idx_t flag)
00213 {
00214 idx_t i;
00215
00216 if (flag == INCOL) {
00217 if (where[root] == HC)
00218 return;
00219 where[root] = HC;
00220 for (i=xadj[root]; i<xadj[root+1]; i++)
00221 MinCover_ColDFS(xadj, adjncy, adjncy[i], mate, where, INROW);
00222 }
00223 else {
00224 if (where[root] == HR)
00225 return;
00226 where[root] = HR;
00227 if (mate[root] != -1)
00228 MinCover_ColDFS(xadj, adjncy, mate[root], mate, where, INCOL);
00229 }
00230
00231 }
00232
00233
00234
00235
00236
00237 void MinCover_RowDFS(idx_t *xadj, idx_t *adjncy, idx_t root, idx_t *mate, idx_t *where, idx_t flag)
00238 {
00239 idx_t i;
00240
00241 if (flag == INROW) {
00242 if (where[root] == VR)
00243 return;
00244 where[root] = VR;
00245 for (i=xadj[root]; i<xadj[root+1]; i++)
00246 MinCover_RowDFS(xadj, adjncy, adjncy[i], mate, where, INCOL);
00247 }
00248 else {
00249 if (where[root] == VC)
00250 return;
00251 where[root] = VC;
00252 if (mate[root] != -1)
00253 MinCover_RowDFS(xadj, adjncy, mate[root], mate, where, INROW);
00254 }
00255
00256 }
00257
00258
00259