assign_lisa.w
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:30k
源码类别:

通讯编程

开发平台:

Visual C++

  1. % This file is part of the Stanford GraphBase (c) Stanford University 1993
  2. @i boilerplate.w %<< legal stuff: PLEASE READ IT BEFORE MAKING ANY CHANGES!
  3. @i gb_types.w
  4. % PostScript is a registered trade mark of Adobe Systems Incorporated.
  5. deftitle{ASSIGN_,LISA}
  6. def<#1>{$langle${rm#1}$rangle$}
  7. defdash{mathrel-joinreljoinrelmathrel-} % adjacent vertices
  8. defddash{mathrel{above.2exhbox to1.1em{}}}  % matched vertices
  9. prerequisite{GB_,LISA}
  10. @* The assignment problem.
  11. This demonstration program takes a matrix of numbers
  12. constructed by the {sc GB_,LISA} module and chooses at most one number from
  13. each row and column in such a way as to maximize the sum of the numbers
  14. chosen. It also reports the number of ``mems'' (memory references)
  15. expended during its computations, so that the algorithm it uses
  16. can be compared with alternative procedures.
  17. The matrix has $m$ rows and $n$ columns. If $mle n$, one number will
  18. be chosen in each row; if $mge n$, one number will be chosen in each column.
  19. The numbers in the matrix are brightness levels (pixel values) in
  20. a digitized version of the Mona Lisa.
  21. Of course the author does not pretend that the location of ``highlights'' in
  22. da Vinci's painting, one per row and one per column, has any application
  23. to art appreciation. However, this program does seem to have pedagogic value,
  24. because the relation between pixel values and shades of gray allows us
  25. to visualize the data underlying this special case of the
  26. assignment problem; ordinary matrices of numeric data are much harder
  27. to perceive. The nonrandom nature of pixels
  28. in a work of art might also have similarities to the ``organic'' properties
  29. of data in real-world applications.
  30. This program is optionally able to produce an encapsulated PostScript file
  31. from which the solution can be displayed graphically, with halftone shading.
  32. @ As explained in {sc GB_,LISA}, the subroutine call
  33. |lisa(m,n,d,m0,m1,n0,n1,d0,d1,@[@t\{area}@>@])| constructs an $mtimes n$
  34. matrix of integers between $0$ and~$d$, inclusive, based on the brightness
  35. levels in a rectangular region of a digitized Mona Lisa, where |m0|,
  36. |m1|, |n0|, and |n1| define that region. The raw data is obtained as a
  37. sum of |(m1-m0)(n1-n0)| pixel values between $0$ and~$255$, then
  38. scaled in such a way that sums |<=d0| are mapped to zero, sums |>=d1|
  39. are mapped to~$d$, and intermediate sums are mapped linearly to
  40. intermediate values. Default values |m1=360|, |n1=250|, |m=m1-m0|,
  41. |n=n1-n0|, |d=255|, and |d1=255(m1-m0)(n1-n0)| are substituted if any
  42. of the parameters |m|, |n|, |d|, |m1|, |n1|, or |d1| are zero.
  43. The user can specify the nine parameters |(m,n,d,m0,m1,n0,n1,d0,d1)|
  44. on the command line, at least in a UNIX/ implementation, thereby
  45. obtaining a variety of special effects; the relevant
  46. command-line options are .{m=}<number>, .{m0=}<number>, and so on,
  47. with no spaces before or after the .= signs that separate parameter
  48. names from parameter values. Additional options are also provided:
  49. .{-s} (use only Mona Lisa's $16times32$ ``smile'');
  50. .{-e} (use only her $20times50$ eyes);
  51. .{-c} (complement black/white); .{-p} (print the matrix and solution);
  52. .{-P} (produce a PostScript file .{lisa.eps} for graphic output);
  53. .{-h} (use a heuristic that applies only when $m=n$); and
  54. .{-v} or .{-V} (print verbose or Very verbose commentary about the
  55.  algorithm's performance).
  56. @^UNIX dependencies@>
  57. Here is the overall layout of this CEE/ program:
  58. @p
  59. #include "gb_graph.h" /* the GraphBase data structures */
  60. #include "gb_lisa.h" /* the |lisa| routine */
  61. @h@#
  62. @<Global variables@>@;
  63. main(argc,argv)
  64.   int argc; /* the number of command-line arguments */
  65.   char *argv[]; /* an array of strings containing those arguments */
  66. {@+@<Local variables@>@;@#
  67.   @<Scan the command-line options@>;
  68.   mtx=lisa(m,n,d,m0,m1,n0,n1,d0,d1,working_storage);
  69.   if (mtx==NULL) {
  70.     fprintf(stderr,"Sorry, can't create the matrix! (error code %ld)n",
  71.              panic_code);
  72.     return -1;
  73.   }
  74.   printf("Assignment problem for %s%sn",lisa_id,(compl?", complemented":""));
  75.   sscanf(lisa_id,"lisa(%lu,%lu,%lu",&m,&n,&d); /* adjust for defaults */
  76.   if (m!=n) heur=0;
  77.   if (printing) @<Display the input matrix@>;
  78.   if (PostScript) @<Output the input matrix in PostScript format@>;
  79.   mems=0;
  80.   @<Solve the assignment problem@>;
  81.   if (printing) @<Display the solution@>;
  82.   if (PostScript) @<Output the solution in PostScript format@>;
  83.   printf("Solved in %ld mems%s.n",mems,
  84.    (heur?" with square-matrix heuristic":""));
  85.   return 0; /* normal exit */
  86. }
  87. @ @<Glob...@>=
  88. Area working_storage; /* where to put the input data and auxiliary arrays */
  89. long *mtx; /* input data for the assignment problem */
  90. long mems; /* the number of memory references counted
  91.                     while solving the problem */
  92. @ The following local variables are related to the command-line options:
  93. @<Local v...@>=
  94. unsigned long m=0,n=0; /* number of rows and columns desired */
  95. unsigned long d=0; /* number of pixel values desired, minus~1 */
  96. unsigned long m0=0,m1=0; /* input will be from rows $[|m0|,.,.,|m1|)$ */
  97. unsigned long n0=0,n1=0; /* and from columns $[|n0|,.,.,|n1|)$ */
  98. unsigned long d0=0,d1=0; /* lower and upper threshold of raw pixel scores */
  99. long compl=0; /* should the input values be complemented? */
  100. long heur=0; /* should the square-matrix heuristic be used? */
  101. long printing=0; /* should the input matrix and solution be printed? */
  102. long PostScript=0; /* should an encapsulated PostScript file be produced? */
  103. @ @<Scan the command-line options@>=
  104. while (--argc) {
  105. @^UNIX dependencies@>
  106.   if (sscanf(argv[argc],"m=%lu",&m)==1) ;
  107.   else if (sscanf(argv[argc],"n=%lu",&n)==1) ;
  108.   else if (sscanf(argv[argc],"d=%lu",&d)==1) ;
  109.   else if (sscanf(argv[argc],"m0=%lu",&m0)==1) ;
  110.   else if (sscanf(argv[argc],"m1=%lu",&m1)==1) ;
  111.   else if (sscanf(argv[argc],"n0=%lu",&n0)==1) ;
  112.   else if (sscanf(argv[argc],"n1=%lu",&n1)==1) ;
  113.   else if (sscanf(argv[argc],"d0=%lu",&d0)==1) ;
  114.   else if (sscanf(argv[argc],"d1=%lu",&d1)==1) ;
  115.   else if (strcmp(argv[argc],"-s")==0) {
  116.     smile; /* sets |m0|, |m1|, |n0|, |n1| */
  117.     d1=100000; /* makes the pixels brighter */
  118.   } else if (strcmp(argv[argc],"-e")==0) {
  119.     eyes;
  120.     d1=200000;
  121.   } else if (strcmp(argv[argc],"-c")==0) compl=1;
  122.   else if (strcmp(argv[argc],"-h")==0) heur=1;
  123.   else if (strcmp(argv[argc],"-v")==0) verbose=1;
  124.   else if (strcmp(argv[argc],"-V")==0) verbose=2; /* terrifically verbose */
  125.   else if (strcmp(argv[argc],"-p")==0) printing=1;
  126.   else if (strcmp(argv[argc],"-P")==0) PostScript=1;
  127.   else {
  128.     fprintf(stderr,
  129.        "Usage: %s [param=value] [-s] [-c] [-h] [-v] [-p] [-P]n",argv[0]);
  130.     return -2;
  131.   }
  132. }
  133. @ @<Display the input matrix@>=
  134. for (k=0;k<m;k++) {
  135.   for (l=0;l<n;l++) printf("% 4ld",compl?d-*(mtx+k*n+l):*(mtx+k*n+l));
  136.   printf("n");
  137. }
  138. @ We obtain a crude but useful estimate of the computation time
  139. by counting mem units, as explained in the {sc MILES_,SPAN} program.
  140. @d o mems++
  141. @d oo mems+=2
  142. @d ooo mems+=3
  143. @* Algorithmic overview. The assignment problem is the classical
  144. problem of weighted bipartite matching: to choose
  145. a maximum-weight set of disjoint edges in a bipartite graph. We will consider
  146. only the case of complete bipartite graphs, when the weights are
  147. specified by an $mtimes n$ matrix.
  148. An algorithm is most easily developed if we begin with the assumption
  149. that the matrix is square (i.e., that $m=n$), and if we change from
  150. maximization to minimization. Then the assignment problem is the task
  151. of finding a permutation $pi[0]ldotspi[n-1]$ of ${0,ldots,n-1}$
  152. such that $sum_{k=0}^{n-1} a_{kpi[k]}$ is minimized, where
  153. $A=(a_{kl})$ is a given matrix of numbers $a_{kl}$ for $0le k,l<n$.
  154. The algorithm below works for arbitrary real numbers $a_{kl}$, but we
  155. will assume in our implementation that the matrix entries are integers.
  156. One way to approach the assignment problem is to make three simple
  157. observations: (a)~Adding a constant to any row of the matrix does not
  158. change the solution $pi[0]ldotspi[n-1]$. (b)~Adding a constant to
  159. any column of the matrix does not change the solution. (c)~If $a_{kl}ge0$
  160. for all $k$ and~$l$, and if $pi[0]ldotspi[n-1]$ is a permutation
  161. with the property that $a_{kpi[k]}=0$ for all~$k$, then $pi[0]ldotspi[n-1]$
  162. solves the assignment problem.
  163. The remarkable fact is that these three observations actually suffice. In
  164. other words, there is always a sequence of constants $(sigma_0,ldots,sigma_
  165. {n-1})$ and $(tau_0,ldots,tau_{n-1})$ and a permutation $pi[0]ldots
  166. pi[n-1]$ such that
  167. $$vbox{halign{$#$,hfil&quad for #hfilcr
  168. a_{kl}-sigma_k+tau_{,l}ge0& $0le k<n$ and $0le l<n$;cr
  169. a_{kpi[k]}-sigma_k+tau_{pi[k]}=0& $0le k<n$.cr}}$$
  170. @ To prove the remarkable fact just stated, we start by reviewing the
  171. theory of {sl unweighted/} bipartite matching. Any $mtimes n$ matrix
  172. $A=(a_{kl})$ defines a bipartite graph on the vertices $(r_0,ldots,r_{m-1})$
  173. and $(c_0,ldots,c_{n-1})$ if we say that $r_kdash c_l$ whenever
  174. $a_{kl}=0$; in other words, the edges of the bipartite graph are the zeroes
  175. of the matrix. Two zeroes of~$A$ are called {sl independent/} if they appear
  176. in different rows and columns; this means that the corresponding edges have
  177. no vertices in common. A set of mutually independent zeroes of the matrix
  178. therefore corresponds to a set of mutually disjoint edges, also called a
  179. {sl matching/} between rows and columns.
  180. The Hungarian mathematicians Egerv'ary and K"onig proved
  181. @^Egerv'ary, Eugen (= JenH{o})@>
  182. @:Konig}{K"onig, D'enes@>
  183. [{sl Matematikai 'es Fizikai Lapok/ bf38} (1931), 16--28, 116--119]
  184. that the maximum number of independent zeroes in a matrix is equal to
  185. the minimum number of rows and/or columns that are needed to ``cover''
  186. every zero. In other words, if we can find $p$ independent zeroes but
  187. not~$p+1$, then there is a way to choose $p$ lines in such a way that
  188. every zero of the matrix is included in at least one of the chosen lines,
  189. where a ``line'' is either a row or a column.
  190. Their proof was constructive, and it leads to a useful computer algorithm.
  191. Given a set of $p$ independent zeroes of a matrix, let us write
  192. $r_kddash c_l$ or $c_lddash r_k$ and say that $r_k$ is matched with $c_l$
  193. if $a_{kl}$ is one of these $p$ special
  194. zeroes, while we continue to write $r_kdash c_l$ or $c_ldash r_k$
  195. if $a_{kl}$ is one of the nonspecial zeroes. A given set of $p$
  196. special zeroes defines a choice of $p$ lines in the following way: Column~$c$
  197. is chosen if and only if it is reachable by a path of the form
  198. $$r^{(0)}dash c^{(1)}ddash r^{(1)}dash c^{(2)}ddashcdots
  199.   dash c^{(q)}ddash r^{(q)},,eqno(*)$$
  200. where $r^{(0)}$ is unmatched, $qge1$, and $c=c^{(q)}$. Row~$r$ is chosen if
  201. and only if it is matched with a column that is not chosen. Thus exactly
  202. $p$ lines are chosen. We can now prove that the chosen lines cover
  203. all the zeroes, unless there is a way to find $p+1$ independent zeroes.
  204. For if $cddash r$, either $c$ or $r$ has been chosen. And
  205. if $cdash r$, one of the following cases must arise. (1)~If $r$ and~$c$
  206. are both unmatched, we can increase~$p$ by matching them to each other.
  207. (2)~If $r$ is unmatched and $cddash r'$, then $c$ has been chosen, so
  208. the zero has been covered. (3)~If $r$ is matched to $c'ne c$, then
  209. either $r$ has been chosen or $c'$ has been chosen. In the latter case,
  210. there is a path of the form
  211. $$r^{(0)}dash c^{(1)}ddash r^{(1)}dash c^{(2)}ddashcdotsddash
  212.        r^{(q-1)}dash c'ddash rdash c,,$$
  213. where $r^{(0)}$ is unmatched and $qge1$.
  214. If $c$ is matched, it has therefore been chosen; otherwise we can increase $p$
  215. by redefining the matching to include
  216. $$r^{(0)}ddash c^{(1)}dash r^{(1)}ddash c^{(2)}dashcdotsdash
  217.      r^{(q-1)}ddash c'dash rddash c,.$$
  218. @ Now suppose $A$ is a {sl nonnegative/} matrix, of size $ntimes n$.
  219. Cover the zeroes of~$A$ with a minimum number of lines, $p$, using the
  220. algorithm of Egerv'ary and K"onig. If $p<n$, some elements are still
  221. uncovered, so those elements are positive. Suppose the minimum uncovered
  222. value is $delta>0$. Then we can subtract $delta$ from each unchosen row
  223. and add $delta$ to each chosen column. The net effect is to subtract~$delta$
  224. from all uncovered elements and to add~$delta$ to all doubly covered
  225. elements, while leaving all singly covered elements unchanged. This
  226. transformation causes a new zero to appear, while preserving
  227. $p$ independent zeroes of the previous matrix (since they were each
  228. vadjust{goodbreak}%
  229. covered only once). If we repeat the Egerv'ary-K"onig construction
  230. with the same $p$ independent zeroes, we find that either $p$~is no
  231. longer maximum or at least one more column has been chosen.
  232. (The new zero $rdash c$ occurs in a row~$r$ that was either unmatched
  233. or matched to a previously chosen column, because row~$r$ was not
  234. chosen.) Therefore if we repeat the process, we must eventually
  235. be able to increase $p$ until finally $p=n$. This will solve the
  236. assignment problem, proving the remarkable claim made earlier.
  237. @ If the given matrix $A$ has $m$ rows and $n>m$ columns,
  238. we can extend it artificially
  239. until it is square, by setting $a_{kl}=0$ for all $mle k<n$ and
  240. $0le l<n$. The construction above will then apply. But we need not
  241. waste time making such an extension, because it suffices to run the
  242. algorithm on the original $mtimes n$ matrix until $m$ independent zeroes
  243. have been found. The reason is that the set of matched vertices always
  244. grows monotonically in the Egerv'ary-K"onig construction: If a
  245. column is matched at some stage, it will remain matched from that time on,
  246. although it might well change partners. The $n-m$ dummy rows at the bottom
  247. of~$A$ are always chosen to be part of the covering; so the dummy entries
  248. become nonzero only in the columns that are part of some covering.
  249. Such columns are part of some matching, so they are part of the
  250. final matching. Therefore at most $m$ columns of the dummy entries
  251. become nonzero during the procedure. We can always find $n-m$ independent
  252. zeroes in the $n-m$ dummy rows of the matrix, so we need not deal with the
  253. dummy elements explicitly.
  254. @ It has been convenient to describe the algorithm by saying that
  255. we add and subtract constants to and from the columns and rows of~$A$.
  256. But all those additions and subtractions can take a lot of time. So we will
  257. merely pretend to make the adjustments that the method calls for; we will
  258. represent them implicitly by two vectors $(sigma_0,ldots,sigma_{m-1})$
  259. and $(tau_0,ldots,tau_{n-1})$. Then the current value of each matrix
  260. entry will be $a_{kl}-sigma_k+tau_{,l}$, instead of $a_{kl}$. The
  261. ``zeroes'' will be positions such that $a_{kl}=sigma_k-tau_{,l}$.
  262. Initially we will set $tau_{,l}=0$ for $0le l<n$ and $sigma_k=
  263. min{a_{k0},ldots,a_{k(n-1)}}$ for $0le k<m$. If $m=n$ we can also
  264. make sure that there's a zero in every column by subtracting
  265. $min{a_{0l},ldots,a_{(n-1)l}}$ from $a_{kl}$ for all $k$ and~$l$.
  266. (This initial adjustment can conveniently be made to the original
  267. matrix entries, instead of indirectly via the $tau$'s.) Users can
  268. discover if such a transformation is worthwhile by trying the program
  269. both with and without the .{-h} option.
  270. We have been saying a lot of things and proving a bunch of theorems,
  271. without writing any code. Let's get back into programming mode
  272. by writing the routine that is called into
  273. action when the .{-h} option has been specified:
  274. @d aa(k,l) *(mtx+k*n+l) /* a macro to access the matrix elements */
  275. @<Subtract column minima in order to start with lots of zeroes@>=
  276. {
  277.   for (l=0; l<n; l++) {
  278.     o,s=aa(0,l); /* the |o| macro counts one mem */
  279.     for (k=1;k<n;k++) 
  280.       if (o,aa(k,l)<s) s=aa(k,l);
  281.     if (s!=0)
  282.       for (k=0;k<n;k++)
  283.         oo,aa(k,l)-=s; /* |oo| counts two mems */
  284.   }
  285.   if (verbose) printf(" The heuristic has cost %ld mems.n",mems);
  286. }
  287. @ @<Local var...@>=
  288. register long k; /* the current row of interest */
  289. register long l; /* the current column of interest */
  290. register long j; /* another interesting column */
  291. register long s; /* the current matrix element of interest */
  292. @* Algorithmic details.
  293. The algorithm sketched above is quite simple, except that we did not
  294. discuss how to determine the chosen columns~$c^{(q)}$ that
  295. are reachable by paths of the stated form $(*)$. It is easy to find
  296. all such columns by constructing an unordered forest whose nodes are rows,
  297. beginning with all unmatched rows~$r^{(0)}$ and adding a row~$r$
  298. for which $cddash r$ when $c$ is adjacent to a row already in the forest.
  299. Our data structure, which is based on suggestions of Papadimitriou and
  300. @^Papadimitriou, Christos Harilaos@>
  301. @^Steiglitz, Kenneth@>
  302. Steiglitz [{sl Combinatorial Optimization/} (Prentice-Hall, 1982),
  303. $mathchar"278$11.1], will use several arrays. If row~$r$ is matched
  304. with column~$c$, we will have |col_mate[r]=c| and |row_mate[c]=r|;
  305. if row~$r$ is unmatched, |col_mate[r]| will be |-1|, and
  306. if column~$c$ is unmatched, |row_mate[c]| will be |-1|.
  307. If column~$c$ has a mate and is also reachable in a path of the form $(*)$,
  308. we will have $|parent_row|[c]=r'$ for some $r'$ in the forest. Otherwise
  309. column~$c$ is not chosen, and we will have |parent_row[c]=-1|. The rows
  310. in the current forest will be called |unchosen_row[0]| through
  311. |unchosen_row[t-1]|, where |t| is the current total number of nodes.
  312. The amount $sigma_k$ subtracted from row $k$ is called |row_dec[k]|; the
  313. amount $tau_{,l}$ added to column~$l$ is called |col_inc[l]|. To
  314. compute the minimum uncovered element efficiently, we maintain a
  315. quantity called |slack[l]|, which represents the minimum uncovered element
  316. in each column. More precisely, if column~$l$ is not chosen,
  317. |slack[l]| is the minimum of $a_{kl}
  318. -sigma_k+tau_{,l}$ for $kin{|unchosen_row|[0],ldots,allowbreak
  319. |unchosen_row|[q-1]}$, where $qle t$ is the number of rows in the
  320. forest that we have explored so far. We also remember |slack_row[l]|,
  321. the number of a row where the stated minimum occurs.
  322. Column $l$ is chosen if and only if |parent_row[l]>=0|. We will arrange
  323. things so that we also have |slack[l]=0| in every chosen column.
  324. @<Local var...@>=
  325. long* col_mate; /* the column matching a given row, or $-1$ */
  326. long* row_mate; /* the row matching a given column, or $-1$ */
  327. long* parent_row; /* ancestor of a given column's mate, or $-1$ */
  328. long* unchosen_row; /* node in the forest */
  329. long t; /* total number of nodes in the forest */
  330. long q; /* total number of explored nodes in the forest */
  331. long* row_dec; /* $sigma_k$, the amount subtracted from a given row */
  332. long* col_inc; /* $tau_{,l}$, the amount added to a given column */
  333. long* slack; /* minimum uncovered entry seen in a given column */
  334. long* slack_row; /* where the |slack| in a given column can be found */
  335. long unmatched; /* this many rows have yet to be matched */
  336. @ @<Allocate the intermediate data structures@>=
  337. col_mate=gb_typed_alloc(m,long,working_storage);
  338. row_mate=gb_typed_alloc(n,long,working_storage);
  339. parent_row=gb_typed_alloc(n,long,working_storage);
  340. unchosen_row=gb_typed_alloc(m,long,working_storage);
  341. row_dec=gb_typed_alloc(m,long,working_storage);
  342. col_inc=gb_typed_alloc(n,long,working_storage);
  343. slack=gb_typed_alloc(n,long,working_storage);
  344. slack_row=gb_typed_alloc(n,long,working_storage);
  345. if (gb_trouble_code) {
  346.   fprintf(stderr,"Sorry, out of memory!n"); return -3;
  347. }
  348. @ The algorithm operates in stages, where each stage terminates
  349. when we are able to increase the number of matched elements.
  350. The first stage is different from the others; it simply goes through
  351. the matrix and looks for zeroes, matching as many rows and columns
  352. as it can. This stage also initializes table entries that will be
  353. useful in later stages.
  354. @d INF 0x7fffffff /* infinity (or darn near) */
  355. @<Do the initial stage@>=
  356. t=0; /* the forest starts out empty */
  357. for (l=0; l<n; l++) {
  358.   o,row_mate[l]=-1;
  359.   o,parent_row[l]=-1;
  360.   o,col_inc[l]=0;
  361.   o,slack[l]=INF;
  362. }
  363. for (k=0; k<m; k++) {
  364.   o,s=aa(k,0); /* get ready to calculate the minimum entry of row $k$ */
  365.   for (l=1; l<n; l++) if (o,aa(k,l)<s) s=aa(k,l);
  366.   o,row_dec[k]=s;
  367.   for (l=0; l<n; l++)
  368.     if ((o,s==aa(k,l)) && (o,row_mate[l]<0)) {
  369.       o,col_mate[k]=l;
  370.       o,row_mate[l]=k;
  371.       if (verbose>1) printf(" matching col %ld==row %ldn",l,k);
  372.       goto row_done;
  373.     }
  374.   o,col_mate[k]=-1;
  375.   if (verbose>1) printf("  node %ld: unmatched row %ldn",t,k);
  376.   o,unchosen_row[t++]=k;
  377. row_done:;
  378. }
  379. @ If a subsequent stage has not succeeded in matching every row,
  380. we prepare for a new stage by reinitializing the forest as follows.
  381. @<Get ready for another stage@>=
  382. t=0;
  383. for (l=0; l<n; l++) {
  384.   o,parent_row[l]=-1;
  385.   o,slack[l]=INF;
  386. }
  387. for (k=0; k<m; k++)
  388.   if (o,col_mate[k]<0) {
  389.     if (verbose>1) printf("  node %ld: unmatched row %ldn",t,k);
  390.     o,unchosen_row[t++]=k;
  391.   }
  392. @ Here, then, is the algorithm's overall control structure.
  393. There are at most $m$ stages, and each stage does $O(mn)$ operations,
  394. so the total running time is $O(m^2n)$.
  395. @<Do the Hungarian algorithm@>=
  396. @<Do the initial stage@>;
  397. if (t==0) goto done;
  398. unmatched=t;
  399. while(1) {
  400.   if (verbose) printf(" After %ld mems I've matched %ld rows.n",mems,m-t);
  401.   q=0;
  402.   while(1) {
  403.     while (q<t) {
  404.       @<Explore node |q| of the forest;
  405.         if the matching can be increased, |goto breakthru|@>;
  406.       q++;
  407.     }
  408.     @<Introduce a new zero into the matrix by modifying |row_dec| and
  409.       |col_inc|; if the matching can be increased, |goto breakthru|@>;
  410.   }
  411. breakthru: @<Update the matching by pairing row $k$ with column $l$@>;
  412.   if(--unmatched==0) goto done;
  413.   @<Get ready for another stage@>;
  414. }
  415. done: @<Doublecheck the solution@>;
  416. @ @<Explore node |q| of the forest;
  417.       if the matching can be increased, |goto breakthru|@>=
  418. {
  419.   o,k=unchosen_row[q];
  420.   o,s=row_dec[k];
  421.   for (l=0; l<n; l++)
  422.     if (o,slack[l]) {@+register long del;
  423.       oo,del=aa(k,l)-s+col_inc[l];
  424.       if (del<slack[l]) {
  425.         if (del==0) { /* we found a new zero */
  426.           if (o,row_mate[l]<0) goto breakthru;
  427.           o,slack[l]=0; /* this column will now be chosen */
  428.           o,parent_row[l]=k;
  429.           if (verbose>1) printf("  node %ld: row %ld==col %ld--row %ldn",
  430.                                     t,row_mate[l],l,k);
  431.           oo,unchosen_row[t++]=row_mate[l];
  432.         }@+else {
  433.           o,slack[l]=del;
  434.           o,slack_row[l]=k;
  435.         }
  436.       }
  437.     }
  438. }
  439. @ At this point, column $l$ is unmatched, and row $k$ is in
  440. the forest. By following parent links in the forest,
  441. we can rematch rows and columns so that a previously unmatched row~$r^{(0)}$
  442. gets a mate.
  443. @<Update the matching by pairing row $k$ with column $l$@>=
  444. if (verbose) printf(" Breakthrough at node %ld of %ld!n",q,t);
  445. while (1) {
  446.   o,j=col_mate[k];
  447.   o,col_mate[k]=l;
  448.   o,row_mate[l]=k;
  449.   if (verbose>1) printf(" rematching col %ld==row %ldn",l,k);
  450.   if (j<0) break;
  451.   o,k=parent_row[j];
  452.   l=j;
  453. }
  454. @ If we get to this point, we have explored the entire forest; none of
  455. the unchosen rows has led to a breakthrough. An unchosen column with
  456. smallest |slack| will allow us to make further progress.
  457. @<Introduce a new zero into the matrix by modifying |row_dec| and |col_inc|;
  458.         if the matching can be increased, |goto breakthru|@>=
  459. s=INF;
  460. for (l=0; l<n; l++)
  461.   if (o,slack[l] && slack[l]<s)
  462.     s=slack[l];
  463. for (q=0; q<t; q++)
  464.   ooo,row_dec[unchosen_row[q]]+=s;
  465. for (l=0; l<n; l++)
  466.   if (o,slack[l])  { /* column $l$ is not chosen */
  467.     o,slack[l]-=s;
  468.     if (slack[l]==0) @<Look at a new zero, and |goto breakthru| with
  469.                          |col_inc| up to date if there's a breakthrough@>;
  470.   }@+else oo,col_inc[l]+=s;
  471. @ There might be several columns tied for smallest slack. If any of them
  472. leads to a breakthrough, we are very happy; but we must finish the loop on~|l|
  473. before going to |breakthru|, because the |col_inc| variables
  474. need to be maintained for the next stage.
  475. Within column |l|, there might be several rows that produce the same slack;
  476. we have remembered only one of them, |slack_row[l]|. Fortunately, one is
  477. sufficient for our purposes. Either we have a breakthrough or we choose
  478. column~|l|, regardless of which row or rows led us to consider that column.
  479. @<Look at a new zero, and |goto breakthru| with
  480.                          |col_inc| up to date if there's a breakthrough@>=
  481. {
  482.   o,k=slack_row[l];
  483.   if (verbose>1)
  484.    printf(" Decreasing uncovered elements by %ld produces zero at [%ld,%ld]n",
  485.       s,k,l);
  486.   if (o,row_mate[l]<0) {
  487.     for (j=l+1; j<n; j++)
  488.       if (o,slack[j]==0) oo,col_inc[j]+=s;
  489.     goto breakthru;
  490.   }@+else { /* not a breakthrough, but the forest continues to grow */
  491.     o,parent_row[l]=k;
  492.     if (verbose>1) printf("  node %ld: row %ld==col %ld--row %ldn",
  493.                                   t,row_mate[l],l,k);
  494.     oo,unchosen_row[t++]=row_mate[l];
  495.   }
  496. }
  497. @ The code in the present section is redundant, unless cosmic
  498. radiation has caused the hardware to malfunction. But there is some
  499. reassurance whenever we find that mathematics still appears to be
  500. consistent, so the author could not resist writing these few unnecessary lines,
  501. which verify that the assignment problem has indeed been solved optimally.
  502. (We don't count the mems.)
  503. @^discussion of \{mems}@>
  504. @<Doublecheck...@>=
  505. for (k=0;k<m;k++)
  506.   for (l=0;l<n;l++)
  507.     if (aa(k,l)<row_dec[k]-col_inc[l]) {
  508.       fprintf(stderr,"Oops, I made a mistake!n");
  509.       return -6; /* can't happen */
  510.     }
  511. for (k=0;k<m;k++) {
  512.   l=col_mate[k];
  513.   if (l<0 || aa(k,l)!=row_dec[k]-col_inc[l]) {
  514.     fprintf(stderr,"Oops, I blew it!n"); return-66; /* can't happen */
  515.   }
  516. }
  517. k=0;
  518. for (l=0;l<n;l++) if (col_inc[l]) k++;
  519. if (k>m) {
  520.   fprintf(stderr,"Oops, I adjusted too many columns!n");
  521.   return-666; /* can't happen */
  522. }
  523. @* Interfacing.
  524. A few nitty-gritty details still need to be handled: Our algorithm
  525. is not symmetric between rows and columns, and it works only for $mle n$;
  526. so we will transpose the matrix when
  527. $m>n$. Furthermore, our algorithm minimizes, but we actually want
  528. it to maximize (except when |compl| is nonzero).
  529. Hence, we want to make the following transformations to the data before
  530. processing it with the algorithm developed above.
  531. @<Solve the assignment problem@>=
  532. if (m>n) @<Transpose the matrix@>@;
  533. else transposed=0;
  534. @<Allocate the intermediate data structures@>;
  535. if (compl==0)
  536.   for (k=0; k<m; k++) for (l=0; l<n; l++)
  537.     aa(k,l)=d-aa(k,l);
  538. if (heur) @<Subtract column minima...@>;
  539. @<Do the Hungarian algorithm@>;
  540. @ @<Transpose...@>=
  541. {
  542.   if (verbose>1) printf("Temporarily transposing rows and columns...n");
  543.   tmtx=gb_typed_alloc(m*n,long,working_storage);
  544.   if (tmtx==NULL) {
  545.     fprintf(stderr,"Sorry, out of memory!n");@+return -4;
  546.   }
  547.   for (k=0; k<m; k++) for (l=0; l<n; l++)
  548.     *(tmtx+l*m+k)=*(mtx+k*n+l);
  549.   m=n;@+n=k; /* |k| holds the former value of |m| */
  550.   mtx=tmtx;
  551.   transposed=1;
  552. }
  553. @ @<Local v...@>=
  554. long* tmtx; /* the transpose of |mtx| */
  555. long transposed; /* has the data been transposed? */
  556. @ @<Display the solution@>=
  557. {
  558.   printf("The following entries produce an optimum assignment:n");
  559.   for (k=0; k<m; k++)
  560.     printf(" [%ld,%ld]n",@|
  561.      transposed? col_mate[k]:k,@|
  562.      transposed? k:col_mate[k]);
  563. }
  564. @* Encapsulated PostScript.
  565. A special output file called .{lisa.eps} is written if the user has
  566. selected the .{-P} option. This file contains a sequence of
  567. PostScript commands that can be used to generate an illustration
  568. within many kinds of documents. For example, if TEX/ is being used
  569. with the .{dvips} output driver from Radical Eye Software and with the
  570. @.dvips@>
  571. associated .{epsf.tex} macros, one can say
  572. $$.{\epsfxsize=10cm \epsfbox{lisa.eps}}$$
  573. within a TEX/ document and the illustration will be typeset in
  574. a box that is 10 centimeters wide.
  575. The conventions of PostScript allow the illustration to be scaled to
  576. any size. Best results are probably obtained if each pixel is at
  577. least one millimeter wide (about 1/25 inch) when printed.
  578. The illustration is formed by first
  579. ``painting'' the input data as a rectangle of pixels,
  580. with up to 256 shades of gray. Then the solution pixels are
  581. framed in black, with a white trim just inside the black edges
  582. to help make the frame visible in already-dark places. The frames are
  583. created by painting over the original image; the
  584. center of each solution pixel retains its original color.
  585. Encapsulated PostScript files have a simple format that is recognized
  586. by many software packages and printing devices. We use a subset of
  587. PostScript that should be easy to convert to other languages if necessary.
  588. @<Output the input matrix in PostScript format@>=
  589. {
  590.   eps_file=fopen("lisa.eps","w");
  591.   if (!eps_file) {
  592.     fprintf(stderr,"Sorry, I can't open the file `lisa.eps'!n");
  593.     PostScript=0;
  594.   }@+else {
  595.     fprintf(eps_file,"%%!PS-Adobe-3.0 EPSF-3.0n");
  596.         /* .{1.0} and .{2.0} also OK */
  597.     fprintf(eps_file,"%%%%BoundingBox: -1 -1 %ld %ldn",n+1,m+1);
  598.     fprintf(eps_file,"/buffer %ld string defn",n);
  599.     fprintf(eps_file,"%ld %ld 8 [%ld 0 0 -%ld 0 %ld]n",n,m,n,m,m);
  600.     fprintf(eps_file,"{currentfile buffer readhexstring pop} bindn");
  601.     fprintf(eps_file,"gsave %ld %ld scale imagen",n,m);
  602.     for (k=0;k<m;k++) @<Output row |k| as a hexadecimal string@>;
  603.     fprintf(eps_file,"grestoren");
  604.   }
  605. }
  606. @ @<Glob...@>=
  607. FILE *eps_file; /* file for encapsulated PostScript output */
  608. @ This program need not produce machine-independent output, so we can
  609. safely use floating-point arithmetic here. At most 64 characters
  610. (32 pixel-bytes) are output on each line.
  611. @<Output row |k|...@>=
  612. {@+register float conv=255.0/(float)d; register long x;
  613.   for (l=0; l<n; l++) {
  614.     x=(long)(conv*(float)(compl?d-aa(k,l):aa(k,l)));
  615.     fprintf(eps_file,"%02lx",x>255?255L:x);
  616.     if ((l&0x1f)==0x1f) fprintf(eps_file,"n");
  617.   }
  618.   if (n&0x1f) fprintf(eps_file,"n");
  619. }
  620. @ @<Output the solution in PostScript format@>=
  621. {
  622.   fprintf(eps_file,
  623.     "/bx {moveto 0 1 rlineto 1 0 rlineto 0 -1 rlineto closepathn");
  624.   fprintf(eps_file," gsave .3 setlinewidth 1 setgray clip stroke");
  625.   fprintf(eps_file," grestore stroke} bind defn");
  626.   fprintf(eps_file," .1 setlinewidthn");
  627.   for (k=0; k<m; k++)
  628.     fprintf(eps_file," %ld %ld bxn",@|
  629.      transposed? k:col_mate[k],@|
  630.      transposed? n-1-col_mate[k]:m-1-k);
  631.   fclose(eps_file);
  632. }
  633. @* Index. As usual, we close with a list of identifier definitions and uses.