/** * This work is non-copyrightable * @author Myriam Abramson * myriam.abramson@nrl.navy.mil */ package adprey; import java.util.*; import java.text.*; import java.io.*; /** * Adapted from the website http://216.249.163.93/bob.pilgrim/445/munkres.html * roles x agents * find best role allocation * the coefficient of the matrix are the role preferences of the agents */ public class Hungarian { double [][] matrix; int [] rCov; int [] cCov; int [][] stars; int rows; int cols; int dim; int solutions; Random rand = new Random(); static int FORBIDDEN_VALUE = 9999; //columns = agents //rows = roles public Hungarian (int rows, int columns) { this.rows = rows; this.cols = columns; dim = Math.max(rows,columns); // solutions = Math.min(rows,columns); solutions = dim; matrix = new double[dim][dim]; stars = new int[dim][dim]; rCov = new int[dim]; cCov = new int[dim]; init(rows, columns); } /** * converts x,y to one dimension */ public int two2one (int x, int y) { return (x * dim) + y; } public int one2col (int n) { return (n % dim); } public int one2row (int n) { return (int) (n / dim); } // step 0 transform the matrix from maximization to minimization public void max2min () { double maxVal=Double.MIN_VALUE; for (int i=0;i maxVal) maxVal = matrix[i][j]; } } for (int i=0;i matrix[i][j]) minVal = matrix[i][j]; } for (int j=0;j matrix[i][j]) minVal = matrix[i][j]; } for (int i=0;i= 0) { int zeroCol = one2col(zero); int zeroRow = one2row(zero); stars[zeroRow][zeroCol] = 2; //prime it int starCol = foundStarInRow(zeroRow); if (starCol >= 0) { rCov[zeroRow] = 1; cCov[starCol] = 0; } else { // printStars(); starZeroInRow(zero); //step 5 return false; } zero = findUncoveredZero(); } // printIt(); // printStars(); return true; } public int findStarInCol(int col) { if (col < 0) { System.err.println ("Invalid column index " + col); } for (int i=0;i=0) { kount++; path[kount][0]=r; path[kount][1]=path[kount-1][1]; } else { done = true; break; } int c = findPrimeInRow(path[kount][0]); kount++; path[kount][0] = path[kount-1][0]; path[kount][1] = c; } convertPath(path, kount); clearCovers(); erasePrimes(); // printIt(); // printStars(); // go to step 3 } public void solve() { // System.out.println ("in solve"); // forcePrint(); // printIt(); max2min(); rowMin(); //step 1 colMin(); starZeros(); //step 2 boolean done = false; while (!done) { int covCols = coveredColumns();//step 3 // if (covCols == dim) { if (covCols >= solutions) { // printStarZeros(); break; } done = coverZeros(); //step 4 (calls step 5) while (done) { double smallest = findSmallestUncoveredVal(); uncoverSmallest(smallest); //step 6 done = coverZeros(); } // System.out.println ("Continue(y/n)?"); // System.out.flush(); // char response = human.readChar(); // if (response == 'n') // break; } } boolean freeRow(int row, int col) { for (int i=0;i matrix[i][j]) minVal = matrix[i][j]; } } return minVal; } /** * step 6 * modify the matrix * if the row is covered, add the smallest value * if the column is not covered, subtract the smallest value */ public void uncoverSmallest(double smallest) { for (int i=0;i