Commit 7cb8e930 authored by Dominikus Herzberg's avatar Dominikus Herzberg

Merge branch 'reorg'

parents 86f68d7d a508fe0f
......@@ -128,4 +128,236 @@ Nein, nein, so leicht sollten Sie es sich nicht machen. Entweder Sie haben Glüc
Wenn Sie den Fehler entdeckt haben, wie würden Sie ihn beheben?
// Nach der Umwandlung in eine Zahl könnte man überprüfen, ob sich der originale String aus der Zahl rekonstruieren lässt.
include::postDetails.adoc[]
\ No newline at end of file
include::postDetails.adoc[]
== Multiple-Choice-Test und der Zufall
Angenommen, Sie bekommen einen Multiple-Choice-Test mit zehn Fragen vorgelegt, wobei es zu jeder Frage vier ankreuzbare Antworten gibt. Sie wissen lediglich, dass pro Frage mehr als eine Antwort korrekt sein kann. Der Test wird so bewertet, dass es zur Lösung auf eine Frage nur dann einen Punkt gibt, wenn ausschließlich die korrekte Antwort bzw. die korrekten Antworten angekreuzt sind.footnote:[Die Anregung für diese Aufgabe geht zurück auf eine Email, die ich von Philipp Sautner erhalten habe.]
.Was sind Multiple-Choice-Fragen?
****
Im Deutschen ist mit Multiple-Choice-Test schlicht ein Antwort-Wahl-Verfahren gemeint, d.h. zu einer Frage stehen mehrere Antworten zur Wahl. Offen dabei ist, wieviele Antworten richtig sein können. Verwendet man im Englischen den Begriff _Multiple Choice_, dann will man damit ausdrücken, dass genau _eine_ Antwort richtig ist, was man im Deutschen wiederum _Single Choice_ nennt. Verwirrend, nicht wahr?
****
Schreiben Sie zur Beantwortung der folgenden Fragen ein Programm, mit dem Sie die verschiedene Fälle simulieren können.
=== Zufallskreuze machen
Angenommen, Sie sind unglücklicherweise nicht auf den Test vorbereitet. Wie viele Punkte erhalten Sie im Schnitt, wenn Sie zufällig Kreuze setzen?
include::preDetailsSolution.adoc[]
Da Sie nicht wissen, ob ein, zwei, drei oder vier Kreuze richtig sind, müssen wir für jeden dieser mit einem Viertel gewichteten Fälle ausrechnen, was es bedeutet, ein, zwei, drei oder vier Kreuze zu setzen. Man kommt im Mittel auf 10.4%.
CAUTION: Das verwendete Simulationsprogramm wird weiter unten erklärt. Sie können anhand seiner Nutzung vermutlich erraten, was die einzelnen Aufruf-Parameter bedeuten.
----
jshell> new MC(4,1,1,4).run(1_000_000)
$35 ==> 0.062644
jshell> new MC(4,2,1,4).run(1_000_000)
$36 ==> 0.041609
jshell> new MC(4,3,1,4).run(1_000_000)
$37 ==> 0.06242
jshell> new MC(4,4,1,4).run(1_000_000)
$38 ==> 0.249505
jshell> ($35 + $36 + $37 + $38)/4
$39 ==> 0.10404450000000001
----
Lassen Sie uns noch ein paar weitere Fälle betrachten, um etwas über Multiple-Choice-Fragen zu lernen.
Schließt man aus, dass Fälle mit vier korrekten Antworten vorkommen, dann sinkt die Wahrscheinlichkeit eines Zufallstreffers ab auf 7.4%.
----
jshell> new MC(4,1,1,3).run(1_000_000)
$40 ==> 0.082814
jshell> new MC(4,2,1,3).run(1_000_000)
$41 ==> 0.055447
jshell> new MC(4,3,1,3).run(1_000_000)
$42 ==> 0.083462
jshell> ($40 + $41 + $42)/3
$43 ==> 0.07390766666666666
----
Ist bekannt, dass nur ein oder zwei Antworten korrekt sind, kommt man auf 10.4%.
----
jshell> new MC(4,1,1,2).run(1_000_000)
$44 ==> 0.124957
jshell> new MC(4,2,1,2).run(1_000_000)
$45 ==> 0.083298
jshell> ($44 + $45)/2
$46 ==> 0.1041275
----
Und geht man davon aus, dass nur eine Antwort korrekt ist, dann wählt man zu 25% die richtige Antwort.
----
jshell> new MC(4,1,1,1).run(1_000_000)
$47 ==> 0.249135
----
include::postDetails.adoc[]
=== Zufallskreuze schlau gemacht
Ist es so schlau, rein zufällig Kreuze zu setzen? Sie lesen die Antworten zu den Fragen durch und stellen fest, dass sich manche Antworten ausschließen -- das kann man spachlogisch rausfinden, ohne etwas von der Thematik zu verstehen. Sie kommen zu dem Schluss, dass bei sieben der zehn Aufgaben nur eine oder zwei Antworten richtig sein können, und dass bei den restlichen drei Aufgaben ein, zwei oder drei Antworten richtig sein können.
Wie viele Punkte erhalten Sie im Schnitt, wenn Sie zwar zufällig Kreuze setzen, aber das abgeleitete Wissen um die Anzahl der möglichen Antworten ausnutzen?
include::preDetailsSolution.adoc[]
Wenn ein oder zwei Antworten richtig sind, dann "erraten" wir die richtige Antwort zu 10.4% -- das haben wir in der Lösung der vorigen Aufgabe gelernt. Bei ein bis drei richtigen Antworten ist die "Raterei" mit 7.4%iger Wahrscheinlichkeit erfolgreich -- auch das haben wir zuvor ermittelt. Da das eine in sieben, das andere in drei Fällen zutrifft, kommen wir auf eine Wahrscheinlichkeit von (7*10.4% + 3*7.4%)/10 = 9.5%.
include::postDetails.adoc[]
=== Zufallskreuze mit Vorwissen
Ihnen liegt die Musterlösung zu dem MC-Test vor. Sie wissen nun, wieviele Antworten tatsächlich richtig waren und was sich, mit Blick auf die sprachliche Analyse der Antworten, an Mutmaßungen über die Anzahl möglicher Lösungen aussagen lässt. Wir hoch waren die Chancen eines Studierenden nun tatsächlich, per Zufall Punkte zu holen?
|===
| Frage | 1. | 2. | 3. | 4. | 5. | 6. | 7. | 8. | 9. | 10.
| Lösung | 1 | 1 | 2 | 2 | 1 | 1 | 1 | 1 | 1 | 2
| Vermutung | 1-3 | 1-2 | 1-2 | 1-3 | 1-2 | 1-2 | 1-2 | 1-2 | 1-3 | 1-2
|===
include::preDetailsSolution.adoc[]
Stellen wir die möglichen Lösungen in einer Übersicht zusammen:
* 5x `new MC(4,1,1,2)`
* 2x `new MC(4,1,1,3)`
* 2x `new MC(4,2,1-2)`
* 1x `new MC(4,2,1-3)`
Das Ergebnis liegt bei 10.1%.
----
jshell> new MC(4,1,1,2).run(1_000_000)
$49 ==> 0.124973
jshell> new MC(4,1,1,3).run(1_000_000)
$50 ==> 0.083046
jshell> new MC(4,2,1,2).run(1_000_000)
$51 ==> 0.083814
jshell> new MC(4,2,1,3).run(1_000_000)
$52 ==> 0.055843
jshell> (5*$49 + 2*$50 + 2*$51 + $52)/10
$53 ==> 0.10144280000000001
----
include::postDetails.adoc[]
=== Das Simulationsprogramm
Ihr Programm mag vollkommen anders aussehen. Hier ist ein Vorschlag, wie man ohne allzuviel Wissen um Wahrscheinlichkeiten zu Antworten kommen kann.
include::preDetailsSolution.adoc[]
Der folgende Programmcode simuliert eine Wahlstrategie für _eine_ Multiple-Choice-Aufgabe:
* Eine Multiple-Choice-Aufgabe `MC` hat eine festgelegte Anzahl von Antworten zu einer Frage; wir nennen die Anzahl `answers`, mindestens eine Antwort muss gegeben sein (`answers >= 1`)
* Jede Frage hat eine bestimmte Anzahl an richtigen Antworten, `solutions`, wobei `solutions <= answers` sein muss
* Wenn der Antwortgeber rät, dann muss er sich entscheiden, wieviele Antworten er ankreuzt; wir geben vor, dass er eine zufällige Anzahl ankreuzt uns zwar aus dem Wertebereich von `minGuesses` bis `maxGuesses`
[source,java]
----
include::{sourcedir}/multipleChoice.java[tag=KlasseKonstruktor]
----
Das Array `crosses` dient zur Simulation eines zufälligen Ankreuzverhaltens. Das Array wird initialisiert und kann mit einem Aufruf von `shuffle`, als Klassenmethode angelegt, zufällig durchmischt werden.
[source,java]
----
include::{sourcedir}/multipleChoice.java[tag=shuffle]
----
Die Simulation eines Lösungsdurchlaufs nimmt die Methode `simulate` vor.
* Per Zufall wird ausgelost, wieviele Antwortkreuze gemacht werden sollen.
* Stimmt die Anzahl der Antwortkreuze mit der Anzahl der Lösungen nicht überein, ist klar, dass die Antwort falsch ist; ein `false` wird zurückgemeldet.
* Stimmt die Anzahl der Antwortkreuze, wird eine zufällige Ankreuzlösung generiert.
* Es wird abgeglichen, ob die Antwortkreuze auch die Lösungen abdecken; entsprechen wird ein `false` bzw. ein `true` zurückgegeben
[source,java]
----
include::{sourcedir}/multipleChoice.java[tag=simulate]
----
Die Methode `run` führt eine Simulation mehrfach durch und gibt den prozentualen Anteil erfolgreicher Lösungen an.
[source,java]
----
include::{sourcedir}/multipleChoice.java[tag=run]
----
Erproben wir die Richtigkeit bzw. die Plausibilität des Programms.
Angenommen, es gibt unter vier Fragen nur exakt eine korrekte Antwort, dann muss jemand, der zufällig ein Kreuz macht, diese Lösung mit einer Wahrscheinlichkeit von 25% richtig ankreuzen:
----
jshell> new MC(4,1,1,1).run(1_000_000)
$21 ==> 0.250007
----
Wenn man glaubt, dass auch zwei Kreuze möglich seien, dann veringert man die Wahrscheinlichkeit für eine richtige Lösung um die Hälfte (12.5%). Glaubt man, dass auch drei oder gar vier Kreuze richtig sein könnten, dann sind es nur ein Drittel bzw. ein Viertel von 25%, d.h. 8.3% bzw. 6.25%.
----
jshell> new MC(4,1,1,2).run(1_000_000)
$22 ==> 0.125209
jshell> new MC(4,1,1,3).run(1_000_000)
$23 ==> 0.083344
jshell> new MC(4,1,1,4).run(1_000_000)
$24 ==> 0.062426
----
Übrigens ist ein Gegencheck sinnvoll: Wenn bekannt ist, dass eine Antwort richtig ist (25%-Treffer), dann entspricht das der Aufgabe, bei bekannten drei richtigen Antworten die _eine_ falsche Antwort herauszusuchen. Unser Code muss das gleiche Ergebnis (wieder 25%) ausspucken:
----
jshell> new MC(4,3,3,3).run(1_000_000)
$48 ==> 0.249943
----
Angenommen, es gibt unter vier Fragen genau zwei korrekte Antworten, dann findet jemand, der zufällig zwei Kreuze macht, die Lösung in einem von sechs Fällen (1+2, 1+3, 1+4, 2+3, 2+4, 3+4), d.h. zu 16.6%.
----
jshell> new MC(4,2,2,2).run(1_000_000)
$25 ==> 0.166534
----
Die Zahl halbiert, drittelt bzw. viertelt sich, wenn man annimmt, auch nur ein Kreuz, drei bzw. vier Kreuze seien korrekt (8.3%, 5.6%, 4.1%).
----
jshell> new MC(4,2,1,2).run(1_000_000)
$26 ==> 0.083589
jshell> new MC(4,2,1,3).run(1_000_000)
$27 ==> 0.055681
jshell> new MC(4,2,1,4).run(1_000_000)
$28 ==> 0.041824
jshell> new MC(4,2,2,3).run(1_000_000)
$29 ==> 0.083615
jshell> new MC(4,2,2,4).run(1_000_000)
$30 ==> 0.05588
----
Die besprochenen Fälle liegen allesamt als Testfälle vor. Es kann nicht ganz ausgeschlossen werden, dass ein Test zufällig außerhalb der Toleranzzone liegt, aber bislang hat sich eine Genauigkeit von einem halben Prozentpunkt als zuverlässig erwiesen.
[source,java]
----
include::{sourcedir}/multipleChoice.java[tag=Tests]
----
include::postDetails.adoc[]
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment