From: Mart Lubbers Date: Wed, 18 Jun 2014 17:50:15 +0000 (+0200) Subject: Initial commit X-Git-Url: https://git.martlubbers.net/?a=commitdiff_plain;h=dacf198f6e0f3fe47e35744b00be5c71199c293e;p=co1314.git Initial commit --- dacf198f6e0f3fe47e35744b00be5c71199c293e diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..915f7c2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +build/* +build.xml +dist/* +make.sh +*.class diff --git a/IPetproblemSolver.java b/IPetproblemSolver.java new file mode 100755 index 0000000..e6748f4 --- /dev/null +++ b/IPetproblemSolver.java @@ -0,0 +1,14 @@ +public interface IPetproblemSolver { + /** + * Solves the Pet Problem. + * @param n The number of children. + * @param m The number of pets. + * @param compatibility Matrix containing for every element c[i][j] the value of f(i, j). (See assignment) + * For the base case contains either values "0" or "1". + * For the bonus case might contain any non-negative number. + * @return An array with n elements, containing the index the pet assigned to each child. + * Thus result[i] = j means "child i gets pet j". + * If a child gets no pet, assign the value "-1". + */ + int[] solve(int n, int m, final int[][] compatibility); +} diff --git a/LubbersSolver.java b/LubbersSolver.java new file mode 100755 index 0000000..dfd968c --- /dev/null +++ b/LubbersSolver.java @@ -0,0 +1,85 @@ +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.Collections; +import java.util.Random; +import java.util.Arrays; +import java.util.List; +import java.util.Comparator; + + +/* Generate a random solution which not is necessarily optimal. */ +public class LubbersSolver implements IPetproblemSolver { + + private class Tuple { + public int[] list; + public int score; + + public Tuple(int[] l, int s) { + list = l; + score = s; + } + + @Override + public String toString() { + return score + ": " + Arrays.toString(list); + } + } + + 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; + } + + if(m ps = new LinkedList(); + permute(possibilities, 0, ps); + return Collections.max(ps, new Comparator(){ + @Override + public int compare(int[] a, int[] b){ + return computeCompatibility(compatibility, a) - computeCompatibility(compatibility, b); + } + }); + } + else{ + System.out.println("not equal..."); + return null; + } + + } +} diff --git a/PetTest.java b/PetTest.java new file mode 100755 index 0000000..cabef3e --- /dev/null +++ b/PetTest.java @@ -0,0 +1,136 @@ +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Random; +import java.util.TreeSet; + +import junit.framework.Assert; + +/** + * Tests conformance of a Solver to constraints. + * May not test whether a solution returns a correct (optimal) answer. + */ +@RunWith(Parameterized.class) +public class PetTest { + IPetproblemSolver ps; + + public PetTest(IPetproblemSolver ps) + { + this.ps = ps; + } + + @Parameters + public static Collection data() { + Object[][] solvers = new Object[][] { + { //new RandomSolver(), + new LubbersSolver() + } + }; + return Arrays.asList(solvers); + } + + /** + * @param n The number of children. + * @param m The number of pets. + * @param result + */ + private static void checkConformance(int n, int m, final int[] result) + { + Assert.assertEquals("There should not suddenly be more or less children.", n, result.length); + + TreeSet pets = new TreeSet(); + for(int i = 0; i < result.length; i++) + { + Assert.assertTrue("Pet should exist, or be a no-pet (-1).", result[i] >= -1 && result[i] < m); + Assert.assertTrue("Pet should not be assigned to multiple children.", result[i] == -1 || pets.add(result[i])); + } + } + + private static int[][] generateTestMatrix(int n, int m, int maxValue) + { + int[][] result = new int[n][m]; + + Random r = new Random(n * (m+1)); + for(int n_i = 0; n_i < n; n_i++) + for(int m_i = 0; m_i < m; m_i++) + result[n_i][m_i] = r.nextInt(maxValue+1); + + return result; + } + + private static int computeCompatibility(int[][] matrix, int[] pairing) + { + int sum = 0; + for(int n_i = 0; n_i < pairing.length; n_i++) + { + int m_i = pairing[n_i]; + if(m_i == -1) + continue; + + sum += matrix[n_i][m_i]; + } + + return sum; + } + + /** + * Test whether Solver conforms for a semi-random test set. + * Note that these tests do not test whether a solution is optimal. + * (If it could do that the test would be a Solver by itself) + */ + private void performGeneratedTest(int n, int m) + { + int[][] compatibility = generateTestMatrix(n, m, 1); + int[] result = ps.solve(n, m, compatibility); + checkConformance(n, m, result); + } + + @Test(timeout = 2000) + public void testExample() { + int n = 5, m = 4; + int[][] compatibility = { + {1, 1, 0, 0}, + {0, 1, 1, 1}, + {0, 1, 0, 0}, + {1, 0, 1, 0}, + {0, 0, 1, 1} + }; + + int[] result = ps.solve(n, m, compatibility); + checkConformance(n, m, result); + Assert.assertEquals("Does not give a correct answer", 4, computeCompatibility(compatibility, result)); + } + + @Test(timeout = 2000) + public void testGeneratedSmall() { + performGeneratedTest(8, 10); + performGeneratedTest(10, 8); + } + + @Test(timeout = 2000) + public void testGeneratedMedium() { + performGeneratedTest(23, 20); + performGeneratedTest(20, 23); + } + + @Test(timeout = 5000) + public void testGeneratedLarge() { + performGeneratedTest(121, 130); + performGeneratedTest(130, 121); + } + + /** + * This timeout is just a suggestion, + * your solution is not incorrect if it takes longer, + * or if it is not capable to finish in a reasonable amount of time. + */ + @Test(timeout = 5000) + public void testGeneratedTerrible() { + performGeneratedTest(2910, 3102); + performGeneratedTest(3102, 2910); + } +} diff --git a/RandomSolver.java b/RandomSolver.java new file mode 100755 index 0000000..91b3bc6 --- /dev/null +++ b/RandomSolver.java @@ -0,0 +1,30 @@ +import java.util.ArrayList; +import java.util.Collections; +import java.util.Random; + +/* Generate a random solution which not is necessarily optimal. */ +public class RandomSolver implements IPetproblemSolver { + @Override + public int[] solve(int n, int m, int[][] compatibility) { + int[] result = new int[n]; + ArrayList possibilities = new ArrayList(); + + // Init list of possible pets + for(int m_i = 0; m_i < m; m_i++) + possibilities.add(m_i); + + // If number of children is bigger then number of pets + if(n > m) + for(int i = 0; i < n - m; i++) + possibilities.add(-1); // Add possibility of drawing "no pet" + + // Shuffle the available options + Collections.shuffle(possibilities, new Random()); + + // Assign a possible pet to all children + for(int n_i = 0; n_i < n; n_i++) + result[n_i] = possibilities.get(n_i); + + return result; + } +}