00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdio.h>
00020
00021 #include "gnrl.h"
00022 #include "lap.h"
00023
00024 namespace cpl_visual_features
00025 {
00026 LapCost lap(int dim,
00027 LapCost **assigncost,
00028 LapCol *rowsol,
00029 LapRow *colsol,
00030 LapCost *u,
00031 LapCost *v)
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 {
00044 boolean unassignedfound;
00045 LapRow i, imin, numfree = 0, prvnumfree, f, i0, k, freerow, *pred, *free;
00046 LapCol j, j1, j2, endofpath, last, low, up, *collist, *matches;
00047 LapCost min, h, umin, usubmin, v2, *d;
00048
00049 free = new LapRow[dim];
00050 collist = new LapCol[dim];
00051 matches = new LapCol[dim];
00052 d = new LapCost[dim];
00053 pred = new LapRow[dim];
00054
00055
00056 for (i = 0; i < dim; i++)
00057 matches[i] = 0;
00058
00059
00060 for (j = dim-1; j >= 0; j--)
00061 {
00062
00063 min = assigncost[0][j];
00064 imin = 0;
00065 for (i = 1; i < dim; i++)
00066 if (assigncost[i][j] < min)
00067 {
00068 min = assigncost[i][j];
00069 imin = i;
00070 }
00071 v[j] = min;
00072
00073 if (++matches[imin] == 1)
00074 {
00075
00076 rowsol[imin] = j;
00077 colsol[j] = imin;
00078 }
00079 else
00080 colsol[j] = -1;
00081 }
00082
00083
00084 for (i = 0; i < dim; i++)
00085 if (matches[i] == 0)
00086 free[numfree++] = i;
00087 else
00088 if (matches[i] == 1)
00089 {
00090 j1 = rowsol[i];
00091 min = BIG;
00092 for (j = 0; j < dim; j++)
00093 if (j != j1)
00094 if (assigncost[i][j] - v[j] < min)
00095 min = assigncost[i][j] - v[j];
00096 v[j1] = v[j1] - min;
00097 }
00098
00099
00100 int loopcnt = 0;
00101 do
00102 {
00103 loopcnt++;
00104
00105
00106
00107 k = 0;
00108 prvnumfree = numfree;
00109 numfree = 0;
00110 while (k < prvnumfree)
00111 {
00112 i = free[k];
00113 k++;
00114
00115
00116 umin = assigncost[i][0] - v[0];
00117 j1 = 0;
00118 usubmin = BIG;
00119 for (j = 1; j < dim; j++)
00120 {
00121 h = assigncost[i][j] - v[j];
00122 if (h < usubmin)
00123 {
00124 if (h >= umin)
00125 {
00126 usubmin = h;
00127 j2 = j;
00128 }
00129 else
00130 {
00131 usubmin = umin;
00132 umin = h;
00133 j2 = j1;
00134 j1 = j;
00135 }
00136 }
00137 }
00138
00139 i0 = colsol[j1];
00140 if (umin < usubmin)
00141
00142
00143 v[j1] = v[j1] - (usubmin - umin);
00144 else
00145 if (i0 >= 0)
00146 {
00147
00148 j1 = j2;
00149 i0 = colsol[j2];
00150 }
00151
00152
00153 rowsol[i] = j1;
00154 colsol[j1] = i;
00155
00156 if (i0 >= 0)
00157 {
00158 if (umin < usubmin)
00159
00160
00161 free[--k] = i0;
00162 else
00163
00164
00165 free[numfree++] = i0;
00166 }
00167 }
00168 }
00169 while (loopcnt < 2);
00170
00171
00172 for (f = 0; f < numfree; f++)
00173 {
00174 freerow = free[f];
00175
00176
00177
00178 for (j = 0; j < dim; j++)
00179 {
00180 d[j] = assigncost[freerow][j] - v[j];
00181 pred[j] = freerow;
00182 collist[j] = j;
00183 }
00184
00185 low = 0;
00186 up = 0;
00187
00188
00189 unassignedfound = FALSE;
00190 do
00191 {
00192 if (up == low)
00193 {
00194 last = low - 1;
00195
00196
00197
00198 min = d[collist[up++]];
00199 for (k = up; k < dim; k++)
00200 {
00201 j = collist[k];
00202 h = d[j];
00203 if (h <= min)
00204 {
00205 if (h < min)
00206 {
00207 up = low;
00208 min = h;
00209 }
00210
00211 collist[k] = collist[up];
00212 collist[up++] = j;
00213 }
00214 }
00215
00216
00217
00218 for (k = low; k < up; k++)
00219 if (colsol[collist[k]] < 0)
00220 {
00221 endofpath = collist[k];
00222 unassignedfound = TRUE;
00223 break;
00224 }
00225 }
00226
00227 if (!unassignedfound)
00228 {
00229
00230 j1 = collist[low];
00231 low++;
00232 i = colsol[j1];
00233 h = assigncost[i][j1] - v[j1] - min;
00234
00235 for (k = up; k < dim; k++)
00236 {
00237 j = collist[k];
00238 v2 = assigncost[i][j] - v[j] - h;
00239 if (v2 < d[j])
00240 {
00241 pred[j] = i;
00242 if (v2 == min)
00243 {
00244 if (colsol[j] < 0)
00245 {
00246
00247 endofpath = j;
00248 unassignedfound = TRUE;
00249 break;
00250 }
00251
00252 else
00253 {
00254 collist[k] = collist[up];
00255 collist[up++] = j;
00256 }
00257 d[j] = v2;
00258 }
00259 }
00260 }
00261 }
00262 }
00263 while (!unassignedfound);
00264
00265
00266 for (k = 0; k <= last; k++)
00267 {
00268 j1 = collist[k];
00269 v[j1] = v[j1] + d[j1] - min;
00270 }
00271
00272
00273 do
00274 {
00275 i = pred[endofpath];
00276 colsol[endofpath] = i;
00277 j1 = endofpath;
00278 endofpath = rowsol[i];
00279 rowsol[i] = j1;
00280 }
00281 while (i != freerow);
00282 }
00283
00284
00285 LapCost lapcost = 0;
00286 for (i = 0; i < dim; i++)
00287 {
00288 j = rowsol[i];
00289 u[i] = assigncost[i][j] - v[j];
00290 lapcost = lapcost + assigncost[i][j];
00291 }
00292
00293
00294 delete[] pred;
00295 delete[] free;
00296 delete[] collist;
00297 delete[] matches;
00298 delete[] d;
00299
00300 return lapcost;
00301 }
00302
00303 void checklap(int dim, LapCost **assigncost,
00304 LapCol *rowsol, LapRow *colsol, LapCost *u, LapCost *v)
00305 {
00306 LapRow i;
00307 LapCol j;
00308 LapCost lapcost = 0, redcost = 0;
00309 boolean *matched;
00310 char wait;
00311
00312 matched = new boolean[dim];
00313
00314 for (i = 0; i < dim; i++)
00315 for (j = 0; j < dim; j++)
00316 if ((redcost = assigncost[i][j] - u[i] - v[j]) < 0)
00317 {
00318 printf("\n");
00319 printf("negative reduced cost i %d j %d redcost %d\n", i, j, redcost);
00320 printf("\n\ndim %5d - press key\n", dim);
00321 scanf("%d", &wait);
00322 break;
00323 }
00324
00325 for (i = 0; i < dim; i++)
00326 if ((redcost = assigncost[i][rowsol[i]] - u[i] - v[rowsol[i]]) != 0)
00327 {
00328 printf("\n");
00329 printf("non-null reduced cost i %d soli %d redcost %d\n", i, rowsol[i], redcost);
00330 printf("\n\ndim %5d - press key\n", dim);
00331 scanf("%d", &wait);
00332 break;
00333 }
00334
00335 for (j = 0; j < dim; j++)
00336 matched[j] = FALSE;
00337
00338 for (i = 0; i < dim; i++)
00339 if (matched[rowsol[i]])
00340 {
00341 printf("\n");
00342 printf("column matched more than once - i %d soli %d\n", i, rowsol[i]);
00343 printf("\n\ndim %5d - press key\n", dim);
00344 scanf("%d", &wait);
00345 break;
00346 }
00347 else
00348 matched[rowsol[i]] = TRUE;
00349
00350
00351 for (i = 0; i < dim; i++)
00352 if (colsol[rowsol[i]] != i)
00353 {
00354 printf("\n");
00355 printf("error in row solution i %d soli %d solsoli %d\n", i, rowsol[i], colsol[rowsol[i]]);
00356 printf("\n\ndim %5d - press key\n", dim);
00357 scanf("%d", &wait);
00358 break;
00359 }
00360
00361 for (j = 0; j < dim; j++)
00362 if (rowsol[colsol[j]] != j)
00363 {
00364 printf("\n");
00365 printf("error in col solution j %d solj %d solsolj %d\n", j, colsol[j], rowsol[colsol[j]]);
00366 printf("\n\ndim %5d - press key\n", dim);
00367 scanf("%d", &wait);
00368 break;
00369 }
00370
00371 delete[] matched;
00372 return;
00373 }
00374 };