float floatMax = AssignmentHelper.getFloatMax(Math.max(costMatrix.length, costMatrix[0].length));
matching[0].setFloatMax(floatMax);
matching[1].setFloatMax(floatMax);
WeightedGraph graph = new WeightedGraph(NO_X + NO_Y);
int ALL_NODES = NO_X + NO_Y;
for (int x = 0; x < NO_X; x++) {
int tmpY = 0;
for (int y = NO_X; y < ALL_NODES; y++, tmpY++) {
if (costMatrix[tmpY][x] < floatMax) {
graph.addEdge(x, y, costMatrix[tmpY][x]);
} else {
// we would not need this line, if we would have a better graph.getOneNodeWithAnEdge()
// see within the while(true) loop
graph.addEdge(x, y, floatMax);
}
}
}
// x is somewhat missleading, because the x and y nodes swap
// in every iteration (in the while(true) loop)
int x = graph.getOneNodeWithAnEdge();
int saveFirstNode = x;
Map<Integer, Float> saveNeighbors =
new FastMap<Integer, Float>(graph.getNeighbors(x));
int yForExtremalWeight = -1;
while (graph.getNoOfEdges() > 0) {
while (true) {
if (graph.getNeighbors(x).size() == 0) {
// EITHER return only x node if they are required (or y) via:
//x = graph.getOneNodeWithAnEdge();
//if (x < 0) { break; }
// OR assume a complete graph and simply break (no while(graph.getNoOfEdges() > 0) would be required)
break;
}
float minWeight = floatMax + 1;
yForExtremalWeight = -1;
for (Entry<Integer, Float> entry : graph.getNeighbors(x).entrySet()) {
if (entry.getValue() < minWeight) {
yForExtremalWeight = entry.getKey();
minWeight = entry.getValue();
}
}
assert yForExtremalWeight != -1;
// even add it if float is floatMax, because otherwise we will
// will have a wrong totalSum
matching[i].addEdge(x, yForExtremalWeight, minWeight);
i = 1 - i;
boolean ret = graph.removeNodeAndNeighbors(x);
assert ret;
x = yForExtremalWeight;
}
}