Advertisement
Guest User

Hungarian.java

a guest
Jan 23rd, 2019
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.63 KB | None | 0 0
  1. import java.util.ArrayList;
  2. import java.util.Arrays;
  3. import java.util.Random;
  4.  
  5. class Hungarian {
  6.  
  7.     public static void main(String[] args) {
  8.  
  9.         long start = System.currentTimeMillis();
  10.  
  11.         int n = 4096;
  12.  
  13.         double[][] theCosts = new double[n][n];
  14.  
  15.         Random random = new Random(2019);
  16.  
  17.         for (int i = 0; i < n; i++) {
  18.             theCosts[i][i] = random.nextDouble();
  19.         }
  20.  
  21.         Hungarian hungarian = new Hungarian(theCosts);
  22.  
  23.         System.out.println(Arrays.deepHashCode(hungarian.execute()));
  24.  
  25.         long finish = System.currentTimeMillis();
  26.         System.out.println(finish - start);
  27.  
  28.     }
  29.  
  30.     int numRows;
  31.     int numCols;
  32.  
  33.     boolean[][] primes;
  34.     boolean[][] stars;
  35.     boolean[] rowsCovered;
  36.     boolean[] colsCovered;
  37.     double[][] costs;
  38.  
  39.     Hungarian(double[][] theCosts) {
  40.         costs = theCosts;
  41.         numRows = costs.length;
  42.         numCols = costs[0].length;
  43.  
  44.         primes = new boolean[numRows][numCols];
  45.         stars = new boolean[numRows][numCols];
  46.  
  47.         rowsCovered = new boolean[numRows];
  48.         colsCovered = new boolean[numCols];
  49.  
  50.     }
  51.  
  52.     int[][] execute() {
  53.         for (int i = 0; i < numRows; i++) {
  54.             double rowMin = Double.MAX_VALUE;
  55.             for (int j = 0; j < numCols; j++) {
  56.                 if (costs[i][j] < rowMin) {
  57.                     rowMin = costs[i][j];
  58.                 }
  59.             }
  60.             for (int j = 0; j < numCols; j++) {
  61.                 costs[i][j] = costs[i][j] - rowMin;
  62.             }
  63.         }
  64.  
  65.         for (int j = 0; j < numCols; j++) {
  66.             double colMin = Double.MAX_VALUE;
  67.             for (int i = 0; i < numRows; i++) {
  68.                 if (costs[i][j] < colMin) {
  69.                     colMin = costs[i][j];
  70.                 }
  71.             }
  72.             for (int i = 0; i < numRows; i++) {
  73.                 costs[i][j] = costs[i][j] - colMin;
  74.             }
  75.         }
  76.  
  77.         boolean[] rowStars = new boolean[numRows];
  78.         boolean[] colStars = new boolean[numCols];
  79.  
  80.         for (int i = 0; i < numRows; i++) {
  81.             rowStars[i] = false;
  82.         }
  83.         for (int j = 0; j < numCols; j++) {
  84.             colStars[j] = false;
  85.         }
  86.  
  87.         for (int j = 0; j < numCols; j++) {
  88.             for (int i = 0; i < numRows; i++) {
  89.                 if (costs[i][j] == 0 && !rowStars[i] && !colStars[j]) {
  90.                     stars[i][j] = true;
  91.                     rowStars[i] = true;
  92.                     colStars[j] = true;
  93.                     break;
  94.                 }
  95.             }
  96.         }
  97.         resetCovered();
  98.         coverStarredZeroCols(numRows, numCols, stars, colsCovered);
  99.  
  100.         while (!allColsCovered(numCols, colsCovered)) {
  101.             int[] primedLocation = primeUncoveredZero();
  102.  
  103.             if (primedLocation[0] == -1) {
  104.                 double minUncovered = Double.MAX_VALUE;
  105.                 for (int i = 0; i < numRows; i++) {
  106.                     if (!rowsCovered[i]) {
  107.                         for (int j = 0; j < numCols; j++) {
  108.                             if (!colsCovered[j]) {
  109.                                 if (costs[i][j] < minUncovered) {
  110.                                     minUncovered = costs[i][j];
  111.                                 }
  112.                             }
  113.                         }
  114.                     }
  115.                 }
  116.  
  117.                 for (int i = 0; i < numRows; i++) {
  118.                     if (rowsCovered[i]) {
  119.                         for (int j = 0; j < numCols; j++) {
  120.                             costs[i][j] = costs[i][j] + minUncovered;
  121.  
  122.                         }
  123.                     }
  124.                 }
  125.  
  126.                 for (int j = 0; j < numCols; j++) {
  127.                     if (!colsCovered[j]) {
  128.                         for (int i = 0; i < numRows; i++) {
  129.                             costs[i][j] = costs[i][j] - minUncovered;
  130.                         }
  131.                     }
  132.                 }
  133.                 primedLocation = primeUncoveredZero();
  134.             }
  135.  
  136.             int primedRow = primedLocation[0];
  137.             int starCol = findStarColInRow(primedRow, numCols, stars);
  138.             if (starCol != -1) {
  139.                 rowsCovered[primedRow] = true;
  140.                 colsCovered[starCol] = false;
  141.             } else {
  142.                 ArrayList<int[]> primeLocations = new ArrayList<int[]>(numRows + numCols);
  143.                 ArrayList<int[]> starLocations = new ArrayList<int[]>(numRows + numCols);
  144.                 primeLocations.add(primedLocation);
  145.  
  146.                 int currentRow = primedLocation[0];
  147.                 int currentCol = primedLocation[1];
  148.                 while (true) {
  149.                     int starRow = findStarRowInCol(currentCol, numRows, stars);
  150.                     if (starRow == -1) {
  151.                         break;
  152.                     }
  153.                     int[] starLocation = new int[] { starRow, currentCol };
  154.                     starLocations.add(starLocation);
  155.                     currentRow = starRow;
  156.  
  157.                     int primeCol = findPrimeColInRow(currentRow, numCols, primes);
  158.                     int[] primeLocation = new int[] { currentRow, primeCol };
  159.                     primeLocations.add(primeLocation);
  160.                     currentCol = primeCol;
  161.                 }
  162.  
  163.                 for (int k = 0; k < starLocations.size(); k++) {
  164.                     int[] starLocation = starLocations.get(k);
  165.                     int row = starLocation[0];
  166.                     int col = starLocation[1];
  167.                     stars[row][col] = false;
  168.                 }
  169.                 for (int k = 0; k < primeLocations.size(); k++) {
  170.                     int[] location1 = primeLocations.get(k);
  171.                     int row = location1[0];
  172.                     int col = location1[1];
  173.                     stars[row][col] = true;
  174.                 }
  175.                 resetCovered();
  176.                 for (int i = 0; i < numRows; i++) {
  177.                     for (int j = 0; j < numCols; j++) {
  178.                         primes[i][j] = false;
  179.                     }
  180.                 }
  181.                 coverStarredZeroCols(numRows, numCols, stars, colsCovered);
  182.             }
  183.         }
  184.  
  185.         return starsToAssignments();
  186.  
  187.     }
  188.  
  189.     int[][] starsToAssignments() {
  190.         int[][] toRet = new int[numCols][];
  191.         for (int j = 0; j < numCols; j++) {
  192.             toRet[j] = new int[] { findStarRowInCol(j, numRows, stars), j }; // O(n)
  193.         }
  194.         return toRet;
  195.     }
  196.  
  197.     void resetCovered() {
  198.         for (int i = 0; i < numRows; i++) {
  199.             rowsCovered[i] = false;
  200.         }
  201.         for (int j = 0; j < numCols; j++) {
  202.             colsCovered[j] = false;
  203.         }
  204.     }
  205.  
  206.     int[] primeUncoveredZero() {
  207.         int[] location = new int[2];
  208.  
  209.         for (int i = 0; i < numRows; i++) {
  210.             if (!rowsCovered[i]) {
  211.                 for (int j = 0; j < numCols; j++) {
  212.                     if (!colsCovered[j]) {
  213.                         if (costs[i][j] == 0) {
  214.                             primes[i][j] = true;
  215.                             location[0] = i;
  216.                             location[1] = j;
  217.                             return location;
  218.                         }
  219.                     }
  220.                 }
  221.             }
  222.         }
  223.  
  224.         location[0] = -1;
  225.         location[1] = -1;
  226.         return location;
  227.     }
  228.  
  229.     int findPrimeColInRow(int theRow, int numCols, boolean[][] primes) {
  230.         for (int j = 0; j < numCols; j++) {
  231.             if (primes[theRow][j]) {
  232.                 return j;
  233.             }
  234.         }
  235.         return -1;
  236.     }
  237.  
  238.     int findStarRowInCol(int theCol, int numRows, boolean[][] stars) {
  239.         for (int i = 0; i < numRows; i++) {
  240.             if (stars[i][theCol]) {
  241.                 return i;
  242.             }
  243.         }
  244.         return -1;
  245.     }
  246.  
  247.     int findStarColInRow(int theRow, int numCols, boolean[][] stars) {
  248.         for (int j = 0; j < numCols; j++) {
  249.             if (stars[theRow][j]) {
  250.                 return j;
  251.             }
  252.         }
  253.         return -1;
  254.     }
  255.  
  256.     boolean allColsCovered(int numCols, boolean[] colsCovered) {
  257.         for (int j = 0; j < numCols; j++) {
  258.             if (!colsCovered[j]) {
  259.                 return false;
  260.             }
  261.         }
  262.         return true;
  263.     }
  264.  
  265.     void coverStarredZeroCols(int numRows, int numCols, boolean[][] stars, boolean[] colsCovered) {
  266.         for (int j = 0; j < numCols; j++) {
  267.             colsCovered[j] = false;
  268.             for (int i = 0; i < numRows; i++) {
  269.                 if (stars[i][j]) {
  270.                     colsCovered[j] = true;
  271.                     break;
  272.                 }
  273.             }
  274.         }
  275.     }
  276.  
  277. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement