wolffd@0
|
1 function [C,T]=hungarian(A)
|
wolffd@0
|
2 %HUNGARIAN Solve the Assignment problem using the Hungarian method.
|
wolffd@0
|
3 %
|
wolffd@0
|
4 %[C,T]=hungarian(A)
|
wolffd@0
|
5 %A - a square cost matrix.
|
wolffd@0
|
6 %C - the optimal assignment.
|
wolffd@0
|
7 %T - the cost of the optimal assignment.
|
wolffd@0
|
8
|
wolffd@0
|
9 % Adapted from the FORTRAN IV code in Carpaneto and Toth, "Algorithm 548:
|
wolffd@0
|
10 % Solution of the assignment problem [H]", ACM Transactions on
|
wolffd@0
|
11 % Mathematical Software, 6(1):104-111, 1980.
|
wolffd@0
|
12
|
wolffd@0
|
13 % v1.0 96-06-14. Niclas Borlin, niclas@cs.umu.se.
|
wolffd@0
|
14 % Department of Computing Science, Umeå University,
|
wolffd@0
|
15 % Sweden.
|
wolffd@0
|
16 % All standard disclaimers apply.
|
wolffd@0
|
17
|
wolffd@0
|
18 % A substantial effort was put into this code. If you use it for a
|
wolffd@0
|
19 % publication or otherwise, please include an acknowledgement or at least
|
wolffd@0
|
20 % notify me by email. /Niclas
|
wolffd@0
|
21
|
wolffd@0
|
22 [m,n]=size(A);
|
wolffd@0
|
23
|
wolffd@0
|
24 if (m~=n)
|
wolffd@0
|
25 error('HUNGARIAN: Cost matrix must be square!');
|
wolffd@0
|
26 end
|
wolffd@0
|
27
|
wolffd@0
|
28 % Save original cost matrix.
|
wolffd@0
|
29 orig=A;
|
wolffd@0
|
30
|
wolffd@0
|
31 % Reduce matrix.
|
wolffd@0
|
32 A=hminired(A);
|
wolffd@0
|
33
|
wolffd@0
|
34 % Do an initial assignment.
|
wolffd@0
|
35 [A,C,U]=hminiass(A);
|
wolffd@0
|
36
|
wolffd@0
|
37 % Repeat while we have unassigned rows.
|
wolffd@0
|
38 while (U(n+1))
|
wolffd@0
|
39 % Start with no path, no unchecked zeros, and no unexplored rows.
|
wolffd@0
|
40 LR=zeros(1,n);
|
wolffd@0
|
41 LC=zeros(1,n);
|
wolffd@0
|
42 CH=zeros(1,n);
|
wolffd@0
|
43 RH=[zeros(1,n) -1];
|
wolffd@0
|
44
|
wolffd@0
|
45 % No labelled columns.
|
wolffd@0
|
46 SLC=[];
|
wolffd@0
|
47
|
wolffd@0
|
48 % Start path in first unassigned row.
|
wolffd@0
|
49 r=U(n+1);
|
wolffd@0
|
50 % Mark row with end-of-path label.
|
wolffd@0
|
51 LR(r)=-1;
|
wolffd@0
|
52 % Insert row first in labelled row set.
|
wolffd@0
|
53 SLR=r;
|
wolffd@0
|
54
|
wolffd@0
|
55 % Repeat until we manage to find an assignable zero.
|
wolffd@0
|
56 while (1)
|
wolffd@0
|
57 % If there are free zeros in row r
|
wolffd@0
|
58 if (A(r,n+1)~=0)
|
wolffd@0
|
59 % ...get column of first free zero.
|
wolffd@0
|
60 l=-A(r,n+1);
|
wolffd@0
|
61
|
wolffd@0
|
62 % If there are more free zeros in row r and row r in not
|
wolffd@0
|
63 % yet marked as unexplored..
|
wolffd@0
|
64 if (A(r,l)~=0 & RH(r)==0)
|
wolffd@0
|
65 % Insert row r first in unexplored list.
|
wolffd@0
|
66 RH(r)=RH(n+1);
|
wolffd@0
|
67 RH(n+1)=r;
|
wolffd@0
|
68
|
wolffd@0
|
69 % Mark in which column the next unexplored zero in this row
|
wolffd@0
|
70 % is.
|
wolffd@0
|
71 CH(r)=-A(r,l);
|
wolffd@0
|
72 end
|
wolffd@0
|
73 else
|
wolffd@0
|
74 % If all rows are explored..
|
wolffd@0
|
75 if (RH(n+1)<=0)
|
wolffd@0
|
76 % Reduce matrix.
|
wolffd@0
|
77 [A,CH,RH]=hmreduce(A,CH,RH,LC,LR,SLC,SLR);
|
wolffd@0
|
78 end
|
wolffd@0
|
79
|
wolffd@0
|
80 % Re-start with first unexplored row.
|
wolffd@0
|
81 r=RH(n+1);
|
wolffd@0
|
82 % Get column of next free zero in row r.
|
wolffd@0
|
83 l=CH(r);
|
wolffd@0
|
84 % Advance "column of next free zero".
|
wolffd@0
|
85 CH(r)=-A(r,l);
|
wolffd@0
|
86 % If this zero is last in the list..
|
wolffd@0
|
87 if (A(r,l)==0)
|
wolffd@0
|
88 % ...remove row r from unexplored list.
|
wolffd@0
|
89 RH(n+1)=RH(r);
|
wolffd@0
|
90 RH(r)=0;
|
wolffd@0
|
91 end
|
wolffd@0
|
92 end
|
wolffd@0
|
93
|
wolffd@0
|
94 % While the column l is labelled, i.e. in path.
|
wolffd@0
|
95 while (LC(l)~=0)
|
wolffd@0
|
96 % If row r is explored..
|
wolffd@0
|
97 if (RH(r)==0)
|
wolffd@0
|
98 % If all rows are explored..
|
wolffd@0
|
99 if (RH(n+1)<=0)
|
wolffd@0
|
100 % Reduce cost matrix.
|
wolffd@0
|
101 [A,CH,RH]=hmreduce(A,CH,RH,LC,LR,SLC,SLR);
|
wolffd@0
|
102 end
|
wolffd@0
|
103
|
wolffd@0
|
104 % Re-start with first unexplored row.
|
wolffd@0
|
105 r=RH(n+1);
|
wolffd@0
|
106 end
|
wolffd@0
|
107
|
wolffd@0
|
108 % Get column of next free zero in row r.
|
wolffd@0
|
109 l=CH(r);
|
wolffd@0
|
110
|
wolffd@0
|
111 % Advance "column of next free zero".
|
wolffd@0
|
112 CH(r)=-A(r,l);
|
wolffd@0
|
113
|
wolffd@0
|
114 % If this zero is last in list..
|
wolffd@0
|
115 if(A(r,l)==0)
|
wolffd@0
|
116 % ...remove row r from unexplored list.
|
wolffd@0
|
117 RH(n+1)=RH(r);
|
wolffd@0
|
118 RH(r)=0;
|
wolffd@0
|
119 end
|
wolffd@0
|
120 end
|
wolffd@0
|
121
|
wolffd@0
|
122 % If the column found is unassigned..
|
wolffd@0
|
123 if (C(l)==0)
|
wolffd@0
|
124 % Flip all zeros along the path in LR,LC.
|
wolffd@0
|
125 [A,C,U]=hmflip(A,C,LC,LR,U,l,r);
|
wolffd@0
|
126 % ...and exit to continue with next unassigned row.
|
wolffd@0
|
127 break;
|
wolffd@0
|
128 else
|
wolffd@0
|
129 % ...else add zero to path.
|
wolffd@0
|
130
|
wolffd@0
|
131 % Label column l with row r.
|
wolffd@0
|
132 LC(l)=r;
|
wolffd@0
|
133
|
wolffd@0
|
134 % Add l to the set of labelled columns.
|
wolffd@0
|
135 SLC=[SLC l];
|
wolffd@0
|
136
|
wolffd@0
|
137 % Continue with the row assigned to column l.
|
wolffd@0
|
138 r=C(l);
|
wolffd@0
|
139
|
wolffd@0
|
140 % Label row r with column l.
|
wolffd@0
|
141 LR(r)=l;
|
wolffd@0
|
142
|
wolffd@0
|
143 % Add r to the set of labelled rows.
|
wolffd@0
|
144 SLR=[SLR r];
|
wolffd@0
|
145 end
|
wolffd@0
|
146 end
|
wolffd@0
|
147 end
|
wolffd@0
|
148
|
wolffd@0
|
149 % Calculate the total cost.
|
wolffd@0
|
150 T=sum(orig(logical(sparse(C,1:size(orig,2),1))));
|
wolffd@0
|
151
|
wolffd@0
|
152
|
wolffd@0
|
153 function A=hminired(A)
|
wolffd@0
|
154 %HMINIRED Initial reduction of cost matrix for the Hungarian method.
|
wolffd@0
|
155 %
|
wolffd@0
|
156 %B=assredin(A)
|
wolffd@0
|
157 %A - the unreduced cost matris.
|
wolffd@0
|
158 %B - the reduced cost matrix with linked zeros in each row.
|
wolffd@0
|
159
|
wolffd@0
|
160 % v1.0 96-06-13. Niclas Borlin, niclas@cs.umu.se.
|
wolffd@0
|
161
|
wolffd@0
|
162 [m,n]=size(A);
|
wolffd@0
|
163
|
wolffd@0
|
164 % Subtract column-minimum values from each column.
|
wolffd@0
|
165 colMin=min(A);
|
wolffd@0
|
166 A=A-colMin(ones(n,1),:);
|
wolffd@0
|
167
|
wolffd@0
|
168 % Subtract row-minimum values from each row.
|
wolffd@0
|
169 rowMin=min(A')';
|
wolffd@0
|
170 A=A-rowMin(:,ones(1,n));
|
wolffd@0
|
171
|
wolffd@0
|
172 % Get positions of all zeros.
|
wolffd@0
|
173 [i,j]=find(A==0);
|
wolffd@0
|
174
|
wolffd@0
|
175 % Extend A to give room for row zero list header column.
|
wolffd@0
|
176 A(1,n+1)=0;
|
wolffd@0
|
177 for k=1:n
|
wolffd@0
|
178 % Get all column in this row.
|
wolffd@0
|
179 cols=j(k==i)';
|
wolffd@0
|
180 % Insert pointers in matrix.
|
wolffd@0
|
181 A(k,[n+1 cols])=[-cols 0];
|
wolffd@0
|
182 end
|
wolffd@0
|
183
|
wolffd@0
|
184
|
wolffd@0
|
185 function [A,C,U]=hminiass(A)
|
wolffd@0
|
186 %HMINIASS Initial assignment of the Hungarian method.
|
wolffd@0
|
187 %
|
wolffd@0
|
188 %[B,C,U]=hminiass(A)
|
wolffd@0
|
189 %A - the reduced cost matrix.
|
wolffd@0
|
190 %B - the reduced cost matrix, with assigned zeros removed from lists.
|
wolffd@0
|
191 %C - a vector. C(J)=I means row I is assigned to column J,
|
wolffd@0
|
192 % i.e. there is an assigned zero in position I,J.
|
wolffd@0
|
193 %U - a vector with a linked list of unassigned rows.
|
wolffd@0
|
194
|
wolffd@0
|
195 % v1.0 96-06-14. Niclas Borlin, niclas@cs.umu.se.
|
wolffd@0
|
196
|
wolffd@0
|
197 [n,np1]=size(A);
|
wolffd@0
|
198
|
wolffd@0
|
199 % Initalize return vectors.
|
wolffd@0
|
200 C=zeros(1,n);
|
wolffd@0
|
201 U=zeros(1,n+1);
|
wolffd@0
|
202
|
wolffd@0
|
203 % Initialize last/next zero "pointers".
|
wolffd@0
|
204 LZ=zeros(1,n);
|
wolffd@0
|
205 NZ=zeros(1,n);
|
wolffd@0
|
206
|
wolffd@0
|
207 for i=1:n
|
wolffd@0
|
208 % Set j to first unassigned zero in row i.
|
wolffd@0
|
209 lj=n+1;
|
wolffd@0
|
210 j=-A(i,lj);
|
wolffd@0
|
211
|
wolffd@0
|
212 % Repeat until we have no more zeros (j==0) or we find a zero
|
wolffd@0
|
213 % in an unassigned column (c(j)==0).
|
wolffd@0
|
214
|
wolffd@0
|
215 while (C(j)~=0)
|
wolffd@0
|
216 % Advance lj and j in zero list.
|
wolffd@0
|
217 lj=j;
|
wolffd@0
|
218 j=-A(i,lj);
|
wolffd@0
|
219
|
wolffd@0
|
220 % Stop if we hit end of list.
|
wolffd@0
|
221 if (j==0)
|
wolffd@0
|
222 break;
|
wolffd@0
|
223 end
|
wolffd@0
|
224 end
|
wolffd@0
|
225
|
wolffd@0
|
226 if (j~=0)
|
wolffd@0
|
227 % We found a zero in an unassigned column.
|
wolffd@0
|
228
|
wolffd@0
|
229 % Assign row i to column j.
|
wolffd@0
|
230 C(j)=i;
|
wolffd@0
|
231
|
wolffd@0
|
232 % Remove A(i,j) from unassigned zero list.
|
wolffd@0
|
233 A(i,lj)=A(i,j);
|
wolffd@0
|
234
|
wolffd@0
|
235 % Update next/last unassigned zero pointers.
|
wolffd@0
|
236 NZ(i)=-A(i,j);
|
wolffd@0
|
237 LZ(i)=lj;
|
wolffd@0
|
238
|
wolffd@0
|
239 % Indicate A(i,j) is an assigned zero.
|
wolffd@0
|
240 A(i,j)=0;
|
wolffd@0
|
241 else
|
wolffd@0
|
242 % We found no zero in an unassigned column.
|
wolffd@0
|
243
|
wolffd@0
|
244 % Check all zeros in this row.
|
wolffd@0
|
245
|
wolffd@0
|
246 lj=n+1;
|
wolffd@0
|
247 j=-A(i,lj);
|
wolffd@0
|
248
|
wolffd@0
|
249 % Check all zeros in this row for a suitable zero in another row.
|
wolffd@0
|
250 while (j~=0)
|
wolffd@0
|
251 % Check the in the row assigned to this column.
|
wolffd@0
|
252 r=C(j);
|
wolffd@0
|
253
|
wolffd@0
|
254 % Pick up last/next pointers.
|
wolffd@0
|
255 lm=LZ(r);
|
wolffd@0
|
256 m=NZ(r);
|
wolffd@0
|
257
|
wolffd@0
|
258 % Check all unchecked zeros in free list of this row.
|
wolffd@0
|
259 while (m~=0)
|
wolffd@0
|
260 % Stop if we find an unassigned column.
|
wolffd@0
|
261 if (C(m)==0)
|
wolffd@0
|
262 break;
|
wolffd@0
|
263 end
|
wolffd@0
|
264
|
wolffd@0
|
265 % Advance one step in list.
|
wolffd@0
|
266 lm=m;
|
wolffd@0
|
267 m=-A(r,lm);
|
wolffd@0
|
268 end
|
wolffd@0
|
269
|
wolffd@0
|
270 if (m==0)
|
wolffd@0
|
271 % We failed on row r. Continue with next zero on row i.
|
wolffd@0
|
272 lj=j;
|
wolffd@0
|
273 j=-A(i,lj);
|
wolffd@0
|
274 else
|
wolffd@0
|
275 % We found a zero in an unassigned column.
|
wolffd@0
|
276
|
wolffd@0
|
277 % Replace zero at (r,m) in unassigned list with zero at (r,j)
|
wolffd@0
|
278 A(r,lm)=-j;
|
wolffd@0
|
279 A(r,j)=A(r,m);
|
wolffd@0
|
280
|
wolffd@0
|
281 % Update last/next pointers in row r.
|
wolffd@0
|
282 NZ(r)=-A(r,m);
|
wolffd@0
|
283 LZ(r)=j;
|
wolffd@0
|
284
|
wolffd@0
|
285 % Mark A(r,m) as an assigned zero in the matrix . . .
|
wolffd@0
|
286 A(r,m)=0;
|
wolffd@0
|
287
|
wolffd@0
|
288 % ...and in the assignment vector.
|
wolffd@0
|
289 C(m)=r;
|
wolffd@0
|
290
|
wolffd@0
|
291 % Remove A(i,j) from unassigned list.
|
wolffd@0
|
292 A(i,lj)=A(i,j);
|
wolffd@0
|
293
|
wolffd@0
|
294 % Update last/next pointers in row r.
|
wolffd@0
|
295 NZ(i)=-A(i,j);
|
wolffd@0
|
296 LZ(i)=lj;
|
wolffd@0
|
297
|
wolffd@0
|
298 % Mark A(r,m) as an assigned zero in the matrix . . .
|
wolffd@0
|
299 A(i,j)=0;
|
wolffd@0
|
300
|
wolffd@0
|
301 % ...and in the assignment vector.
|
wolffd@0
|
302 C(j)=i;
|
wolffd@0
|
303
|
wolffd@0
|
304 % Stop search.
|
wolffd@0
|
305 break;
|
wolffd@0
|
306 end
|
wolffd@0
|
307 end
|
wolffd@0
|
308 end
|
wolffd@0
|
309 end
|
wolffd@0
|
310
|
wolffd@0
|
311 % Create vector with list of unassigned rows.
|
wolffd@0
|
312
|
wolffd@0
|
313 % Mark all rows have assignment.
|
wolffd@0
|
314 r=zeros(1,n);
|
wolffd@0
|
315 rows=C(C~=0);
|
wolffd@0
|
316 r(rows)=rows;
|
wolffd@0
|
317 empty=find(r==0);
|
wolffd@0
|
318
|
wolffd@0
|
319 % Create vector with linked list of unassigned rows.
|
wolffd@0
|
320 U=zeros(1,n+1);
|
wolffd@0
|
321 U([n+1 empty])=[empty 0];
|
wolffd@0
|
322
|
wolffd@0
|
323
|
wolffd@0
|
324 function [A,C,U]=hmflip(A,C,LC,LR,U,l,r)
|
wolffd@0
|
325 %HMFLIP Flip assignment state of all zeros along a path.
|
wolffd@0
|
326 %
|
wolffd@0
|
327 %[A,C,U]=hmflip(A,C,LC,LR,U,l,r)
|
wolffd@0
|
328 %Input:
|
wolffd@0
|
329 %A - the cost matrix.
|
wolffd@0
|
330 %C - the assignment vector.
|
wolffd@0
|
331 %LC - the column label vector.
|
wolffd@0
|
332 %LR - the row label vector.
|
wolffd@0
|
333 %U - the
|
wolffd@0
|
334 %r,l - position of last zero in path.
|
wolffd@0
|
335 %Output:
|
wolffd@0
|
336 %A - updated cost matrix.
|
wolffd@0
|
337 %C - updated assignment vector.
|
wolffd@0
|
338 %U - updated unassigned row list vector.
|
wolffd@0
|
339
|
wolffd@0
|
340 % v1.0 96-06-14. Niclas Borlin, niclas@cs.umu.se.
|
wolffd@0
|
341
|
wolffd@0
|
342 n=size(A,1);
|
wolffd@0
|
343
|
wolffd@0
|
344 while (1)
|
wolffd@0
|
345 % Move assignment in column l to row r.
|
wolffd@0
|
346 C(l)=r;
|
wolffd@0
|
347
|
wolffd@0
|
348 % Find zero to be removed from zero list..
|
wolffd@0
|
349
|
wolffd@0
|
350 % Find zero before this.
|
wolffd@0
|
351 m=find(A(r,:)==-l);
|
wolffd@0
|
352
|
wolffd@0
|
353 % Link past this zero.
|
wolffd@0
|
354 A(r,m)=A(r,l);
|
wolffd@0
|
355
|
wolffd@0
|
356 A(r,l)=0;
|
wolffd@0
|
357
|
wolffd@0
|
358 % If this was the first zero of the path..
|
wolffd@0
|
359 if (LR(r)<0)
|
wolffd@0
|
360 ...remove row from unassigned row list and return.
|
wolffd@0
|
361 U(n+1)=U(r);
|
wolffd@0
|
362 U(r)=0;
|
wolffd@0
|
363 return;
|
wolffd@0
|
364 else
|
wolffd@0
|
365
|
wolffd@0
|
366 % Move back in this row along the path and get column of next zero.
|
wolffd@0
|
367 l=LR(r);
|
wolffd@0
|
368
|
wolffd@0
|
369 % Insert zero at (r,l) first in zero list.
|
wolffd@0
|
370 A(r,l)=A(r,n+1);
|
wolffd@0
|
371 A(r,n+1)=-l;
|
wolffd@0
|
372
|
wolffd@0
|
373 % Continue back along the column to get row of next zero in path.
|
wolffd@0
|
374 r=LC(l);
|
wolffd@0
|
375 end
|
wolffd@0
|
376 end
|
wolffd@0
|
377
|
wolffd@0
|
378
|
wolffd@0
|
379 function [A,CH,RH]=hmreduce(A,CH,RH,LC,LR,SLC,SLR)
|
wolffd@0
|
380 %HMREDUCE Reduce parts of cost matrix in the Hungerian method.
|
wolffd@0
|
381 %
|
wolffd@0
|
382 %[A,CH,RH]=hmreduce(A,CH,RH,LC,LR,SLC,SLR)
|
wolffd@0
|
383 %Input:
|
wolffd@0
|
384 %A - Cost matrix.
|
wolffd@0
|
385 %CH - vector of column of 'next zeros' in each row.
|
wolffd@0
|
386 %RH - vector with list of unexplored rows.
|
wolffd@0
|
387 %LC - column labels.
|
wolffd@0
|
388 %RC - row labels.
|
wolffd@0
|
389 %SLC - set of column labels.
|
wolffd@0
|
390 %SLR - set of row labels.
|
wolffd@0
|
391 %
|
wolffd@0
|
392 %Output:
|
wolffd@0
|
393 %A - Reduced cost matrix.
|
wolffd@0
|
394 %CH - Updated vector of 'next zeros' in each row.
|
wolffd@0
|
395 %RH - Updated vector of unexplored rows.
|
wolffd@0
|
396
|
wolffd@0
|
397 % v1.0 96-06-14. Niclas Borlin, niclas@cs.umu.se.
|
wolffd@0
|
398
|
wolffd@0
|
399 n=size(A,1);
|
wolffd@0
|
400
|
wolffd@0
|
401 % Find which rows are covered, i.e. unlabelled.
|
wolffd@0
|
402 coveredRows=LR==0;
|
wolffd@0
|
403
|
wolffd@0
|
404 % Find which columns are covered, i.e. labelled.
|
wolffd@0
|
405 coveredCols=LC~=0;
|
wolffd@0
|
406
|
wolffd@0
|
407 r=find(~coveredRows);
|
wolffd@0
|
408 c=find(~coveredCols);
|
wolffd@0
|
409
|
wolffd@0
|
410 % Get minimum of uncovered elements.
|
wolffd@0
|
411 m=min(min(A(r,c)));
|
wolffd@0
|
412
|
wolffd@0
|
413 % Subtract minimum from all uncovered elements.
|
wolffd@0
|
414 A(r,c)=A(r,c)-m;
|
wolffd@0
|
415
|
wolffd@0
|
416 % Check all uncovered columns..
|
wolffd@0
|
417 for j=c
|
wolffd@0
|
418 % ...and uncovered rows in path order..
|
wolffd@0
|
419 for i=SLR
|
wolffd@0
|
420 % If this is a (new) zero..
|
wolffd@0
|
421 if (A(i,j)==0)
|
wolffd@0
|
422 % If the row is not in unexplored list..
|
wolffd@0
|
423 if (RH(i)==0)
|
wolffd@0
|
424 % ...insert it first in unexplored list.
|
wolffd@0
|
425 RH(i)=RH(n+1);
|
wolffd@0
|
426 RH(n+1)=i;
|
wolffd@0
|
427 % Mark this zero as "next free" in this row.
|
wolffd@0
|
428 CH(i)=j;
|
wolffd@0
|
429 end
|
wolffd@0
|
430 % Find last unassigned zero on row I.
|
wolffd@0
|
431 row=A(i,:);
|
wolffd@0
|
432 colsInList=-row(row<0);
|
wolffd@0
|
433 if (length(colsInList)==0)
|
wolffd@0
|
434 % No zeros in the list.
|
wolffd@0
|
435 l=n+1;
|
wolffd@0
|
436 else
|
wolffd@0
|
437 l=colsInList(row(colsInList)==0);
|
wolffd@0
|
438 end
|
wolffd@0
|
439 % Append this zero to end of list.
|
wolffd@0
|
440 A(i,l)=-j;
|
wolffd@0
|
441 end
|
wolffd@0
|
442 end
|
wolffd@0
|
443 end
|
wolffd@0
|
444
|
wolffd@0
|
445 % Add minimum to all doubly covered elements.
|
wolffd@0
|
446 r=find(coveredRows);
|
wolffd@0
|
447 c=find(coveredCols);
|
wolffd@0
|
448
|
wolffd@0
|
449 % Take care of the zeros we will remove.
|
wolffd@0
|
450 [i,j]=find(A(r,c)<=0);
|
wolffd@0
|
451
|
wolffd@0
|
452 i=r(i);
|
wolffd@0
|
453 j=c(j);
|
wolffd@0
|
454
|
wolffd@0
|
455 for k=1:length(i)
|
wolffd@0
|
456 % Find zero before this in this row.
|
wolffd@0
|
457 lj=find(A(i(k),:)==-j(k));
|
wolffd@0
|
458 % Link past it.
|
wolffd@0
|
459 A(i(k),lj)=A(i(k),j(k));
|
wolffd@0
|
460 % Mark it as assigned.
|
wolffd@0
|
461 A(i(k),j(k))=0;
|
wolffd@0
|
462 end
|
wolffd@0
|
463
|
wolffd@0
|
464 A(r,c)=A(r,c)+m;
|