00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include "match.defs"
00015 #include "graphtypes.h"
00016 #include "pairs.c"
00017 #include "pointer.c"
00018 #include "readgraph.c"
00019 #include "term.c"
00020 #include "unpairs.c"
00021
00022 int *Weighted_Match (void * gptr, int type, int maximize)
00023 {
00024 int g = 0;
00025 int j = 0;
00026 int w = 0;
00027 int outcome = 0;
00028 int loop = 1;
00029
00030
00031 SetUp(gptr,type);
00032 Initialize(maximize);
00033
00034 for( ; ; )
00035 {
00036
00037 DELTA = 0;
00038
00039 for (v = 1; v <= U; ++v)
00040 {
00041 if (MATE[v] == DUMMYEDGE)
00042 {
00043 POINTER (DUMMYVERTEX, v, DUMMYEDGE);
00044 }
00045 }
00046
00047 for ( ; ; )
00048 {
00049 i = 1;
00050
00051 for (j = 2; j <= U; ++j)
00052 {
00053 if (NEXT_D[i] > NEXT_D[j])
00054 {
00055 i = j;
00056 }
00057 }
00058
00059 DELTA = NEXT_D[i];
00060
00061 if (DELTA == LAST_D)
00062 {
00063 goto done;
00064 }
00065
00066 v = BASE[i];
00067
00068 if (LINK[v] >= 0)
00069 {
00070 PAIR (&outcome);
00071
00072 if (outcome == 1)
00073 {
00074 break;
00075 }
00076 }
00077 else
00078 {
00079 w = BMATE (v);
00080
00081 if (LINK[w] < 0)
00082 {
00083 POINTER (v, w, OPPEDGE(NEXTEDGE[i]));
00084 }
00085 else
00086 {
00087 UNPAIR (v, w);
00088 }
00089 }
00090 }
00091
00092 LAST_D -=DELTA;
00093 SET_BOUNDS();
00094 g = OPPEDGE(e);
00095 REMATCH (BEND(e), g);
00096 REMATCH (BEND(g), e);
00097 }
00098
00099 done:
00100
00101 SET_BOUNDS();
00102 UNPAIR_ALL();
00103 for (i = 1; i <= U; ++i)
00104 {
00105 MATE[i] = END[MATE[i]];
00106 if (MATE[i] == DUMMYVERTEX)
00107 {
00108 MATE[i] = 0;
00109 }
00110 }
00111
00112 FreeUp();
00113
00114 return(MATE);
00115 }
00116
00117
00118 Initialize (int maximize)
00119 {
00120 int i = 0;
00121 int allocsize = 0;
00122 int max_wt = -MAXWT;
00123 int min_wt = MAXWT;
00124
00125
00126 DUMMYVERTEX = U + 1;
00127 DUMMYEDGE = U + 2*V + 1;
00128 END[DUMMYEDGE] = DUMMYVERTEX;
00129
00130 for (i = U + 2; i <= U + 2*V; i += 2)
00131 {
00132 if (WEIGHT[i] > max_wt)
00133 {
00134 max_wt = WEIGHT[i];
00135 }
00136 if (WEIGHT[i] < min_wt)
00137 {
00138 min_wt = WEIGHT[i];
00139 }
00140 }
00141
00142 if (!maximize)
00143 {
00144 if ( (U % 2) != 0)
00145 {
00146 printf("Must have an even number of vertices to do a\n");
00147 printf("minimum complete matching.\n");
00148 exit(0);
00149 }
00150
00151 max_wt += 2;
00152 for (i = U+1; i <= U + 2*V; i++)
00153 {
00154 WEIGHT[i] = max_wt-WEIGHT[i];
00155 }
00156
00157 max_wt = max_wt-min_wt;
00158 }
00159
00160 LAST_D = max_wt/2;
00161
00162 #ifdef MATLAB_MEX_FILE
00163 void *mxMalloc(size_t);
00164 allocsize = (U + 2) * sizeof(int);
00165 MATE = (int *) mxMalloc(allocsize);
00166 LINK = (int *) mxMalloc(allocsize);
00167 BASE = (int *) mxMalloc(allocsize);
00168 NEXTVTX = (int *) mxMalloc(allocsize);
00169 LASTVTX = (int *) mxMalloc(allocsize);
00170 Y = (int *) mxMalloc(allocsize);
00171 NEXT_D = (int *) mxMalloc(allocsize);
00172 NEXTEDGE = (int *) mxMalloc(allocsize);
00173
00174 allocsize = (U + 2 * V + 2) * sizeof(int);
00175 NEXTPAIR = (int *) mxMalloc(allocsize);
00176 #else
00177 allocsize = (U + 2) * sizeof(int);
00178 MATE = (int *) malloc(allocsize);
00179 LINK = (int *) malloc(allocsize);
00180 BASE = (int *) malloc(allocsize);
00181 NEXTVTX = (int *) malloc(allocsize);
00182 LASTVTX = (int *) malloc(allocsize);
00183 Y = (int *) malloc(allocsize);
00184 NEXT_D = (int *) malloc(allocsize);
00185 NEXTEDGE = (int *) malloc(allocsize);
00186
00187 allocsize = (U + 2 * V + 2) * sizeof(int);
00188 NEXTPAIR = (int *) malloc(allocsize);
00189 #endif
00190
00191 for (i = 1; i <= U+1; ++i)
00192 {
00193 MATE[i] = DUMMYEDGE;
00194 NEXTEDGE[i] = DUMMYEDGE;
00195 NEXTVTX[i] = 0;
00196 LINK[i] = -DUMMYEDGE;
00197 BASE[i] = i;
00198 LASTVTX[i] = i;
00199 Y[i] = LAST_D;
00200 NEXT_D[i] = LAST_D;
00201 }
00202 }
00203
00204
00205 FreeUp()
00206 {
00207
00208 #ifdef MATLAB_MEX_FILE
00209
00210 mxFree(LINK);
00211 mxFree(BASE);
00212 mxFree(NEXTVTX);
00213 mxFree(LASTVTX);
00214 mxFree(Y);
00215 mxFree(NEXT_D);
00216 mxFree(NEXTEDGE);
00217 mxFree(NEXTPAIR);
00218 mxFree(A);
00219 mxFree(END);
00220 mxFree(WEIGHT);
00221
00222 #else
00223
00224 free(LINK);
00225 free(BASE);
00226 free(NEXTVTX);
00227 free(LASTVTX);
00228 free(Y);
00229 free(NEXT_D);
00230 free(NEXTEDGE);
00231 free(NEXTPAIR);
00232 free(A);
00233 free(END);
00234 free(WEIGHT);
00235
00236 #endif
00237 }
00238