********************************************************************
********************************************************************/
-/* $Id$ */
+/**
+ * @file
+ * @brief Solving the Minimum Assignment Problem using the Hungarian Method.
+ * @version $Id$
+ */
+#include "config.h"
#include <stdio.h>
#include <stdlib.h>
int num_rows; /**< number of rows */
int num_cols; /**< number of columns */
int **cost; /**< the cost matrix */
- int width; /**< the width for cost matrix dumper */
int max_cost; /**< the maximal costs in the matrix */
int match_type; /**< PERFECT or NORMAL matching */
bitset_t *missing_left; /**< left side nodes having no edge to the right side */
DEBUG_ONLY(firm_dbg_module_t *dbg);
};
-static INLINE void *get_init_mem(struct obstack *obst, long sz) {
- void *p = obstack_alloc(obst, sz);
- memset(p, 0, sz);
- return p;
-}
-
static void hungarian_dump_f(FILE *f, int **C, int rows, int cols, int width) {
int i, j;
fprintf(f, "\n");
}
-void hungarian_print_costmatrix(hungarian_problem_t *p) {
- hungarian_dump_f(stderr, p->cost, p->num_rows, p->num_cols, p->width);
+void hungarian_print_cost_matrix(hungarian_problem_t *p, int width) {
+ hungarian_dump_f(stderr, p->cost, p->num_rows, p->num_cols, width);
}
/**
* Create the object and allocate memory for the data structures.
*/
-hungarian_problem_t *hungarian_new(int rows, int cols, int width, int match_type) {
+hungarian_problem_t *hungarian_new(int rows, int cols, int match_type) {
int i;
- hungarian_problem_t *p = xmalloc(sizeof(*p));
-
- memset(p, 0, sizeof(p));
+ hungarian_problem_t *p = XMALLOCZ(hungarian_problem_t);
FIRM_DBG_REGISTER(p->dbg, "firm.hungarian");
p->num_rows = rows;
p->num_cols = cols;
- p->width = width;
p->match_type = match_type;
/*
}
/* allocate space for cost matrix */
- p->cost = (int **)get_init_mem(&p->obst, rows * sizeof(p->cost[0]));
+ p->cost = OALLOCNZ(&p->obst, int*, rows);
for (i = 0; i < p->num_rows; i++)
- p->cost[i] = (int *)get_init_mem(&p->obst, cols * sizeof(p->cost[0][0]));
+ p->cost[i] = OALLOCNZ(&p->obst, int, cols);
return p;
}
void hungarian_add(hungarian_problem_t *p, int left, int right, int cost) {
assert(p->num_rows > left && "Invalid row selected.");
assert(p->num_cols > right && "Invalid column selected.");
+ assert(cost >= 0);
p->cost[left][right] = cost;
p->max_cost = MAX(p->max_cost, cost);
/**
* Do the assignment.
*/
-int hungarian_solve(hungarian_problem_t* p, int *assignment) {
+int hungarian_solve(hungarian_problem_t* p, int *assignment, int *final_cost, int cost_threshold) {
int i, j, m, n, k, l, s, t, q, unmatched, cost;
int *col_mate;
int *row_mate;
m = p->num_rows;
n = p->num_cols;
- col_mate = xcalloc(p->num_rows, sizeof(col_mate[0]));
- unchosen_row = xcalloc(p->num_rows, sizeof(unchosen_row[0]));
- row_dec = xcalloc(p->num_rows, sizeof(row_dec[0]));
- slack_row = xcalloc(p->num_rows, sizeof(slack_row[0]));
+ col_mate = XMALLOCNZ(int, p->num_rows);
+ unchosen_row = XMALLOCNZ(int, p->num_rows);
+ row_dec = XMALLOCNZ(int, p->num_rows);
+ slack_row = XMALLOCNZ(int, p->num_rows);
- row_mate = xcalloc(p->num_cols, sizeof(row_mate[0]));
- parent_row = xcalloc(p->num_cols, sizeof(parent_row[0]));
- col_inc = xcalloc(p->num_cols, sizeof(col_inc[0]));
- slack = xcalloc(p->num_cols, sizeof(slack[0]));
+ row_mate = XMALLOCNZ(int, p->num_cols);
+ parent_row = XMALLOCNZ(int, p->num_cols);
+ col_inc = XMALLOCNZ(int, p->num_cols);
+ slack = XMALLOCNZ(int, p->num_cols);
memset(assignment, -1, m * sizeof(assignment[0]));
/* collect the assigned values */
for (i = 0; i < m; ++i) {
- assignment[i] = col_mate[i];
+ if (cost_threshold > 0 && p->cost[i][col_mate[i]] >= cost_threshold)
+ assignment[i] = -1; /* remove matching having cost > threshold */
+ else
+ assignment[i] = col_mate[i];
}
/* In case of normal matching: remove impossible ones */
xfree(unchosen_row);
xfree(col_mate);
- return cost;
+ if (final_cost != NULL)
+ *final_cost = cost;
+
+ return 0;
}