Seite 2 von 2

Re: Münzwurf-Generator

Verfasst: Freitag 26. Juni 2020, 08:17
von __blackjack__
@kbr: Sorry ich versteh's nicht. Meine 54% Ergebnis hat nichts mit dem zu tun was Du da beschreibst und doch, die Wahrscheinlichkeit das wenn ich eine von den 100.000 Sequenzen rauspicke und da dann mindestens eine Sechserreihe enthalten ist, ist bei mir 80%. Und müsste auch nach Deinem Text so sein, denn der beschreibt für mich zweimal das gleiche mit anderen Worten.

Vorausgesetzt Sechserreihe meint 6 oder mehr und nicht *genau* sechs und dann *muss* was anderes kommen. Aber *den* Unterschied lese ich bei Deinem Text nicht heraus. *Dann* käme aber auch weder 54% noch 80% heraus, denn *der* Unterschied kommt bei mir durch eine Interpretation von „K oder Z“ zustande was man ja auf zwei verschiedene Arten verstehen kann — inklusiv oder exklusiv.

Ich habe ja in Code selbst ausprobiert das ich auch 54% herausbekomme wenn ich das „oder“ anders interpretiere. Hast Du auch in Code 80% heraus bekommen oder vermutest Du nur das das wohl heraus kommt wenn man Deine Argumentation zugrunde legt und wir reden gerade aneinander vorbei?

@Zizibee: Bei dem vorgehen wie Du das beschreibst bin ich auf 80% gekommen. Den Code habe ich ja gepostet. Und ich würde auch sagen bei Wurf 1 und 2 ist mindestens eine Viererreihe. Auf 54% komme ich wenn ich das „K oder Z“ so interpretiere das nur entweder Wurf 1 *oder* Wurf 2 ein Treffer ist, aber nicht *beide*.

Re: Münzwurf-Generator

Verfasst: Freitag 26. Juni 2020, 08:41
von Zizibee
@__blackjack__ Das ist ja merkwürdig, ich dachte ich habe das im Jupiter Notebook so umgesetzt, wie ich es eben erklärt habe:

Code: Alles auswählen

import random

REPEATS = 6
CHECKS = 10000
result_counter = 0

for _ in range(0, CHECKS):
    throws = [random.choice("ZK") for throw in range(0,100)]
    old_element = "-"
    same_element_counter = 0
    
    for element in throws:
        if old_element == element:
            same_element_counter = same_element_counter + 1
        else:
            same_element_counter = 0

        old_element = element

        if same_element_counter >= REPEATS:
            result_counter = result_counter + 1
            break
        
print(f'Gefunden {result_counter} von {CHECKS} => {result_counter / CHECKS * 100} %')
Gefunden 5454 von 10000 => 54.54 %

Re: Münzwurf-Generator

Verfasst: Freitag 26. Juni 2020, 10:39
von __blackjack__
@Zizibee: Hm, und ich denke ich mache im Grunde das gleiche, bekomme aber 80% heraus. Ich versteh's nicht…

Die 54% bekomme ich wenn ich das „K oder Z“ exklusiv interpretiere und die Sechserreihe als „mindestens 6“. Aber Dein Code sieht nach „K oder Z“ inklusiv und Sechserreihe als „mindestens 6“ aus, und da bekomme ich 80%. Also entweder sehe ich den Fehler bei Dir nicht oder ich sehe den Fehler bei mir nicht. ☹️

Nah dran an 54%, nämlich eher so um die 55% bekomme ich bei „K oder Z“ inklusive und Sechserreihe als „exakt 6“.

Randbemerkung `throws` klingt falsch. Das würde wohl eher `tosses` oder `flips` heissen.

Hier mal die Ergebnisse für die vier Varianten:

Code: Alles auswählen

bj@s8n:~$ ./test
80.53% for inclusive or and at least n.
55.07% for inclusive or and exactly n.
54.50% for exclusive or and at least n.
32.58% for exclusive or and exactly n.
bj@s8n:~$ ./test
80.78% for inclusive or and at least n.
55.24% for inclusive or and exactly n.
54.73% for exclusive or and at least n.
32.41% for exclusive or and exactly n.
bj@s8n:~$ ./test
80.71% for inclusive or and at least n.
55.17% for inclusive or and exactly n.
54.45% for exclusive or and at least n.
32.50% for exclusive or and exactly n.
Und das Vala-Programm dazu:

Code: Alles auswählen

private static string create_random_coin_flips (size_t count) {
    var result = new StringBuilder.sized (count);
    for (int i = 0; i < count; ++i) {
        result.append_c ((Random.boolean ()) ? 'H' : 'T');
    }
    return result.str;
}

private static uint count_runs (
    string text, size_t size, bool just_heads, bool exact_size
) {
    var result = 0;
    try {
        var regex = new Regex (
            "([%s])\\1{%u}".printf ((just_heads) ? "H" : "HT", (uint) size - 1)
        );
        MatchInfo match_info;
        
        regex.match (text, 0, out match_info);
        while (match_info.matches ()) {
            if (exact_size) {
                int start, end;
                match_info.fetch_pos (0, out start, out end);
                if (text[start] != text[end]) ++result;
            } else {
                ++result;
            }
            match_info.next ();
        }
    } catch (RegexError error) {
        print ("Error: %s\n", error.message);
        assert (false);
    }
    return result;
}

private static double run_experiment(
    uint repetition_count,
    uint flip_count,
    uint run_length,
    bool just_heads,
    bool exact_size
) {
    var has_run_count = 0;
    for (int i = 0; i < repetition_count; ++i) {
        var flip_results = create_random_coin_flips (flip_count);
        var run_count = count_runs (
            flip_results, run_length, just_heads, exact_size
        );
        if (run_count > 0) ++has_run_count;
    }
    return (double) has_run_count / repetition_count;
}

public static void main () {
    var repetition_count = 100000;
    var flip_count = 100;
    var run_length = 6;
    string[] or_description = {"inclusive or", "exclusive or"};
    string[] run_description = {"at least n", "exactly n"};
    
    for (var or_variant = 0; or_variant < 2; ++or_variant) {
        for (var run_variant = 0; run_variant < 2; ++run_variant) {
            print (
                "%.2f%% for %s and %s.\n",
                100 *run_experiment (
                    repetition_count,
                    flip_count,
                    run_length,
                    (bool) or_variant,
                    (bool) run_variant
                ),
                or_description[or_variant],
                run_description[run_variant]
            );
        }
    }
}

Re: Münzwurf-Generator

Verfasst: Freitag 26. Juni 2020, 10:44
von __blackjack__
@Zizibee: Ich denke ich habe den Fehler in *Deinem* Programm gefunden. Es brauchte einfach nur einen Kaffee. Du testest nicht ob mindestens 6 in einer Reihe sind sondern ob mindestens 7 in einer Reihe sind. Denn wenn `old_element` ungleich `element` ist, dann darf man `same_counter` nicht auf 0 setzen sondern muss mit 1 anfangen. Man hat dann ja den 1. eines möglichen Laufs gefunden, den man mitzählen muss.

Re: Münzwurf-Generator

Verfasst: Freitag 26. Juni 2020, 10:57
von Jankie
Was mache ich falsch, dass ich immer nur auf ca 74-77% komme?

Code: Alles auswählen

import random

def werfe_muenze(anzahl):
    return [random.choice(["K", "Z"]) for i in range(0, anzahl)]
    
def zaehle_vorkommen(ergebnisse):
    buchstabenfolge = "".join(ergebnisse)
    return buchstabenfolge.count("KKKKKK"), buchstabenfolge.count("ZZZZZZ")

def main():      
    anzahl_sechserserie_kopf = 0
    anzahl_sechserserie_zahl = 0
    for i in range(0,10000):    
        anzahl_kopf, anzahl_zahl = zaehle_vorkommen(werfe_muenze(100))
        anzahl_sechserserie_kopf += anzahl_kopf
        anzahl_sechserserie_zahl += anzahl_zahl
    print(f"Kopf {anzahl_sechserserie_kopf}")
    print(f"Zahl {anzahl_sechserserie_zahl}")
    
main()

Re: Münzwurf-Generator

Verfasst: Freitag 26. Juni 2020, 11:02
von nezzcarth
@__blackjack__: Was du beschreibst, entspricht dem, was ich meinte: Man kann "Wiederholung" (das Worte hatte ich verwendet, in der Aufgabe steht es nicht) so verstehen, dass es eben das eigentliche Element + n Wiederholungen davon sind; also z.B. 1 Element + 6 Wiederholungen davon, was zu einer Gruppengröße von 7 führt . Das ist hier klar ein Programmierfehler (off-by-one-error), da in der Aufgabenstwellung von 6 mal die Rede ist, aber so bin ich im ersten Anlauf eben auf die 54% gekommen:

Code: Alles auswählen

#!/usr/bin/awk -f
function has_sixes(numbers,        i, repeats) {
    for (i=1; i<length(numbers); i++) {
        if (numbers[i] == numbers[i-1]) {
            repeats += 1;
        } else {
            repeats = 0;
        }
        # sic!
        if (repeats == 6) return 1;
    }
    # sic!
    if (repeats >= 6) {return 1} else {return 0};
}

BEGIN {
    srand();
    for (k=0; k<10000; k++) {
        for (j=0; j<100; j++) {
            p = rand();
            if (p<0.5) {
                numbers[j] = "K";
            } else {
                numbers[j] = "Z";
            }
        }
        stats[has_sixes(numbers)] += 1;
    }
    for (key in stats) {
        print key, stats[key]/100;
    }
}

Code: Alles auswählen

% ./flip.awk  
0 45.53
1 54.47

Re: Münzwurf-Generator

Verfasst: Freitag 26. Juni 2020, 11:10
von nezzcarth
Jankie hat geschrieben: Freitag 26. Juni 2020, 10:57 Was mache ich falsch, dass ich immer nur auf ca 74-77% komme?
Du wertest die Anzahl aus. Nach meinem Verständnis ist das nicht gefragt.

Vergleiche folgende Variante deines Codes:

Code: Alles auswählen

#!/usr/bin/env python3
import random

def werfe_muenze(anzahl):
    return [random.choice(["K", "Z"]) for i in range(0, anzahl)]
    
def zaehle_vorkommen(ergebnisse):
    buchstabenfolge = "".join(ergebnisse)
    return buchstabenfolge.count("KKKKKK") > 0 or  buchstabenfolge.count("ZZZZZZ") > 0

def main():      
    sechser = 0
    for i in range(10_000):    
        resultat= zaehle_vorkommen(werfe_muenze(100))
        sechser += resultat
    print(sechser)
    
main()

Code: Alles auswählen

% ./jankie.py
8021

Re: Münzwurf-Generator

Verfasst: Freitag 26. Juni 2020, 11:18
von __blackjack__
@nezzcarth: Die Variante hatte ich bis Zizibee seinen Code gezeigt hat überhaupt gar nicht auf dem Schirm. Also kann ich das in der Konversation mit Dir vorher nicht beschrieben haben‽ Was die Lauflänge angeht war da bei mir immer nur die Unterscheidung zwischen „mindestens 6“ oder „exakt 6“. Klar ergibt „exakt 6“ (fast) die gleiche Wahrscheinlichkeit wie „mindestens 1 + 6 Wiederholungen” aber der Test darauf sieht ja anders aus, weswegen ich da so überhaupt nicht drauf gekommen bin, dass Du das gemeint haben könntest.

Diese „1 + 6 Wiederholungen“ gibt der Aufgabentext IMHO nicht her, während er IMHO bei „mindestens 6“ oder „exakt 6“ wirklich interpretationsfähig wäre, wenn da am Ende die 80% nicht erwähnt werden würden.

Re: Münzwurf-Generator

Verfasst: Freitag 26. Juni 2020, 11:29
von nezzcarth
@__blackjack__: Das habe ich undeutlich formuliert, entschuldige bitte. Ich meinte "beschrieben" in Bezug auf deinen Post um 11:44 an Zizibee in dem du den Fehler erklärst, nicht in Bezug auf deine und meine Konversation davor.

Und wie du schon sagst, der Aufgabentext gibt meine Interpretation nicht her, aber in die Falle bin ich halt getappt und habe mich über die 54% gewundert. :)

Re: Münzwurf-Generator

Verfasst: Freitag 26. Juni 2020, 11:32
von kbr
Ich werfe hier mal meinen Code rein. Als erstes berechne ich, wie häufig Sechserreihen in 100er Sequenzen zu finden sind und komme damit auf ca. 76%.

Code: Alles auswählen

import re
import random

pat = re.compile('1{6}')
runs = int(1e4)
choices = '0', '1'
sequence_size = 100

def has_match():
    return len(pat.findall(''.join(random.choice(choices) for _ in range(sequence_size))))

matches = sum(has_match() for _ in range(runs))
print(f'probability: {matches / runs * 100:4.1f} %')
Dann modifiziere ich has_match() um zu testen, ob eine Sequenz zumindest eine Sechserreihe enthält:

Code: Alles auswählen

def has_match():
    return bool(pat.search(''.join(random.choice(choices) for _ in range(sequence_size))))
Das ergibt dann ca. 54%. Die Differenz kommt dadurch zustande, dass die Sechserreihen nicht gleichverteilt über alle 100er Sequenzen vorkommen.

D.h., werden nur die 100er Sequenzen betrachtet, dann werden etwa 46% davon keine Sechserreihen enthalten.

Re: Münzwurf-Generator

Verfasst: Freitag 26. Juni 2020, 11:54
von __blackjack__
@kbr: Du hast also das „K oder Z“ als exklusives oder interpretiert im Gegensatz zum Aufgabensteller. Und der Code vor der Modifikation mit dem `bool` ist falsch. Also entweder der Code oder der Text in der `print()`-Ausgabe, denn das ist ja keine Wahrscheinlichkeit wenn man da `len()` statt `bool()` verwendet.

Re: Münzwurf-Generator

Verfasst: Freitag 26. Juni 2020, 12:01
von Zizibee
@__blackjack__: Danke fürs drüberschauen. Da nezzcarth auch 54 % als Ergbenis raus hatte, bin ich gar nicht auf die Idee gekommen, den Fehler in meinem Code zu suchen.

Re: Münzwurf-Generator

Verfasst: Freitag 26. Juni 2020, 16:50
von kbr
@__blackjack__: ja, ich hatte nur nach Kopf gesucht (möglicherweise hatte ich das 'oder' aus Kopf oder Zahl verinnerlicht). Wenn ich nach Kopf und Zahl suche komme ich auch auf 80% für mindestens eine Sechserreihe pro Sequenz.

Der Sinn von len() entspricht Aufgabe Teil 2. Das ergibt dann ca. 1.5 Sechserreihen pro Sequenz.

Re: Münzwurf-Generator

Verfasst: Freitag 26. Juni 2020, 18:57
von __blackjack__
Oh den 2. Teil habe ich gar nicht beachtet. Aber da stellt sie dann ja auch wieder die Frage wie eine Sechserreihe eigentlich definiert ist. Gibt ja drei Möglichkeiten. :-)