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 };