emd.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  1. /*
  2. emd.c
  3. Last update: 3/14/98
  4. An implementation of the Earth Movers Distance.
  5. Based of the solution for the Transportation problem as described in
  6. "Introduction to Mathematical Programming" by F. S. Hillier and
  7. G. J. Lieberman, McGraw-Hill, 1990.
  8. Copyright (C) 1998 Yossi Rubner
  9. Computer Science Department, Stanford University
  10. E-Mail: rubner@cs.stanford.edu URL: http://vision.stanford.edu/~rubner
  11. */
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <math.h>
  15. #include "vislearning/math/distances/emd.h"
  16. #define DEBUG_LEVEL 0
  17. /*
  18. DEBUG_LEVEL:
  19. 0 = NO MESSAGES
  20. 1 = PRINT THE NUMBER OF ITERATIONS AND THE FINAL RESULT
  21. 2 = PRINT THE RESULT AFTER EVERY ITERATION
  22. 3 = PRINT ALSO THE FLOW AFTER EVERY ITERATION
  23. 4 = PRINT A LOT OF INFORMATION (PROBABLY USEFUL ONLY FOR THE AUTHOR)
  24. */
  25. #define MAX_SIG_SIZE1 (MAX_SIG_SIZE+1) /* FOR THE POSIBLE DUMMY FEATURE */
  26. /* NEW TYPES DEFINITION */
  27. /* node1_t IS USED FOR SINGLE-LINKED LISTS */
  28. typedef struct node1_t {
  29. int i;
  30. double val;
  31. struct node1_t *Next;
  32. } node1_t;
  33. /* node1_t IS USED FOR DOUBLE-LINKED LISTS */
  34. typedef struct node2_t {
  35. int i, j;
  36. double val;
  37. struct node2_t *NextC; /* NEXT COLUMN */
  38. struct node2_t *NextR; /* NEXT ROW */
  39. } node2_t;
  40. /* GLOBAL VARIABLE DECLARATION */
  41. static int _n1, _n2; /* SIGNATURES SIZES */
  42. static float *_C = (float *)malloc(MAX_SIG_SIZE1*MAX_SIG_SIZE1*sizeof(float));/* THE COST MATRIX */
  43. static node2_t *_X = (node2_t *)malloc(sizeof(node2_t)*MAX_SIG_SIZE1*2); /* THE BASIC VARIABLES VECTOR */
  44. /* VARIABLES TO HANDLE _X EFFICIENTLY */
  45. static node2_t *_EndX, *_EnterX;
  46. static char *_IsX = (char *)malloc(MAX_SIG_SIZE1*MAX_SIG_SIZE1*sizeof(char));
  47. static node2_t **_RowsX = (node2_t **)malloc(MAX_SIG_SIZE1*sizeof(node2_t *));
  48. static node2_t **_ColsX = (node2_t **)malloc(MAX_SIG_SIZE1*sizeof(node2_t *));
  49. static double _maxW;
  50. static float _maxC;
  51. /* DECLARATION OF FUNCTIONS */
  52. static float init(signature_t *Signature1, signature_t *Signature2,
  53. float (*Dist)(feature_t *, feature_t *));
  54. static void findBasicVariables(node1_t *U, node1_t *V);
  55. static int isOptimal(node1_t *U, node1_t *V);
  56. static int findLoop(node2_t **Loop);
  57. static void newSol();
  58. static void russel(double *S, double *D);
  59. static void addBasicVariable(int minI, int minJ, double *S, double *D,
  60. node1_t *PrevUMinI, node1_t *PrevVMinJ,
  61. node1_t *UHead);
  62. #if DEBUG_LEVEL > 0
  63. static void printSolution();
  64. #endif
  65. /******************************************************************************
  66. float emd(signature_t *Signature1, signature_t *Signature2,
  67. float (*Dist)(feature_t *, feature_t *), flow_t *Flow, int *FlowSize)
  68. where
  69. Signature1, Signature2 Pointers to signatures that their distance we want
  70. to compute.
  71. Dist Pointer to the ground distance. i.e. the function that computes
  72. the distance between two features.
  73. // refactor-nice.pl: check this substitution
  74. // old: Flow (Optional) Pointer to a vector of flow_t (defined in emd.h)
  75. Flow (Optional) Pointer to a std::vector of flow_t (defined in emd.h)
  76. where the resulting flow will be stored. Flow must have n1+n2-1
  77. elements, where n1 and n2 are the sizes of the two signatures
  78. respectively.
  79. If NULL, the flow is not returned.
  80. FlowSize (Optional) Pointer to an integer where the number of elements in
  81. Flow will be stored
  82. ******************************************************************************/
  83. float emd(signature_t *Signature1, signature_t *Signature2,
  84. float (*Dist)(feature_t *, feature_t *),
  85. flow_t *Flow, int *FlowSize)
  86. {
  87. int itr;
  88. double totalCost;
  89. float w;
  90. node2_t *XP;
  91. flow_t *FlowP;
  92. node1_t *U = (node1_t *)malloc(MAX_SIG_SIZE1*sizeof(node1_t));
  93. node1_t *V = (node1_t *)malloc(MAX_SIG_SIZE1*sizeof(node1_t));
  94. w = init(Signature1, Signature2, Dist);
  95. #if DEBUG_LEVEL > 1
  96. printf("\nINITIAL SOLUTION:\n");
  97. printSolution();
  98. #endif
  99. if (_n1 > 1 && _n2 > 1) /* IF _n1 = 1 OR _n2 = 1 THEN WE ARE DONE */
  100. {
  101. for (itr = 1; itr < MAX_ITERATIONS; itr++)
  102. {
  103. /* FIND BASIC VARIABLES */
  104. findBasicVariables(U, V);
  105. /* CHECK FOR OPTIMALITY */
  106. if (isOptimal(U, V))
  107. break;
  108. /* IMPROVE SOLUTION */
  109. newSol();
  110. #if DEBUG_LEVEL > 1
  111. printf("\nITERATION # %d \n", itr);
  112. printSolution();
  113. #endif
  114. }
  115. if (itr == MAX_ITERATIONS)
  116. fprintf(stderr, "emd: Maximum number of iterations has been reached (%d)\n",
  117. MAX_ITERATIONS);
  118. }
  119. /* COMPUTE THE TOTAL FLOW */
  120. totalCost = 0;
  121. if (Flow != NULL)
  122. FlowP = Flow;
  123. for(XP=_X; XP < _EndX; XP++)
  124. {
  125. if (XP == _EnterX) /* _EnterX IS THE EMPTY SLOT */
  126. continue;
  127. if (XP->i == Signature1->n || XP->j == Signature2->n) /* DUMMY FEATURE */
  128. continue;
  129. if (XP->val == 0) /* ZERO FLOW */
  130. continue;
  131. totalCost += (double)XP->val * _C[XP->i*MAX_SIG_SIZE1 + XP->j];
  132. if (Flow != NULL)
  133. {
  134. FlowP->from = XP->i;
  135. FlowP->to = XP->j;
  136. FlowP->amount = XP->val;
  137. FlowP++;
  138. }
  139. }
  140. if (Flow != NULL)
  141. *FlowSize = FlowP-Flow;
  142. #if DEBUG_LEVEL > 0
  143. printf("\n*** OPTIMAL SOLUTION (%d ITERATIONS): %f ***\n", itr, totalCost);
  144. #endif
  145. free(U);
  146. free(V);
  147. /* RETURN THE NORMALIZED COST == EMD */
  148. return (float)(totalCost / w);
  149. }
  150. /**********************
  151. init
  152. **********************/
  153. static float init(signature_t *Signature1, signature_t *Signature2,
  154. float (*Dist)(feature_t *, feature_t *))
  155. {
  156. int i, j;
  157. double sSum, dSum, diff;
  158. feature_t *P1, *P2;
  159. double S[MAX_SIG_SIZE1], D[MAX_SIG_SIZE1];
  160. _n1 = Signature1->n;
  161. _n2 = Signature2->n;
  162. if (_n1 > MAX_SIG_SIZE || _n2 > MAX_SIG_SIZE)
  163. {
  164. fprintf(stderr, "emd: Signature size is limited to %d\n", MAX_SIG_SIZE);
  165. exit(1);
  166. }
  167. /* COMPUTE THE DISTANCE MATRIX */
  168. _maxC = 0;
  169. for(i=0, P1=Signature1->Features; i < _n1; i++, P1++)
  170. for(j=0, P2=Signature2->Features; j < _n2; j++, P2++)
  171. {
  172. _C[i*MAX_SIG_SIZE1 + j] = Dist(P1, P2);
  173. if (_C[i*MAX_SIG_SIZE1 + j] > _maxC)
  174. _maxC = _C[i*MAX_SIG_SIZE1 + j];
  175. }
  176. /* SUM UP THE SUPPLY AND DEMAND */
  177. sSum = 0.0;
  178. for(i=0; i < _n1; i++)
  179. {
  180. S[i] = Signature1->Weights[i];
  181. sSum += Signature1->Weights[i];
  182. _RowsX[i] = NULL;
  183. }
  184. dSum = 0.0;
  185. for(j=0; j < _n2; j++)
  186. {
  187. D[j] = Signature2->Weights[j];
  188. dSum += Signature2->Weights[j];
  189. _ColsX[j] = NULL;
  190. }
  191. /* IF SUPPLY DIFFERENT THAN THE DEMAND, ADD A ZERO-COST DUMMY CLUSTER */
  192. diff = sSum - dSum;
  193. if (fabs(diff) >= EPSILON * sSum)
  194. {
  195. if (diff < 0.0)
  196. {
  197. for (j=0; j < _n2; j++)
  198. _C[_n1*MAX_SIG_SIZE1 + j] = 0;
  199. S[_n1] = -diff;
  200. _RowsX[_n1] = NULL;
  201. _n1++;
  202. }
  203. else
  204. {
  205. for (i=0; i < _n1; i++)
  206. _C[i*MAX_SIG_SIZE1 + _n2] = 0;
  207. D[_n2] = diff;
  208. _ColsX[_n2] = NULL;
  209. _n2++;
  210. }
  211. }
  212. /* INITIALIZE THE BASIC VARIABLE STRUCTURES */
  213. for (i=0; i < _n1; i++)
  214. for (j=0; j < _n2; j++)
  215. _IsX[i*MAX_SIG_SIZE1 + j] = 0;
  216. _EndX = _X;
  217. _maxW = sSum > dSum ? sSum : dSum;
  218. /* FIND INITIAL SOLUTION */
  219. russel(S, D);
  220. _EnterX = _EndX++; /* AN EMPTY SLOT (ONLY _n1+_n2-1 BASIC VARIABLES) */
  221. return sSum > dSum ? dSum : sSum;
  222. }
  223. /**********************
  224. findBasicVariables
  225. **********************/
  226. static void findBasicVariables(node1_t *U, node1_t *V)
  227. {
  228. int i, j, found;
  229. int UfoundNum, VfoundNum;
  230. node1_t u0Head, u1Head, *CurU, *PrevU;
  231. node1_t v0Head, v1Head, *CurV, *PrevV;
  232. /* INITIALIZE THE ROWS LIST (U) AND THE COLUMNS LIST (V) */
  233. u0Head.Next = CurU = U;
  234. for (i=0; i < _n1; i++)
  235. {
  236. CurU->i = i;
  237. CurU->Next = CurU+1;
  238. CurU++;
  239. }
  240. (--CurU)->Next = NULL;
  241. u1Head.Next = NULL;
  242. CurV = V+1;
  243. v0Head.Next = _n2 > 1 ? V+1 : NULL;
  244. for (j=1; j < _n2; j++)
  245. {
  246. CurV->i = j;
  247. CurV->Next = CurV+1;
  248. CurV++;
  249. }
  250. (--CurV)->Next = NULL;
  251. v1Head.Next = NULL;
  252. /* THERE ARE _n1+_n2 VARIABLES BUT ONLY _n1+_n2-1 INDEPENDENT EQUATIONS,
  253. SO SET V[0]=0 */
  254. V[0].i = 0;
  255. V[0].val = 0;
  256. v1Head.Next = V;
  257. v1Head.Next->Next = NULL;
  258. /* LOOP UNTIL ALL VARIABLES ARE FOUND */
  259. UfoundNum=VfoundNum=0;
  260. while (UfoundNum < _n1 || VfoundNum < _n2)
  261. {
  262. #if DEBUG_LEVEL > 3
  263. printf("UfoundNum=%d/%d,VfoundNum=%d/%d\n",UfoundNum,_n1,VfoundNum,_n2);
  264. printf("U0=");
  265. for(CurU = u0Head.Next; CurU != NULL; CurU = CurU->Next)
  266. printf("[%d]",CurU-U);
  267. printf("\n");
  268. printf("U1=");
  269. for(CurU = u1Head.Next; CurU != NULL; CurU = CurU->Next)
  270. printf("[%d]",CurU-U);
  271. printf("\n");
  272. printf("V0=");
  273. for(CurV = v0Head.Next; CurV != NULL; CurV = CurV->Next)
  274. printf("[%d]",CurV-V);
  275. printf("\n");
  276. printf("V1=");
  277. for(CurV = v1Head.Next; CurV != NULL; CurV = CurV->Next)
  278. printf("[%d]",CurV-V);
  279. printf("\n\n");
  280. #endif
  281. found = 0;
  282. if (VfoundNum < _n2)
  283. {
  284. /* LOOP OVER ALL MARKED COLUMNS */
  285. PrevV = &v1Head;
  286. for (CurV=v1Head.Next; CurV != NULL; CurV=CurV->Next)
  287. {
  288. j = CurV->i;
  289. /* FIND THE VARIABLES IN COLUMN j */
  290. PrevU = &u0Head;
  291. for (CurU=u0Head.Next; CurU != NULL; CurU=CurU->Next)
  292. {
  293. i = CurU->i;
  294. if (_IsX[i*MAX_SIG_SIZE1 + j])
  295. {
  296. /* COMPUTE U[i] */
  297. CurU->val = _C[i*MAX_SIG_SIZE1 + j] - CurV->val;
  298. /* ...AND ADD IT TO THE MARKED LIST */
  299. PrevU->Next = CurU->Next;
  300. CurU->Next = u1Head.Next != NULL ? u1Head.Next : NULL;
  301. u1Head.Next = CurU;
  302. CurU = PrevU;
  303. }
  304. else
  305. PrevU = CurU;
  306. }
  307. PrevV->Next = CurV->Next;
  308. VfoundNum++;
  309. found = 1;
  310. }
  311. }
  312. if (UfoundNum < _n1)
  313. {
  314. /* LOOP OVER ALL MARKED ROWS */
  315. PrevU = &u1Head;
  316. for (CurU=u1Head.Next; CurU != NULL; CurU=CurU->Next)
  317. {
  318. i = CurU->i;
  319. /* FIND THE VARIABLES IN ROWS i */
  320. PrevV = &v0Head;
  321. for (CurV=v0Head.Next; CurV != NULL; CurV=CurV->Next)
  322. {
  323. j = CurV->i;
  324. if (_IsX[i*MAX_SIG_SIZE1 + j])
  325. {
  326. /* COMPUTE V[j] */
  327. CurV->val = _C[i*MAX_SIG_SIZE1 + j] - CurU->val;
  328. /* ...AND ADD IT TO THE MARKED LIST */
  329. PrevV->Next = CurV->Next;
  330. CurV->Next = v1Head.Next != NULL ? v1Head.Next: NULL;
  331. v1Head.Next = CurV;
  332. CurV = PrevV;
  333. }
  334. else
  335. PrevV = CurV;
  336. }
  337. PrevU->Next = CurU->Next;
  338. UfoundNum++;
  339. found = 1;
  340. }
  341. }
  342. if (! found)
  343. {
  344. fprintf(stderr, "emd: Unexpected error in findBasicVariables!\n");
  345. fprintf(stderr, "This typically happens when the EPSILON defined in\n");
  346. fprintf(stderr, "emd.h is not right for the scale of the problem.\n");
  347. exit(1);
  348. }
  349. }
  350. }
  351. /**********************
  352. isOptimal
  353. **********************/
  354. static int isOptimal(node1_t *U, node1_t *V)
  355. {
  356. double delta, deltaMin;
  357. int i, j, minI, minJ;
  358. /* FIND THE MINIMAL Cij-Ui-Vj OVER ALL i,j */
  359. deltaMin = INFINITY;
  360. for(i=0; i < _n1; i++)
  361. for(j=0; j < _n2; j++)
  362. if (! _IsX[i*MAX_SIG_SIZE1 + j])
  363. {
  364. delta = _C[i*MAX_SIG_SIZE1 + j] - U[i].val - V[j].val;
  365. if (deltaMin > delta)
  366. {
  367. deltaMin = delta;
  368. minI = i;
  369. minJ = j;
  370. }
  371. }
  372. #if DEBUG_LEVEL > 3
  373. printf("deltaMin=%f\n", deltaMin);
  374. #endif
  375. if (deltaMin == INFINITY)
  376. {
  377. fprintf(stderr, "emd: Unexpected error in isOptimal.\n");
  378. exit(0);
  379. }
  380. _EnterX->i = minI;
  381. _EnterX->j = minJ;
  382. /* IF NO NEGATIVE deltaMin, WE FOUND THE OPTIMAL SOLUTION */
  383. return deltaMin >= -EPSILON * _maxC;
  384. /*
  385. return deltaMin >= -EPSILON;
  386. */
  387. }
  388. /**********************
  389. newSol
  390. **********************/
  391. static void newSol()
  392. {
  393. int i, j, k;
  394. double xMin;
  395. int steps;
  396. node2_t **Loop = (node2_t **)malloc(2*MAX_SIG_SIZE1 * sizeof(node2_t*)), *CurX, *LeaveX;
  397. #if DEBUG_LEVEL > 3
  398. printf("EnterX = (%d,%d)\n", _EnterX->i, _EnterX->j);
  399. #endif
  400. /* ENTER THE NEW BASIC VARIABLE */
  401. i = _EnterX->i;
  402. j = _EnterX->j;
  403. _IsX[i*MAX_SIG_SIZE1 + j] = 1;
  404. _EnterX->NextC = _RowsX[i];
  405. _EnterX->NextR = _ColsX[j];
  406. _EnterX->val = 0;
  407. _RowsX[i] = _EnterX;
  408. _ColsX[j] = _EnterX;
  409. /* FIND A CHAIN REACTION */
  410. steps = findLoop(Loop);
  411. /* FIND THE LARGEST VALUE IN THE LOOP */
  412. xMin = INFINITY;
  413. for (k=1; k < steps; k+=2)
  414. {
  415. if (Loop[k]->val < xMin)
  416. {
  417. LeaveX = Loop[k];
  418. xMin = Loop[k]->val;
  419. }
  420. }
  421. /* UPDATE THE LOOP */
  422. for (k=0; k < steps; k+=2)
  423. {
  424. Loop[k]->val += xMin;
  425. Loop[k+1]->val -= xMin;
  426. }
  427. #if DEBUG_LEVEL > 3
  428. printf("LeaveX = (%d,%d)\n", LeaveX->i, LeaveX->j);
  429. #endif
  430. /* REMOVE THE LEAVING BASIC VARIABLE */
  431. i = LeaveX->i;
  432. j = LeaveX->j;
  433. _IsX[i*MAX_SIG_SIZE1 + j] = 0;
  434. if (_RowsX[i] == LeaveX)
  435. _RowsX[i] = LeaveX->NextC;
  436. else
  437. for (CurX=_RowsX[i]; CurX != NULL; CurX = CurX->NextC)
  438. if (CurX->NextC == LeaveX)
  439. {
  440. CurX->NextC = CurX->NextC->NextC;
  441. break;
  442. }
  443. if (_ColsX[j] == LeaveX)
  444. _ColsX[j] = LeaveX->NextR;
  445. else
  446. for (CurX=_ColsX[j]; CurX != NULL; CurX = CurX->NextR)
  447. if (CurX->NextR == LeaveX)
  448. {
  449. CurX->NextR = CurX->NextR->NextR;
  450. break;
  451. }
  452. /* SET _EnterX TO BE THE NEW EMPTY SLOT */
  453. _EnterX = LeaveX;
  454. free (Loop);
  455. }
  456. /**********************
  457. findLoop
  458. **********************/
  459. static int findLoop(node2_t **Loop)
  460. {
  461. int i, steps;
  462. node2_t **CurX, *NewX;
  463. char IsUsed[2*MAX_SIG_SIZE1];
  464. for (i=0; i < _n1+_n2; i++)
  465. IsUsed[i] = 0;
  466. CurX = Loop;
  467. NewX = *CurX = _EnterX;
  468. IsUsed[_EnterX-_X] = 1;
  469. steps = 1;
  470. do
  471. {
  472. if (steps%2 == 1)
  473. {
  474. /* FIND AN UNUSED X IN THE ROW */
  475. NewX = _RowsX[NewX->i];
  476. while (NewX != NULL && IsUsed[NewX-_X])
  477. NewX = NewX->NextC;
  478. }
  479. else
  480. {
  481. /* FIND AN UNUSED X IN THE COLUMN, OR THE ENTERING X */
  482. NewX = _ColsX[NewX->j];
  483. while (NewX != NULL && IsUsed[NewX-_X] && NewX != _EnterX)
  484. NewX = NewX->NextR;
  485. if (NewX == _EnterX)
  486. break;
  487. }
  488. if (NewX != NULL) /* FOUND THE NEXT X */
  489. {
  490. /* ADD X TO THE LOOP */
  491. *++CurX = NewX;
  492. IsUsed[NewX-_X] = 1;
  493. steps++;
  494. #if DEBUG_LEVEL > 3
  495. printf("steps=%d, NewX=(%d,%d)\n", steps, NewX->i, NewX->j);
  496. #endif
  497. }
  498. else /* DIDN'T FIND THE NEXT X */
  499. {
  500. /* BACKTRACK */
  501. do
  502. {
  503. NewX = *CurX;
  504. do
  505. {
  506. if (steps%2 == 1)
  507. NewX = NewX->NextR;
  508. else
  509. NewX = NewX->NextC;
  510. } while (NewX != NULL && IsUsed[NewX-_X]);
  511. if (NewX == NULL)
  512. {
  513. IsUsed[*CurX-_X] = 0;
  514. CurX--;
  515. steps--;
  516. }
  517. } while (NewX == NULL && CurX >= Loop);
  518. #if DEBUG_LEVEL > 3
  519. printf("BACKTRACKING TO: steps=%d, NewX=(%d,%d)\n",
  520. steps, NewX->i, NewX->j);
  521. #endif
  522. IsUsed[*CurX-_X] = 0;
  523. *CurX = NewX;
  524. IsUsed[NewX-_X] = 1;
  525. }
  526. } while(CurX >= Loop);
  527. if (CurX == Loop)
  528. {
  529. fprintf(stderr, "emd: Unexpected error in findLoop!\n");
  530. exit(1);
  531. }
  532. #if DEBUG_LEVEL > 3
  533. printf("FOUND LOOP:\n");
  534. for (i=0; i < steps; i++)
  535. printf("%d: (%d,%d)\n", i, Loop[i]->i, Loop[i]->j);
  536. #endif
  537. return steps;
  538. }
  539. /**********************
  540. russel
  541. **********************/
  542. static void russel(double *S, double *D)
  543. {
  544. int i, j, found, minI, minJ;
  545. double deltaMin, oldVal, diff;
  546. double *Delta = (double *)malloc(MAX_SIG_SIZE1*MAX_SIG_SIZE1*sizeof(double));
  547. node1_t *Ur = (node1_t *)malloc(MAX_SIG_SIZE1 * sizeof(node1_t));
  548. node1_t *Vr = (node1_t *)malloc(MAX_SIG_SIZE1 * sizeof(node1_t));
  549. node1_t uHead, *CurU, *PrevU;
  550. node1_t vHead, *CurV, *PrevV;
  551. node1_t *PrevUMinI, *PrevVMinJ, *Remember;
  552. /* INITIALIZE THE ROWS LIST (Ur), AND THE COLUMNS LIST (Vr) */
  553. uHead.Next = CurU = Ur;
  554. for (i=0; i < _n1; i++)
  555. {
  556. CurU->i = i;
  557. CurU->val = -INFINITY;
  558. CurU->Next = CurU+1;
  559. CurU++;
  560. }
  561. (--CurU)->Next = NULL;
  562. vHead.Next = CurV = Vr;
  563. for (j=0; j < _n2; j++)
  564. {
  565. CurV->i = j;
  566. CurV->val = -INFINITY;
  567. CurV->Next = CurV+1;
  568. CurV++;
  569. }
  570. (--CurV)->Next = NULL;
  571. /* FIND THE MAXIMUM ROW AND COLUMN VALUES (Ur[i] AND Vr[j]) */
  572. for(i=0; i < _n1 ; i++)
  573. for(j=0; j < _n2 ; j++)
  574. {
  575. float v;
  576. v = _C[i*MAX_SIG_SIZE1 + j];
  577. if (Ur[i].val <= v)
  578. Ur[i].val = v;
  579. if (Vr[j].val <= v)
  580. Vr[j].val = v;
  581. }
  582. /* COMPUTE THE Delta MATRIX */
  583. for(i=0; i < _n1 ; i++)
  584. for(j=0; j < _n2 ; j++)
  585. Delta[i*MAX_SIG_SIZE1 + j] = _C[i*MAX_SIG_SIZE1 + j] - Ur[i].val - Vr[j].val;
  586. /* FIND THE BASIC VARIABLES */
  587. do
  588. {
  589. #if DEBUG_LEVEL > 3
  590. printf("Ur=");
  591. for(CurU = uHead.Next; CurU != NULL; CurU = CurU->Next)
  592. printf("[%d]",CurU-Ur);
  593. printf("\n");
  594. printf("Vr=");
  595. for(CurV = vHead.Next; CurV != NULL; CurV = CurV->Next)
  596. printf("[%d]",CurV-Vr);
  597. printf("\n");
  598. printf("\n\n");
  599. #endif
  600. /* FIND THE SMALLEST Delta[i][j] */
  601. found = 0;
  602. deltaMin = INFINITY;
  603. PrevU = &uHead;
  604. for (CurU=uHead.Next; CurU != NULL; CurU=CurU->Next)
  605. {
  606. int i;
  607. i = CurU->i;
  608. PrevV = &vHead;
  609. for (CurV=vHead.Next; CurV != NULL; CurV=CurV->Next)
  610. {
  611. int j;
  612. j = CurV->i;
  613. if (deltaMin > Delta[i*MAX_SIG_SIZE1 + j])
  614. {
  615. deltaMin = Delta[i*MAX_SIG_SIZE1 + j];
  616. minI = i;
  617. minJ = j;
  618. PrevUMinI = PrevU;
  619. PrevVMinJ = PrevV;
  620. found = 1;
  621. }
  622. PrevV = CurV;
  623. }
  624. PrevU = CurU;
  625. }
  626. if (! found)
  627. break;
  628. /* ADD X[minI][minJ] TO THE BASIS, AND ADJUST SUPPLIES AND COST */
  629. Remember = PrevUMinI->Next;
  630. addBasicVariable(minI, minJ, S, D, PrevUMinI, PrevVMinJ, &uHead);
  631. /* UPDATE THE NECESSARY Delta[][] */
  632. if (Remember == PrevUMinI->Next) /* LINE minI WAS DELETED */
  633. {
  634. for (CurV=vHead.Next; CurV != NULL; CurV=CurV->Next)
  635. {
  636. int j;
  637. j = CurV->i;
  638. if (CurV->val == _C[minI*MAX_SIG_SIZE1 + j]) /* COLUMN j NEEDS UPDATING */
  639. {
  640. /* FIND THE NEW MAXIMUM VALUE IN THE COLUMN */
  641. oldVal = CurV->val;
  642. CurV->val = -INFINITY;
  643. for (CurU=uHead.Next; CurU != NULL; CurU=CurU->Next)
  644. {
  645. int i;
  646. i = CurU->i;
  647. if (CurV->val <= _C[i*MAX_SIG_SIZE1 + j])
  648. CurV->val = _C[i*MAX_SIG_SIZE1 + j];
  649. }
  650. /* IF NEEDED, ADJUST THE RELEVANT Delta[*][j] */
  651. diff = oldVal - CurV->val;
  652. if (fabs(diff) < EPSILON * _maxC)
  653. for (CurU=uHead.Next; CurU != NULL; CurU=CurU->Next)
  654. Delta[CurU->i * MAX_SIG_SIZE1 + j] += diff;
  655. }
  656. }
  657. }
  658. else /* COLUMN minJ WAS DELETED */
  659. {
  660. for (CurU=uHead.Next; CurU != NULL; CurU=CurU->Next)
  661. {
  662. int i;
  663. i = CurU->i;
  664. if (CurU->val == _C[i*MAX_SIG_SIZE1 + minJ]) /* ROW i NEEDS UPDATING */
  665. {
  666. /* FIND THE NEW MAXIMUM VALUE IN THE ROW */
  667. oldVal = CurU->val;
  668. CurU->val = -INFINITY;
  669. for (CurV=vHead.Next; CurV != NULL; CurV=CurV->Next)
  670. {
  671. int j;
  672. j = CurV->i;
  673. if(CurU->val <= _C[i*MAX_SIG_SIZE1 + j])
  674. CurU->val = _C[i*MAX_SIG_SIZE1 + j];
  675. }
  676. /* If NEEDED, ADJUST THE RELEVANT Delta[i][*] */
  677. diff = oldVal - CurU->val;
  678. if (fabs(diff) < EPSILON * _maxC)
  679. for (CurV=vHead.Next; CurV != NULL; CurV=CurV->Next)
  680. Delta[i*MAX_SIG_SIZE1 + CurV->i] += diff;
  681. }
  682. }
  683. }
  684. } while (uHead.Next != NULL || vHead.Next != NULL);
  685. free(Ur);
  686. free(Vr);
  687. free(Delta);
  688. }
  689. /**********************
  690. addBasicVariable
  691. **********************/
  692. static void addBasicVariable(int minI, int minJ, double *S, double *D,
  693. node1_t *PrevUMinI, node1_t *PrevVMinJ,
  694. node1_t *UHead)
  695. {
  696. double T;
  697. if (fabs(S[minI]-D[minJ]) <= EPSILON * _maxW) /* DEGENERATE CASE */
  698. {
  699. T = S[minI];
  700. S[minI] = 0;
  701. D[minJ] -= T;
  702. }
  703. else if (S[minI] < D[minJ]) /* SUPPLY EXHAUSTED */
  704. {
  705. T = S[minI];
  706. S[minI] = 0;
  707. D[minJ] -= T;
  708. }
  709. else /* DEMAND EXHAUSTED */
  710. {
  711. T = D[minJ];
  712. D[minJ] = 0;
  713. S[minI] -= T;
  714. }
  715. /* X(minI,minJ) IS A BASIC VARIABLE */
  716. _IsX[minI*MAX_SIG_SIZE1 + minJ] = 1;
  717. _EndX->val = T;
  718. _EndX->i = minI;
  719. _EndX->j = minJ;
  720. _EndX->NextC = _RowsX[minI];
  721. _EndX->NextR = _ColsX[minJ];
  722. _RowsX[minI] = _EndX;
  723. _ColsX[minJ] = _EndX;
  724. _EndX++;
  725. /* DELETE SUPPLY ROW ONLY IF THE EMPTY, AND IF NOT LAST ROW */
  726. if (S[minI] == 0 && UHead->Next->Next != NULL)
  727. PrevUMinI->Next = PrevUMinI->Next->Next; /* REMOVE ROW FROM LIST */
  728. else
  729. PrevVMinJ->Next = PrevVMinJ->Next->Next; /* REMOVE COLUMN FROM LIST */
  730. }
  731. /**********************
  732. printSolution
  733. **********************/
  734. static void printSolution()
  735. {
  736. node2_t *P;
  737. double totalCost;
  738. totalCost = 0;
  739. #if DEBUG_LEVEL > 2
  740. printf("SIG1\tSIG2\tFLOW\tCOST\n");
  741. #endif
  742. for(P=_X; P < _EndX; P++)
  743. if (P != _EnterX && _IsX[P->i * MAX_SIG_SIZE1 + P->j])
  744. {
  745. #if DEBUG_LEVEL > 2
  746. printf("%d\t%d\t%f\t%f\n", P->i, P->j, P->val, _C[P->i*MAX_SIG_SIZE1 + P->j]);
  747. #endif
  748. totalCost += (double)P->val * _C[P->i*MAX_SIG_SIZE1 + P->j];
  749. }
  750. printf("COST = %f\n", totalCost);
  751. }