wolffd@0: % MATCH - Solves the weighted bipartite matching (or assignment) wolffd@0: % problem. wolffd@0: % wolffd@0: % Usage: a = match(C); wolffd@0: % wolffd@0: % Arguments: wolffd@0: % C - an m x n cost matrix; the sets are taken to be wolffd@0: % 1:m and 1:n; C(i, j) gives the cost of matching wolffd@0: % items i (of the first set) and j (of the second set) wolffd@0: % wolffd@0: % Returns: wolffd@0: % wolffd@0: % a - an m x 1 assignment vector, which gives the wolffd@0: % minimum cost assignment. a(i) is the index of wolffd@0: % the item of 1:n that was matched to item i of wolffd@0: % 1:m. If item i (of 1:m) was not matched to any wolffd@0: % item of 1:n, then a(i) is zero. wolffd@0: wolffd@0: % Copyright (C) 2002 Mark A. Paskin wolffd@0: % wolffd@0: % This program is free software; you can redistribute it and/or modify wolffd@0: % it under the terms of the GNU General Public License as published by wolffd@0: % the Free Software Foundation; either version 2 of the License, or wolffd@0: % (at your option) any later version. wolffd@0: % wolffd@0: % This program is distributed in the hope that it will be useful, but wolffd@0: % WITHOUT ANY WARRANTY; without even the implied warranty of wolffd@0: % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU wolffd@0: % General Public License for more details. wolffd@0: % wolffd@0: % You should have received a copy of the GNU General Public License wolffd@0: % along with this program; if not, write to the Free Software wolffd@0: % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 wolffd@0: % USA. wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: function [a] = optimalMatching(C) wolffd@0: wolffd@0: % Trivial cases: wolffd@0: [p, q] = size(C); wolffd@0: if (p == 0) wolffd@0: a = []; wolffd@0: return; wolffd@0: elseif (q == 0) wolffd@0: a = zeros(p, 1); wolffd@0: return; wolffd@0: end wolffd@0: wolffd@0: wolffd@0: if 0 wolffd@0: % First, reduce the problem by making easy optimal matches. If two wolffd@0: % elements agree that they are the best match, then match them up. wolffd@0: [x, a] = min(C, [], 2); wolffd@0: [y, b] = min(C, [], 1); wolffd@0: u = find(1:p ~= b(a(:))); wolffd@0: a(u) = 0; wolffd@0: v = find(1:q ~= a(b(:))'); wolffd@0: C = C(u, v); wolffd@0: if (isempty(C)) return; end wolffd@0: end wolffd@0: wolffd@0: % Get the (new) size of the two sets, u and v. wolffd@0: [m, n] = size(C); wolffd@0: wolffd@0: %mx = realmax; wolffd@0: mx = 2*max(C(:)); wolffd@0: mn = -2*min(C(:)); wolffd@0: % Pad the affinity matrix to be square wolffd@0: if (m < n) wolffd@0: C = [C; mx * ones(n - m, n)]; wolffd@0: elseif (n < m) wolffd@0: C = [C, mx * ones(m, m - n)]; wolffd@0: end wolffd@0: wolffd@0: % Run the Hungarian method. First replace infinite values by the wolffd@0: % largest (or smallest) finite values. wolffd@0: C(find(isinf(C) & (C > 0))) = mx; wolffd@0: C(find(isinf(C) & (C < 0))) = mn; wolffd@0: %fprintf('running hungarian\n'); wolffd@0: [b, cost] = hungarian(C'); wolffd@0: wolffd@0: % Extract only the real assignments wolffd@0: ap = b(1:m)'; wolffd@0: ap(find(ap > n)) = 0; wolffd@0: wolffd@0: a = ap; wolffd@0: %% Incorporate this sub-assignment into the complete assignment wolffd@0: % k = find(ap); wolffd@0: % a(u(k)) = v(ap(k)); wolffd@0: