From: Mart Lubbers Date: Thu, 19 Jun 2014 08:51:13 +0000 (+0200) Subject: other implementation X-Git-Url: https://git.martlubbers.net/?a=commitdiff_plain;h=8e3b1b7c1e3ea5ce334cf6978496a3b6f7b7a434;p=co1314.git other implementation --- diff --git a/LubbersSolver.java b/LubbersSolver.java index 571bb26..a1b88a0 100755 --- a/LubbersSolver.java +++ b/LubbersSolver.java @@ -5,6 +5,9 @@ import java.util.Random; import java.util.Arrays; import java.util.List; import java.util.Comparator; +import java.util.AbstractMap.SimpleEntry; +import java.util.Comparator; +import java.util.PriorityQueue; /** @@ -14,78 +17,146 @@ import java.util.Comparator; */ public class LubbersSolver implements IPetproblemSolver { - private class Tuple { - public int[] list; - public int score; + public class Tuple implements Comparable + { + public int k; + public int v; - public Tuple(int[] l, int s) { - list = l; - score = s; + public Tuple(int k, int v) + { + this.k = k; + this.v = v; } + /** + * Overrides compareTo so that the priorityqueue is ordered ascending + * + * @param a the entry to compare with + * @return comparison value + */ @Override - public String toString() { - return score + ": " + Arrays.toString(list); + public int compareTo(Tuple a) + { + //note that the values are swapped, so that the sort will be reversed + return Integer.compare(a.v, this.v); } - } - public int factorial(int n) { - return n==1 ? 1 : n*factorial(n-1); - } - - public void permute(int[] num, int start, List result) { - if(start == num.length) { - result.add(num.clone()); - } - for(int i = start; i=m ? -1 : i; + public int[] solve(int n, int m, int[][] compatibility) + { + int[] result = new int[n]; + + // Set to -1 initially + for (int i = 0; i < result.length; i++) + result[i] = -1; + + // Sum rows and columns + PriorityQueue row_sums = new PriorityQueue(n); + PriorityQueue col_sums = new PriorityQueue(m); + + int[] running_row_sums = new int[n]; + int[] running_col_sums = new int[m]; + + // Sum + for (int j = 0; j < m; j++) + { + for (int i = 0; i < n; i++) + { + running_row_sums[i] += compatibility[i][j]; + running_col_sums[j] += compatibility[i][j]; + } } - List ps = new LinkedList(); - permute(possibilities, 0, ps); + // Add running sums to queues + for (int i = 0; i < running_row_sums.length; i++) + row_sums.add(new Tuple(i, running_row_sums[i])); + + for (int i = 0; i < running_col_sums.length; i++) + col_sums.add(new Tuple(i, running_col_sums[i])); + - return Collections.max(ps, new Comparator(){ - @Override - public int compare(int[] a, int[] b){ - return computeCompatibility(compatibility, a) - computeCompatibility(compatibility, b); + // Select smallest sum (in rows/cols) + // Get 1-indices for that sum's index + // Select smallest from those indices + while (!row_sums.isEmpty() && !col_sums.isEmpty()){ + Tuple lowestIndexRow = row_sums.peek(); + Tuple lowestIndexCol = col_sums.peek(); + + boolean useRow = false; + + if (lowestIndexRow.v < lowestIndexCol.v) + useRow = true; + + // Get 1-indices + if (useRow) + { + row_sums.remove(); + + // Get smallest + int smallestValue = Integer.MAX_VALUE; + Tuple smallestKey = null; + + for (Tuple e : col_sums) + { + if (e.v < smallestValue && compatibility[lowestIndexRow.k][e.k] == 1) + { + smallestKey = e; + smallestValue = e.v; + } + } + + // No candidates in this list, continue + if (smallestKey == null) + continue; + + int col_index = smallestKey.k; + col_sums.remove(smallestKey); + + result[lowestIndexRow.k] = col_index; + } + else + { + col_sums.remove(); + + // Get smallest + int smallestValue = Integer.MAX_VALUE; + Tuple smallestKey = null; + + for (Tuple e : row_sums) + { + if (e.v < smallestValue && compatibility[e.k][lowestIndexCol.k] == 1) + { + smallestKey = e; + smallestValue = e.v; + } + } + + // No candidates in this list, continue + if (smallestKey == null) + continue; + + int row_index = smallestKey.k; + row_sums.remove(smallestKey); + + result[row_index] = lowestIndexCol.k; } - }); + } + + int score = 0; + + for (int i = 0; i < result.length; i++) + score += result[i] == -1 ? 0 : 1; + + System.out.println("Score: " + score); + + return result; } + }