From 5df67831497e88d85757f7dd731d9985b0c675ae Mon Sep 17 00:00:00 2001 From: Martin Goik <goik@hdm-stuttgart.de> Date: Sat, 26 Sep 2015 16:21:06 +0200 Subject: [PATCH] Recursive binomial calculation --- Doc/Sd1/Ref/Fig/pascal.fig | 96 ++++ Doc/Sd1/objectsClasses.xml | 428 +++++++++++++++++- P/Sd1/Binomial/V3/.gitignore | 5 + P/Sd1/Binomial/V3/pom.xml | 20 + .../mi/sd1/binomial/Binomial.java | 42 ++ .../mi/sd1/binomial/Lottery.java | 18 + .../mi/sd1/binomial/PerformanceTest.java | 30 ++ .../mi/sd1/binomial/test/BinomTest.java | 60 +++ P/pom.xml | 3 + 9 files changed, 678 insertions(+), 24 deletions(-) create mode 100644 Doc/Sd1/Ref/Fig/pascal.fig create mode 100644 P/Sd1/Binomial/V3/.gitignore create mode 100644 P/Sd1/Binomial/V3/pom.xml create mode 100644 P/Sd1/Binomial/V3/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/Binomial.java create mode 100644 P/Sd1/Binomial/V3/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/Lottery.java create mode 100644 P/Sd1/Binomial/V3/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/PerformanceTest.java create mode 100644 P/Sd1/Binomial/V3/src/test/java/de/hdm_stuttgart/mi/sd1/binomial/test/BinomTest.java diff --git a/Doc/Sd1/Ref/Fig/pascal.fig b/Doc/Sd1/Ref/Fig/pascal.fig new file mode 100644 index 000000000..29c325144 --- /dev/null +++ b/Doc/Sd1/Ref/Fig/pascal.fig @@ -0,0 +1,96 @@ +#FIG 3.2 Produced by xfig version 3.2.5c +Landscape +Center +Metric +A4 +100.00 +Single +-2 +1200 2 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 1957 3442 2182 3217 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 2407 2992 2632 2767 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 2857 2542 3082 2317 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 5130 2970 5355 2745 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 2857 3442 3082 3217 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 3307 2992 3532 2767 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 3757 2542 3982 2317 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 3285 2115 3510 1890 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 2025 3510 2655 3510 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 2925 3510 3555 3510 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 3825 3510 4455 3510 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 4725 3510 5355 3510 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 2430 3060 3060 3060 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 3330 3060 3960 3060 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 4185 3060 4815 3060 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 2880 2610 3510 2610 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 3780 2610 4410 2610 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 3330 2160 3960 2160 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 2160 2610 2610 2610 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 1710 3060 2160 3060 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 1260 3510 1710 3510 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 2610 2160 3060 2160 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 3060 1710 3510 1710 +2 3 0 0 0 0 60 -1 2 0.000 0 0 -1 0 0 4 + 1267 3877 3652 1537 6037 3877 1267 3877 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 3757 1642 3982 1417 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 4207 2092 4432 1867 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 4680 2520 4905 2295 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 5602 3397 5827 3172 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 3757 3397 3982 3172 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 4207 2947 4432 2722 +2 1 0 1 0 0 50 -1 2 0.000 0 0 -1 0 0 2 + 4657 3442 4882 3217 +4 0 0 50 -1 30 12 0.0000 4 135 105 3600 1800 1\001 +4 0 0 50 -1 30 12 0.0000 4 135 105 3150 2250 1\001 +4 0 0 50 -1 30 12 0.0000 4 135 105 4050 2250 1\001 +4 0 0 50 -1 30 12 0.0000 4 135 105 2700 2700 1\001 +4 0 0 50 -1 30 12 0.0000 4 135 105 4500 2700 1\001 +4 0 0 50 -1 30 12 0.0000 4 120 105 3600 2700 2\001 +4 0 0 50 -1 30 12 0.0000 4 135 105 2250 3150 1\001 +4 0 0 50 -1 30 12 0.0000 4 135 105 4950 3150 1\001 +4 0 0 50 -1 30 12 0.0000 4 135 105 5400 3600 1\001 +4 0 0 50 -1 30 12 0.0000 4 135 105 1800 3600 1\001 +4 0 0 50 -1 30 12 0.0000 4 120 105 3150 3150 3\001 +4 0 0 50 -1 30 12 0.0000 4 120 105 4050 3150 3\001 +4 0 0 50 -1 30 12 0.0000 4 135 105 2700 3600 4\001 +4 0 0 50 -1 30 12 0.0000 4 120 105 3600 3600 6\001 +4 0 0 50 -1 30 12 0.0000 4 135 105 4500 3600 4\001 +4 0 0 50 -1 30 12 0.7854 4 150 345 5490 2745 k=3\001 +4 0 0 50 -1 30 12 0.7854 4 150 345 5895 3195 k=4\001 +4 0 0 50 -1 30 12 0.0000 4 135 345 810 3600 n=4\001 +4 0 0 50 -1 30 12 0.0000 4 120 345 1260 3150 n=3\001 +4 0 0 50 -1 30 12 0.0000 4 120 345 1710 2700 n=2\001 +4 0 0 50 -1 30 12 0.0000 4 135 345 2160 2250 n=1\001 +4 0 0 50 -1 30 12 0.0000 4 120 345 2610 1800 n=0\001 +4 0 0 50 -1 30 12 0.7854 4 150 345 4590 1845 k=1\001 +4 0 0 50 -1 30 12 0.7854 4 150 345 4140 1395 k=0\001 +4 0 0 50 -1 30 12 0.7854 4 150 345 4995 2250 k=2\001 diff --git a/Doc/Sd1/objectsClasses.xml b/Doc/Sd1/objectsClasses.xml index 6130ddfa2..534dbb62c 100644 --- a/Doc/Sd1/objectsClasses.xml +++ b/Doc/Sd1/objectsClasses.xml @@ -3010,20 +3010,21 @@ Largest long value:9223372036854775807</programlisting></td> <para>The following sections provide exercises on implementing mathematical functions. We start with an easy one.</para> - <qandaset defaultlabel="qanda" xml:id="sd1QandaMaxAbs"> + <section xml:id="sd1SectMaxAbs"> <title>Maximum and absolute value</title> - <qandadiv> - <qandaentry> - <question> - <para>Implement a class method methods <methodname>double - abs(double)</methodname> and two overloaded methods - <methodname>double max(double, double)</methodname> and - <methodname>double max(double, double, double)</methodname> in a - class <classname>Math</classname> living in a package of your - choice:</para> + <qandaset defaultlabel="qanda" xml:id="sd1QandaMaxAbs"> + <qandadiv> + <qandaentry> + <question> + <para>Implement a class method methods <methodname>double + abs(double)</methodname> and two overloaded methods + <methodname>double max(double, double)</methodname> and + <methodname>double max(double, double, double)</methodname> in + a class <classname>Math</classname> living in a package of + your choice:</para> - <programlisting language="java">package de.hdm_stuttgart.de.sd1.math; + <programlisting language="java">package de.hdm_stuttgart.de.sd1.math; /** * Some class methods. @@ -3062,21 +3063,22 @@ public class Math { } }</programlisting> - <para>Provide at at least 8 unit tests.</para> - </question> + <para>Provide at at least 8 unit tests.</para> + </question> - <answer> - <annotation role="make"> - <para role="eclipse">Sd1/math/V0_5</para> - </annotation> + <answer> + <annotation role="make"> + <para role="eclipse">Sd1/math/V0_5</para> + </annotation> - <para>See <link - xlink:href="Ref/api/P/math/V0_5/de/hdm_stuttgart/de/sd1/math/Math.html">implementation - here.</link></para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> + <para>See <link + xlink:href="Ref/api/P/math/V0_5/de/hdm_stuttgart/de/sd1/math/Math.html">implementation + here.</link></para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> <section xml:id="sd1SectFactorialDirect"> <title>Factorial, the direct way</title> @@ -3636,6 +3638,384 @@ System.out.println(factorial(3));</programlisting> </qandaset> </section> + <section xml:id="sd1SectBinomRecursive"> + <title>Binomials, the recursive way</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaBinomRecursive"> + <qandadiv> + <qandaentry> + <question> + <para>With respect to the upcoming <link + linkend="sd1SectTicTacToeComputerVsHuman">tic-tac-toe strategy + exercise</link> we provide a second example of a recursively + defined method. Our binomial coefficients from our <link + linkend="sd1SectLotteryRevisited">lottery exercise</link> may + be computed in a recursive fashion. Consider pascal's + triangle: </para> + + <figure xml:id="sd1FigPascalTriangle"> + <title>Pascal's triangle representing binomial + coefficients.</title> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Fig/pascal.fig"/> + </imageobject> + </mediaobject> + </figure> + + <para>Each inner node within the triangle is the sum of its + two upper left and right neighbours. With respect to a + recursive definition <xref linkend="sd1FigPascalTriangle"/> + tells us:</para> + + <glosslist> + <glossentry> + <glossterm>Reducing statement</glossterm> + + <glossdef> + <para><inlineequation> + <m:math display="inline"> + <m:mrow> + <m:msub> + <m:mo>∀</m:mo> + + <m:mrow> + <m:mi>0</m:mi> + + <m:mo><</m:mo> + + <m:mi>k</m:mi> + + <m:mo><</m:mo> + + <m:mi>n</m:mi> + </m:mrow> + </m:msub> + + <m:mi>:</m:mi> + + <m:mi> </m:mi> + + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mrow> + <m:mi>n</m:mi> + + <m:mo>+</m:mo> + + <m:mi>1</m:mi> + </m:mrow> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mrow> + <m:mi>k</m:mi> + + <m:mo>+</m:mo> + + <m:mi>1</m:mi> + </m:mrow> + </m:mtd> + </m:mtr> + </m:mtable> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mi>n</m:mi> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mrow> + <m:mi>k</m:mi> + + <m:mo>+</m:mo> + + <m:mi>1</m:mi> + </m:mrow> + </m:mtd> + </m:mtr> + </m:mtable> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>+</m:mo> + + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mi>n</m:mi> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mi>k</m:mi> + </m:mtd> + </m:mtr> + </m:mtable> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> .</para> + + <para>This equation is actually a straightforward + exercise by simply adding two fractions. Wanna + try?</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Termination condition</glossterm> + + <glossdef> + <para><inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mi>n</m:mi> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mi>0</m:mi> + </m:mtd> + </m:mtr> + </m:mtable> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mi>n</m:mi> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mi>n</m:mi> + </m:mtd> + </m:mtr> + </m:mtable> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mi>1</m:mi> + </m:mrow> + </m:math> + </inlineequation>.</para> + + <para>These are values from the left and right edge of + <xref linkend="sd1FigPascalTriangle"/>.</para> + </glossdef> + </glossentry> + </glosslist> + + <para>Tasks:</para> + + <orderedlist> + <listitem> + <para>Re-implement <methodname>public static long + binomial(int n, int k)</methodname> in a recursive fashion + as outlined above.</para> + + <tip> + <para>This is surprisingly simple. You may want to + consider external resources dealing with the subject of + recursively implemented methods.</para> + </tip> + </listitem> + + <listitem> + <para>Compare the performance of your recursive + implementation and the traditional loop based approach. + The <quote>6 out of 90</quote> lottery is a good starting + point.</para> + + <tip> + <para>Measuring method execution times is simple using + either <link + xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#currentTimeMillis--">currentTimeMillis()</link> + or <link + xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#nanoTime--">nanoTime</link>. + <quote + xlink:href="http://www.mkyong.com/java/how-do-calculate-elapsed-execute-time-in-java">See + How to calculate elapsed / execute time in + Java</quote>.</para> + </tip> + </listitem> + + <listitem> + <para>Reuse your unit tests from the <link + linkend="sd1SectLotteryRevisited">lottery + exercise</link>.</para> + </listitem> + </orderedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">Sd1/Binomial/V3</para> + </annotation> + + <para>The implementation is surprisingly simple:</para> + + <programlisting language="java"> public static long binomial(int n, int k) { + + if (0 == k || n == k) { // End of recursion? + return 1; + } else { // Continue reducing: 0 < k < n holds true. + return binomial(n - 1, k) + binomial(n - 1, k - 1); + } + }</programlisting> + + <para>For the purpose of comparison we rename the + <quote>traditional</quote> loop based implementation as + <methodname>static public long binomialLoop(int n, int + k)</methodname> and add a performance test:</para> + + <informaltable border="1"> + <colgroup width="10%"/> + + <colgroup width="90%"/> + + <tr> + <th>Code</th> + + <td valign="top"><programlisting language="java"> public static void main(String[] args) { + + long recursiveTime = 0, loopTime = 0; + + for (int i = 0; i < 10; i++) { + { + final long start = System.nanoTime(); + System.out.println(Binomial.binomial(90, 6)); + final long duration = (System.nanoTime() - start); + recursiveTime += duration; + System.out.println("Recursive: Elapsed time:" + duration); + } + { + final long start = System.nanoTime(); + System.out.println(Binomial.binomialLoop(90, 6)); + final long duration = (System.nanoTime() - start); + loopTime += duration; + System.out.println("Loop: Elapsed time:" + duration); + } + System.out.println(" End of run #" + i + " -------------------------------"); + } + System.out.println("Aggregated loop time: " + loopTime); + System.out.println("Aggregated recursion time: " + recursiveTime); + System.out.println("Ratio Recursive / Loop: " + (recursiveTime / loopTime)); + }</programlisting></td> + </tr> + + <tr> + <th>Result</th> + + <td valign="top"><programlisting language="none">622614630 +Recursive: Elapsed time:1801476567 +622614630 +Loop: Elapsed time:27028 + End of run #0 ------------------------------- +622614630 +Recursive: Elapsed time:1748821324 +622614630 +Loop: Elapsed time:22768 + End of run #1 ------------------------------- +... + End of run #9 ------------------------------- +Aggregated loop time: 267557 +Aggregated recursion time: 17539461906 +Ratio Recursive / Loop: 65554</programlisting></td> + </tr> + </informaltable> + + <para>From a performance point of view this result is quite + disillusioning: The loop based implementation is on average + ~65000 times faster than the recursive approach. </para> + + <para>This is a frequent result: Albeit providing elegant + solutions using recursion in many situations is a <emphasis + role="bold">very bad</emphasis> idea and thus strongly + discouraged. There are however situations where:</para> + + <orderedlist> + <listitem> + <para>The performance penalty is not that large.</para> + </listitem> + + <listitem> + <para>Recursion is the (maybe only) way to implement a + desired logic.</para> + </listitem> + </orderedlist> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + <section xml:id="sd1SecExp"> <title>Implementing exponentials.</title> diff --git a/P/Sd1/Binomial/V3/.gitignore b/P/Sd1/Binomial/V3/.gitignore new file mode 100644 index 000000000..cf5fd6bb2 --- /dev/null +++ b/P/Sd1/Binomial/V3/.gitignore @@ -0,0 +1,5 @@ +/.settings +/target +/.classpath +/.project +/A1.log diff --git a/P/Sd1/Binomial/V3/pom.xml b/P/Sd1/Binomial/V3/pom.xml new file mode 100644 index 000000000..e53220296 --- /dev/null +++ b/P/Sd1/Binomial/V3/pom.xml @@ -0,0 +1,20 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>de.hdm-stuttgart.mi</groupId> + <artifactId>lecturenotes-pom</artifactId> + <version>1.0</version> + <relativePath>../../../pom.xml</relativePath> + </parent> + + <groupId>de.hdm-stuttgart.de.sd1</groupId> + <artifactId>binomial</artifactId> + <version>1.3</version> + <packaging>jar</packaging> + + <name>Binomial</name> + <url>http://www.mi.hdm-stuttgart.de/freedocs</url> + +</project> diff --git a/P/Sd1/Binomial/V3/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/Binomial.java b/P/Sd1/Binomial/V3/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/Binomial.java new file mode 100644 index 000000000..1fc377f54 --- /dev/null +++ b/P/Sd1/Binomial/V3/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/Binomial.java @@ -0,0 +1,42 @@ +package de.hdm_stuttgart.mi.sd1.binomial; + +public class Binomial { + + static public long binomial(int n, int k) { + + if (0 == k || n == k) { // End of recursion? + return 1; + } else { // Continue reducing: 0 < k < n holds true. + return binomial(n - 1, k) + binomial(n - 1, k - 1); + } + } + + static public long binomialLoop(int n, int k) { + + // Trying to avoid arithmetic overflow by making use of: + // n n + // ( ) = ( ) + // k n-k + // + if (n / 2 < k) { + k = n - k; + } + + // Numerator product n (n - 1) ... (n - k + 1) + long numerator = 1; + for (int i = n - k + 1; i <= n; i++) { + numerator *= i; + } + return numerator / factorial(k); + } + + public static long factorial(int n) { + long ret = 1; + + for (int i = 2; i <= n; i++) { + ret *= i; + } + return ret; + } + +} diff --git a/P/Sd1/Binomial/V3/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/Lottery.java b/P/Sd1/Binomial/V3/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/Lottery.java new file mode 100644 index 000000000..7a4dd57f1 --- /dev/null +++ b/P/Sd1/Binomial/V3/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/Lottery.java @@ -0,0 +1,18 @@ +package de.hdm_stuttgart.mi.sd1.binomial; + +public class Lottery { + + public static void main(String[] args) { + + // Input values: + final int + totalNumberCount = 49, + drawnNumberCount = 6; + + System.out.println( + "Your chance to win when drawing " + drawnNumberCount + + " out of " + totalNumberCount + + " is 1 : " + Binomial.binomial(totalNumberCount, drawnNumberCount)); + } + +} diff --git a/P/Sd1/Binomial/V3/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/PerformanceTest.java b/P/Sd1/Binomial/V3/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/PerformanceTest.java new file mode 100644 index 000000000..642f9db8c --- /dev/null +++ b/P/Sd1/Binomial/V3/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/PerformanceTest.java @@ -0,0 +1,30 @@ +package de.hdm_stuttgart.mi.sd1.binomial; + +public class PerformanceTest { + + public static void main(String[] args) { + + long recursiveTime = 0, loopTime = 0; + + for (int i = 0; i < 10; i++) { + { + final long start = System.nanoTime(); + System.out.println(Binomial.binomial(90, 6)); + final long duration = (System.nanoTime() - start); + recursiveTime += duration; + System.out.println("Recursive: Elapsed time:" + duration); + } + { + final long start = System.nanoTime(); + System.out.println(Binomial.binomialLoop(90, 6)); + final long duration = (System.nanoTime() - start); + loopTime += duration; + System.out.println("Loop: Elapsed time:" + duration); + } + System.out.println(" End of run #" + i + " -------------------------------"); + } + System.out.println("Aggregated loop time: " + loopTime); + System.out.println("Aggregated recursion time: " + recursiveTime); + System.out.println("Ratio Recursive / Loop: " + (recursiveTime / loopTime)); + } +} diff --git a/P/Sd1/Binomial/V3/src/test/java/de/hdm_stuttgart/mi/sd1/binomial/test/BinomTest.java b/P/Sd1/Binomial/V3/src/test/java/de/hdm_stuttgart/mi/sd1/binomial/test/BinomTest.java new file mode 100644 index 000000000..fa8c806ab --- /dev/null +++ b/P/Sd1/Binomial/V3/src/test/java/de/hdm_stuttgart/mi/sd1/binomial/test/BinomTest.java @@ -0,0 +1,60 @@ +package de.hdm_stuttgart.mi.sd1.binomial.test; + +import org.junit.Assert; +import org.junit.Test; + +import de.hdm_stuttgart.mi.sd1.binomial.Binomial; + +public class BinomTest { + + @Test + public void test_0_0() { + Assert.assertEquals(1, Binomial.binomial(0, 0)); + } + + @Test + public void test_1_0() { + Assert.assertEquals(1, Binomial.binomial(1, 0)); + } + + @Test + public void test_1_1() { + Assert.assertEquals(1, Binomial.binomial(1, 1)); + } + + @Test + public void test_4_3() { + Assert.assertEquals(4, Binomial.binomial(4, 3)); + } + + @Test + public void test_5_3() { + Assert.assertEquals(10, Binomial.binomial(5, 3)); + } + + @Test + public void test_20_20() { + Assert.assertEquals(1, Binomial.binomial(20, 20)); + } + + // Possible arithmetic overflow situations. + @Test + public void test_22_1() { + Assert.assertEquals(22, Binomial.binomial(22, 1)); + } + + @Test + public void test_22_21() { + Assert.assertEquals(22, Binomial.binomial(22, 21)); + } + + @Test + public void test_22_2() { + Assert.assertEquals(231, Binomial.binomial(22, 2)); + } + + @Test + public void test_22_20() { + Assert.assertEquals(231, Binomial.binomial(22, 20)); + } +} diff --git a/P/pom.xml b/P/pom.xml index 110347e76..5c2bdc652 100644 --- a/P/pom.xml +++ b/P/pom.xml @@ -31,6 +31,9 @@ <module>Sd1/Array/integerStore</module> <module>Sd1/Array/integerStoreMedianAnswer</module> + <module>Sd1/Binomial/V1</module> + <module>Sd1/Binomial/V3</module> + <module>Sd1/CarJump/V1</module> <module>Sd1/CarJump/V2</module> <module>Sd1/CarJump/V5</module> -- GitLab