⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 assign_lisa.w

📁 模拟器提供了一个简单易用的平台
💻 W
📖 第 1 页 / 共 2 页
字号:
% This file is part of the Stanford GraphBase (c) Stanford University 1993@i boilerplate.w %<< legal stuff: PLEASE READ IT BEFORE MAKING ANY CHANGES!@i gb_types.w% PostScript is a registered trade mark of Adobe Systems Incorporated.\def\title{ASSIGN\_\,LISA}\def\<#1>{$\langle${\rm#1}$\rangle$}\def\dash{\mathrel-\joinrel\joinrel\mathrel-} % adjacent vertices\def\ddash{\mathrel{\above.2ex\hbox to1.1em{}}}  % matched vertices@s compl normal @q unreserve a C++ keyword @>\prerequisite{GB\_\,LISA}@* The assignment problem.This demonstration program takes a matrix of numbersconstructed by the {\sc GB\_\,LISA} module and chooses at most one number fromeach row and column in such a way as to maximize the sum of the numberschosen. It also reports the number of ``mems'' (memory references)expended during its computations, so that the algorithm it usescan be compared with alternative procedures.The matrix has $m$ rows and $n$ columns. If $m\le n$, one number willbe chosen in each row; if $m\ge n$, one number will be chosen in each column.The numbers in the matrix are brightness levels (pixel values) ina digitized version of the Mona Lisa.Of course the author does not pretend that the location of ``highlights'' inda Vinci's painting, one per row and one per column, has any applicationto art appreciation. However, this program does seem to have pedagogic value,because the relation between pixel values and shades of gray allows usto visualize the data underlying this special case of theassignment problem; ordinary matrices of numeric data are much harderto perceive. The nonrandom nature of pixelsin a work of art might also have similarities to the ``organic'' propertiesof data in real-world applications.This program is optionally able to produce an encapsulated PostScript filefrom which the solution can be displayed graphically, with halftone shading.@ As explained in {\sc GB\_\,LISA}, the subroutine call|lisa(m,n,d,m0,m1,n0,n1,d0,d1,@[@t\\{area}@>@])| constructs an $m\times n$matrix of integers between $0$ and~$d$, inclusive, based on the brightnesslevels in a rectangular region of a digitized Mona Lisa, where |m0|,|m1|, |n0|, and |n1| define that region. The raw data is obtained as asum of |(m1-m0)(n1-n0)| pixel values between $0$ and~$255$, thenscaled in such a way that sums |<=d0| are mapped to zero, sums |>=d1|are mapped to~$d$, and intermediate sums are mapped linearly tointermediate values. Default values |m1=360|, |n1=250|, |m=m1-m0|,|n=n1-n0|, |d=255|, and |d1=255(m1-m0)(n1-n0)| are substituted if anyof the parameters |m|, |n|, |d|, |m1|, |n1|, or |d1| are zero.The user can specify the nine parameters |(m,n,d,m0,m1,n0,n1,d0,d1)|on the command line, at least in a \UNIX/ implementation, therebyobtaining a variety of special effects; the relevantcommand-line options are \.{m=}\<number>, \.{m0=}\<number>, and so on,with no spaces before or after the \.= signs that separate parameternames from parameter values. Additional options are also provided:\.{-s} (use only Mona Lisa's $16\times32$ ``smile'');\.{-e} (use only her $20\times50$ eyes);\.{-c} (complement black/white); \.{-p} (print the matrix and solution);\.{-P} (produce a PostScript file \.{lisa.eps} for graphic output);\.{-h} (use a heuristic that applies only when $m=n$); and\.{-v} or \.{-V} (print verbose or Very verbose commentary about the algorithm's performance).@^UNIX dependencies@>Here is the overall layout of this \CEE/ program:@p#include "gb_graph.h" /* the GraphBase data structures */#include "gb_lisa.h" /* the |lisa| routine */@h@#@<Global variables@>@;main(argc,argv)  int argc; /* the number of command-line arguments */  char *argv[]; /* an array of strings containing those arguments */{@+@<Local variables@>@;@#  @<Scan the command-line options@>;  mtx=lisa(m,n,d,m0,m1,n0,n1,d0,d1,working_storage);  if (mtx==NULL) {    fprintf(stderr,"Sorry, can't create the matrix! (error code %ld)\n",             panic_code);    return -1;  }  printf("Assignment problem for %s%s\n",lisa_id,(compl?", complemented":""));  sscanf(lisa_id,"lisa(%lu,%lu,%lu",&m,&n,&d); /* adjust for defaults */  if (m!=n) heur=0;  if (printing) @<Display the input matrix@>;  if (PostScript) @<Output the input matrix in PostScript format@>;  mems=0;  @<Solve the assignment problem@>;  if (printing) @<Display the solution@>;  if (PostScript) @<Output the solution in PostScript format@>;  printf("Solved in %ld mems%s.\n",mems,   (heur?" with square-matrix heuristic":""));  return 0; /* normal exit */}@ @<Glob...@>=Area working_storage; /* where to put the input data and auxiliary arrays */long *mtx; /* input data for the assignment problem */long mems; /* the number of memory references counted                    while solving the problem */@ The following local variables are related to the command-line options:@<Local v...@>=unsigned long m=0,n=0; /* number of rows and columns desired */unsigned long d=0; /* number of pixel values desired, minus~1 */unsigned long m0=0,m1=0; /* input will be from rows $[|m0|\,.\,.\,|m1|)$ */unsigned long n0=0,n1=0; /* and from columns $[|n0|\,.\,.\,|n1|)$ */unsigned long d0=0,d1=0; /* lower and upper threshold of raw pixel scores */long compl=0; /* should the input values be complemented? */long heur=0; /* should the square-matrix heuristic be used? */long printing=0; /* should the input matrix and solution be printed? */long PostScript=0; /* should an encapsulated PostScript file be produced? */@ @<Scan the command-line options@>=while (--argc) {@^UNIX dependencies@>  if (sscanf(argv[argc],"m=%lu",&m)==1) ;  else if (sscanf(argv[argc],"n=%lu",&n)==1) ;  else if (sscanf(argv[argc],"d=%lu",&d)==1) ;  else if (sscanf(argv[argc],"m0=%lu",&m0)==1) ;  else if (sscanf(argv[argc],"m1=%lu",&m1)==1) ;  else if (sscanf(argv[argc],"n0=%lu",&n0)==1) ;  else if (sscanf(argv[argc],"n1=%lu",&n1)==1) ;  else if (sscanf(argv[argc],"d0=%lu",&d0)==1) ;  else if (sscanf(argv[argc],"d1=%lu",&d1)==1) ;  else if (strcmp(argv[argc],"-s")==0) {    smile; /* sets |m0|, |m1|, |n0|, |n1| */    d1=100000; /* makes the pixels brighter */  } else if (strcmp(argv[argc],"-e")==0) {    eyes;    d1=200000;  } else if (strcmp(argv[argc],"-c")==0) compl=1;  else if (strcmp(argv[argc],"-h")==0) heur=1;  else if (strcmp(argv[argc],"-v")==0) verbose=1;  else if (strcmp(argv[argc],"-V")==0) verbose=2; /* terrifically verbose */  else if (strcmp(argv[argc],"-p")==0) printing=1;  else if (strcmp(argv[argc],"-P")==0) PostScript=1;  else {    fprintf(stderr,       "Usage: %s [param=value] [-s] [-c] [-h] [-v] [-p] [-P]\n",argv[0]);    return -2;  }}@ @<Display the input matrix@>=for (k=0;k<m;k++) {  for (l=0;l<n;l++) printf("% 4ld",compl?d-*(mtx+k*n+l):*(mtx+k*n+l));  printf("\n");}@ We obtain a crude but useful estimate of the computation timeby counting mem units, as explained in the {\sc MILES\_\,SPAN} program.@d o mems++@d oo mems+=2@d ooo mems+=3@* Algorithmic overview. The assignment problem is the classicalproblem of weighted bipartite matching: to choosea maximum-weight set of disjoint edges in a bipartite graph. We will consideronly the case of complete bipartite graphs, when the weights arespecified by an $m\times n$ matrix.An algorithm is most easily developed if we begin with the assumptionthat the matrix is square (i.e., that $m=n$), and if we change frommaximization to minimization. Then the assignment problem is the taskof finding a permutation $\pi[0]\ldots\pi[n-1]$ of $\{0,\ldots,n-1\}$such that $\sum_{k=0}^{n-1} a_{k\pi[k]}$ is minimized, where$A=(a_{kl})$ is a given matrix of numbers $a_{kl}$ for $0\le k,l<n$.The algorithm below works for arbitrary real numbers $a_{kl}$, but wewill assume in our implementation that the matrix entries are integers.One way to approach the assignment problem is to make three simpleobservations: (a)~Adding a constant to any row of the matrix does notchange the solution $\pi[0]\ldots\pi[n-1]$. (b)~Adding a constant toany column of the matrix does not change the solution. (c)~If $a_{kl}\ge0$for all $k$ and~$l$, and if $\pi[0]\ldots\pi[n-1]$ is a permutationwith the property that $a_{k\pi[k]}=0$ for all~$k$, then $\pi[0]\ldots\pi[n-1]$solves the assignment problem.The remarkable fact is that these three observations actually suffice. Inother words, there is always a sequence of constants $(\sigma_0,\ldots,\sigma_{n-1})$ and $(\tau_0,\ldots,\tau_{n-1})$ and a permutation $\pi[0]\ldots\pi[n-1]$ such that$$\vbox{\halign{$#$,\hfil&\quad for #\hfil\cra_{kl}-\sigma_k+\tau_{\,l}\ge0& $0\le k<n$ and $0\le l<n$;\cra_{k\pi[k]}-\sigma_k+\tau_{\pi[k]}=0& $0\le k<n$.\cr}}$$@ To prove the remarkable fact just stated, we start by reviewing thetheory of {\sl unweighted\/} bipartite matching. Any $m\times n$ matrix$A=(a_{kl})$ defines a bipartite graph on the vertices $(r_0,\ldots,r_{m-1})$and $(c_0,\ldots,c_{n-1})$ if we say that $r_k\dash c_l$ whenever$a_{kl}=0$; in other words, the edges of the bipartite graph are the zeroesof the matrix. Two zeroes of~$A$ are called {\sl independent\/} if they appearin different rows and columns; this means that the corresponding edges haveno vertices in common. A set of mutually independent zeroes of the matrixtherefore corresponds to a set of mutually disjoint edges, also called a{\sl matching\/} between rows and columns.The Hungarian mathematicians Egerv\'ary and K\H{o}nig proved@^Egerv\'ary, Eugen (= Jen\H{o})@>@:Konig}{K\H{o}nig, D\'enes@>[{\sl Matematikai \'es Fizikai Lapok\/ \bf38} (1931), 16--28, 116--119]that the maximum number of independent zeroes in a matrix is equal tothe minimum number of rows and/or columns that are needed to ``cover''every zero. In other words, if we can find $p$ independent zeroes butnot~$p+1$, then there is a way to choose $p$ lines in such a way thatevery zero of the matrix is included in at least one of the chosen lines,where a ``line'' is either a row or a column.Their proof was constructive, and it leads to a useful computer algorithm.Given a set of $p$ independent zeroes of a matrix, let us write$r_k\ddash c_l$ or $c_l\ddash r_k$ and say that $r_k$ is matched with $c_l$if $a_{kl}$ is one of these $p$ specialzeroes, while we continue to write $r_k\dash c_l$ or $c_l\dash r_k$if $a_{kl}$ is one of the nonspecial zeroes. A given set of $p$special zeroes defines a choice of $p$ lines in the following way: Column~$c$is chosen if and only if it is reachable by a path of the form$$r^{(0)}\dash c^{(1)}\ddash r^{(1)}\dash c^{(2)}\ddash\cdots  \dash c^{(q)}\ddash r^{(q)}\,,\eqno(*)$$where $r^{(0)}$ is unmatched, $q\ge1$, and $c=c^{(q)}$. Row~$r$ is chosen ifand only if it is matched with a column that is not chosen. Thus exactly$p$ lines are chosen. We can now prove that the chosen lines coverall the zeroes, unless there is a way to find $p+1$ independent zeroes.For if $c\ddash r$, either $c$ or $r$ has been chosen. Andif $c\dash r$, one of the following cases must arise. (1)~If $r$ and~$c$are both unmatched, we can increase~$p$ by matching them to each other.(2)~If $r$ is unmatched and $c\ddash r'$, then $c$ has been chosen, sothe zero has been covered. (3)~If $r$ is matched to $c'\ne c$, theneither $r$ has been chosen or $c'$ has been chosen. In the latter case,there is a path of the form$$r^{(0)}\dash c^{(1)}\ddash r^{(1)}\dash c^{(2)}\ddash\cdots\ddash       r^{(q-1)}\dash c'\ddash r\dash c\,,$$where $r^{(0)}$ is unmatched and $q\ge1$.If $c$ is matched, it has therefore been chosen; otherwise we can increase $p$by redefining the matching to include$$r^{(0)}\ddash c^{(1)}\dash r^{(1)}\ddash c^{(2)}\dash\cdots\dash     r^{(q-1)}\ddash c'\dash r\ddash c\,.$$@ Now suppose $A$ is a {\sl nonnegative\/} matrix, of size $n\times n$.Cover the zeroes of~$A$ with a minimum number of lines, $p$, using thealgorithm of Egerv\'ary and K\H{o}nig. If $p<n$, some elements are stilluncovered, so those elements are positive. Suppose the minimum uncoveredvalue is $\delta>0$. Then we can subtract $\delta$ from each unchosen rowand add $\delta$ to each chosen column. The net effect is to subtract~$\delta$from all uncovered elements and to add~$\delta$ to all doubly coveredelements, while leaving all singly covered elements unchanged. Thistransformation causes a new zero to appear, while preserving$p$ independent zeroes of the previous matrix (since they were each\vadjust{\goodbreak}%covered only once). If we repeat the Egerv\'ary-K\H{o}nig constructionwith the same $p$ independent zeroes, we find that either $p$~is nolonger maximum or at least one more column has been chosen.(The new zero $r\dash c$ occurs in a row~$r$ that was either unmatchedor matched to a previously chosen column, because row~$r$ was notchosen.) Therefore if we repeat the process, we must eventuallybe able to increase $p$ until finally $p=n$. This will solve theassignment problem, proving the remarkable claim made earlier.@ If the given matrix $A$ has $m$ rows and $n>m$ columns,we can extend it artificiallyuntil it is square, by setting $a_{kl}=0$ for all $m\le k<n$ and$0\le l<n$. The construction above will then apply. But we need notwaste time making such an extension, because it suffices to run thealgorithm on the original $m\times n$ matrix until $m$ independent zeroeshave been found. The reason is that the set of matched vertices alwaysgrows monotonically in the Egerv\'ary-K\H{o}nig construction: If acolumn is matched at some stage, it will remain matched from that time on,although it might well change partners. The $n-m$ dummy rows at the bottomof~$A$ are always chosen to be part of the covering; so the dummy entriesbecome nonzero only in the columns that are part of some covering.Such columns are part of some matching, so they are part of thefinal matching. Therefore at most $m$ columns of the dummy entriesbecome nonzero during the procedure. We can always find $n-m$ independentzeroes in the $n-m$ dummy rows of the matrix, so we need not deal with thedummy elements explicitly.@ It has been convenient to describe the algorithm by saying thatwe add and subtract constants to and from the columns and rows of~$A$.But all those additions and subtractions can take a lot of time. So we willmerely pretend to make the adjustments that the method calls for; we willrepresent them implicitly by two vectors $(\sigma_0,\ldots,\sigma_{m-1})$and $(\tau_0,\ldots,\tau_{n-1})$. Then the current value of each matrixentry will be $a_{kl}-\sigma_k+\tau_{\,l}$, instead of $a_{kl}$. The``zeroes'' will be positions such that $a_{kl}=\sigma_k-\tau_{\,l}$.Initially we will set $\tau_{\,l}=0$ for $0\le l<n$ and $\sigma_k=\min\{a_{k0},\ldots,a_{k(n-1)}\}$ for $0\le k<m$. If $m=n$ we can alsomake sure that there's a zero in every column by subtracting$\min\{a_{0l},\ldots,a_{(n-1)l}\}$ from $a_{kl}$ for all $k$ and~$l$.(This initial adjustment can conveniently be made to the originalmatrix entries, instead of indirectly via the $\tau$'s.) Users candiscover if such a transformation is worthwhile by trying the programboth with and without the \.{-h} option.We have been saying a lot of things and proving a bunch of theorems,without writing any code. Let's get back into programming modeby writing the routine that is called intoaction when the \.{-h} option has been specified:@d aa(k,l) *(mtx+k*n+l) /* a macro to access the matrix elements */@<Subtract column minima in order to start with lots of zeroes@>={  for (l=0; l<n; l++) {    o,s=aa(0,l); /* the |o| macro counts one mem */    for (k=1;k<n;k++)       if (o,aa(k,l)<s) s=aa(k,l);    if (s!=0)      for (k=0;k<n;k++)        oo,aa(k,l)-=s; /* |oo| counts two mems */  }  if (verbose) printf(" The heuristic has cost %ld mems.\n",mems);}@ @<Local var...@>=register long k; /* the current row of interest */register long l; /* the current column of interest */register long j; /* another interesting column */register long s; /* the current matrix element of interest */@* Algorithmic details.The algorithm sketched above is quite simple, except that we did notdiscuss how to determine the chosen columns~$c^{(q)}$ thatare reachable by paths of the stated form $(*)$. It is easy to findall such columns by constructing an unordered forest whose nodes are rows,beginning with all unmatched rows~$r^{(0)}$ and adding a row~$r$for which $c\ddash r$ when $c$ is adjacent to a row already in the forest.Our data structure, which is based on suggestions of Papadimitriou and@^Papadimitriou, Christos Harilaos@>@^Steiglitz, Kenneth@>Steiglitz [{\sl Combinatorial Optimization\/} (Prentice-Hall, 1982),$\mathchar"278$11.1], will use several arrays. If row~$r$ is matchedwith column~$c$, we will have |col_mate[r]=c| and |row_mate[c]=r|;if row~$r$ is unmatched, |col_mate[r]| will be |-1|, andif column~$c$ is unmatched, |row_mate[c]| will be |-1|.If column~$c$ has a mate and is also reachable in a path of the form $(*)$,we will have $|parent_row|[c]=r'$ for some $r'$ in the forest. Otherwisecolumn~$c$ is not chosen, and we will have |parent_row[c]=-1|. The rowsin the current forest will be called |unchosen_row[0]| through|unchosen_row[t-1]|, where |t| is the current total number of nodes.The amount $\sigma_k$ subtracted from row $k$ is called |row_dec[k]|; theamount $\tau_{\,l}$ added to column~$l$ is called |col_inc[l]|. Tocompute the minimum uncovered element efficiently, we maintain aquantity called |slack[l]|, which represents the minimum uncovered elementin each column. More precisely, if column~$l$ is not chosen,|slack[l]| is the minimum of $a_{kl}-\sigma_k+\tau_{\,l}$ for $k\in\{|unchosen_row|[0],\ldots,\allowbreak

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -