assert NO_X > 0 : "Matrix must have at least one column.";
assert NO_Y > 0 : "Matrix must have at least one row.";
// TODO performance: use a static big number instead of determining it?
floatMax = AssignmentHelper.getFloatMax(Math.max(costMatrix.length, costMatrix[0].length));
graph = new BipartiteWeightedGraph(NO_X, NO_Y);
for (int x = 0; x < NO_X; x++) {
for (int y = 0; y < NO_Y; y++) {
if (costMatrix[y][x] < floatMax) {
// this algo calculates maximal weighted bipartite graph
// we need the minimal one
//Float.MAX_VALUE does not work because for large numbers it is 'x + 1 = x'
graph.setEdge(x, y, floatMax - costMatrix[y][x]);
} else {
graph.setEdge(x, y, 0);
}
}
}
if (NO_Y < NO_X) {
graph.addYNodes(NO_X - NO_Y);
for (int x = 0; x < NO_X; x++) {
for (int y = NO_Y; y < NO_X; y++) {
graph.setEdge(x, y, 0);
}
}
NO_Y = NO_X;
}
xLabeling = new float[NO_X];
yLabeling = new float[NO_Y];
// calulate initial labeling
for (int x = 0; x < NO_X; x++) {
float max = -1;
for (int y : graph.getX(x)) {
float tmp = graph.getEdge(x, y);
if (max < tmp) {
max = tmp;
}
}
assert max > -1;
xLabeling[x] = max;
}
// the edges of eqSubGraph depends on the labeling
eqSubGraph = new BipartiteWeightedGraph(NO_X, NO_Y);
// calculate eqSubGraph from labeling
recalculateEqSubGraph();
// S is a subset of X (columns)
setS = new FastSet<Integer>(NO_X);
// T is a subset of Y (rows)
setT = new FastSet<Integer>(NO_Y);
//TODO use a lighter graph (without weight) for matching
// we can choose any matching M
//TODO PERFORMANCE use a fast heuristic to get a better starting matching
matching = new BipartiteWeightedGraph(NO_X, NO_Y);
setN = new FastSet<Integer>(NO_Y);
// Main loop
while (true) {