2 * Based on: Jonker, R., & Volgenant, A. (1987). <i>A shortest augmenting path
3 * algorithm for dense and sparse linear assignment problems</i>. Computing,
7 #include "linear-assignment.h"
9 #define COST(column, row) cost[(column) + column_count * (row)]
12 * The parameter `cost` is the cost matrix: the cost to assign column j to row
13 * i is `cost[j + column_count * i].
15 void compute_assignment(int column_count
, int row_count
, int *cost
,
16 int *column2row
, int *row2column
)
19 int *free_row
, free_count
= 0, saved_free_count
, *pred
, *col
;
22 if (column_count
< 2) {
23 memset(column2row
, 0, sizeof(int) * column_count
);
24 memset(row2column
, 0, sizeof(int) * row_count
);
28 memset(column2row
, -1, sizeof(int) * column_count
);
29 memset(row2column
, -1, sizeof(int) * row_count
);
30 ALLOC_ARRAY(v
, column_count
);
32 /* column reduction */
33 for (j
= column_count
- 1; j
>= 0; j
--) {
36 for (i
= 1; i
< row_count
; i
++)
37 if (COST(j
, i1
) > COST(j
, i
))
40 if (row2column
[i1
] == -1) {
41 /* row i1 unassigned */
45 if (row2column
[i1
] >= 0)
46 row2column
[i1
] = -2 - row2column
[i1
];
51 /* reduction transfer */
52 ALLOC_ARRAY(free_row
, row_count
);
53 for (i
= 0; i
< row_count
; i
++) {
54 int j1
= row2column
[i
];
56 free_row
[free_count
++] = i
;
58 row2column
[i
] = -2 - j1
;
60 int min
= COST(!j1
, i
) - v
[!j1
];
61 for (j
= 1; j
< column_count
; j
++)
62 if (j
!= j1
&& min
> COST(j
, i
) - v
[j
])
63 min
= COST(j
, i
) - v
[j
];
69 (column_count
< row_count
? row_count
- column_count
: 0)) {
75 /* augmenting row reduction */
76 for (phase
= 0; phase
< 2; phase
++) {
79 saved_free_count
= free_count
;
81 while (k
< saved_free_count
) {
86 u1
= COST(j1
, i
) - v
[j1
];
89 for (j
= 1; j
< column_count
; j
++) {
90 int c
= COST(j
, i
) - v
[j
];
120 free_row
[free_count
++] = i0
;
128 saved_free_count
= free_count
;
129 ALLOC_ARRAY(d
, column_count
);
130 ALLOC_ARRAY(pred
, column_count
);
131 ALLOC_ARRAY(col
, column_count
);
132 for (free_count
= 0; free_count
< saved_free_count
; free_count
++) {
133 int i1
= free_row
[free_count
], low
= 0, up
= 0, last
, k
;
136 for (j
= 0; j
< column_count
; j
++) {
137 d
[j
] = COST(j
, i1
) - v
[j
];
146 for (k
= up
; k
< column_count
; k
++) {
158 for (k
= low
; k
< up
; k
++)
159 if (column2row
[col
[k
]] == -1)
167 u1
= COST(j1
, i
) - v
[j1
] - min
;
168 for (k
= up
; k
< column_count
; k
++) {
170 c
= COST(j
, i
) - v
[j
] - u1
;
175 if (column2row
[j
] == -1)
186 /* updating of the column pieces */
187 for (k
= 0; k
< last
; k
++) {
189 v
[j1
] += d
[j1
] - min
;
195 BUG("negative j: %d", j
);
198 SWAP(j
, row2column
[i
]);