Michael: Random

Hi,

ich habe folgendes Problem:
Ich will aus einer SQL Tabelle mit etwa 450 Einträgen zufällig einen Wert auslesen. Allerdings ist eine möglichst exakte Gleichverteilung leider sehr wichtig.

mit rand, mt_rand und dem OrderBy rand (in SQL) krieg ich das irgendwie nicht hin.

Hier mal mein Quelltext falls da ein Fheler sein sollte

mt_srand(microtime()*1000000);
     $zufall = mt_rand(0,450);

Kennt jemand eine gute alternative?

Hoffe einer von euch kann mir helfen

Gruß Michael

  1. Moin!

    Ich will aus einer SQL Tabelle mit etwa 450 Einträgen zufällig einen Wert auslesen. Allerdings ist eine möglichst exakte Gleichverteilung leider sehr wichtig.

    mit rand, mt_rand und dem OrderBy rand (in SQL) krieg ich das irgendwie nicht hin.

    Wie erkennst du, dass deine Versuche scheitern?

    - Sven Rautenberg

    --
    "Love your nation - respect the others."
    1. habs getestet, einige der 450 einträge kamen noch nie n paar ander
      schon 20 30 mal insgesamt stimmts einfach nicht.

      1. Moin!

        habs getestet, einige der 450 einträge kamen noch nie n paar ander
        schon 20 30 mal insgesamt stimmts einfach nicht.

        Aber sowas ist doch vollkommen normal bei "Zufall".

        Gleichverteilung  bedeutet nicht, dass hübsch nacheinander alle 450 Einträge zufällig verteilt genau einmal kommen, bevor dann der erste Eintrag zweimal kommt.

        Wenn du mal eine Statistik führt, wie häufig jeder Eintrag kommt, und dann so ungefähr 450.000.000 Versuche machst - und DABEI dann immer noch ein Eintrag niemals erscheint - DANN erst solltest du dir Gedanken machen.

        - Sven Rautenberg

        --
        "Love your nation - respect the others."
        1. Hello,

          vielleicht meinte Michael nicht, dass er die Datensätze zufällig auswählen lassen will, sondern sie in einer zufälligen Reihenfolge auswählen möchte, die bei jedem Volldurchlauf (Jeder war genau einmal dran) immer anders sein soll.

          Dann sollte er sich so eine Art "Sieb des Eratosthenes" bauen, also eine Abstreichliste.

          vorhandene IDs auslesen in ein Array,
          Array verwürfeln lassen,
          in externe Datei oder Tabelle eintragen

          Beim Aufruf die Tabelle einfach abarbeiten und den benutzten Satz immer entfernen.
          Wenn sie leer ist, wird eine neue erzeugt.

          Interessant dafür ist allerdings die Betrachtung des dynamischen Verhaltens der Lösung.
          Was passiert mit Sätzen, die während eines Durchlaufes hinzukommen oder weggefallen sind?
          Muss man ja meistens damit rechnen in einer realen Online-Datenbank.

          Harzliche Grüße vom Berg
          http://bergpost.annerschbarrich.de

          Tom

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau
          Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

          1. Hallo,

            erst mal danke euch allen für die Lösungsansätze.

            Aber ich seh schon ich hätte das Problem wohl ein bischen genauer beschreiben sollen.

            Also es geht um folgendes:

            Ich programmier gerade mit einem Freund an einem Quiz. Die 450 Einträge sind die Fragen und es ist jetzt so das auf ich sag mal 1000 Versuche etwa 200 der Einträge nie kamen und etwa 50 sehr häufig vorkommen.

            Es kann schon sein das es trotzdem eine Zufallsverteilung ist, die sich auf 10000000 Aufrufe ausgleicht, aber das bringt mir ja nichts, da niemand später so oft das Quiz spielen wird ):

            Das mit der "Strichliste" wie oft etwas dran war oder so könnte das Problem lösen aber kennt ihr vielleicht noch ein einfacheres System, das dafür sorgt das die Fragen einerseits nicht immer in der gleichen Reihenfolge kommen und andererseits regelmäßig alle Fragen drankommen so das nach spätestens 2000 aufrufen alle 450 Fragen einmal vorkamen? Und möglichst keine öfter als 8 mal.

            ps ein weiteres Problem ist das ich einzelne User nicht unterscheiden kann, lösungen die ins diese richtung gingen werden also nicht funktionieren.

            So ich denk das macht das Problem klarer (hätt ich gleich so schreiben sollen)

            1. Hello,

              Das mit der "Strichliste" wie oft etwas dran war oder so könnte das Problem lösen aber kennt ihr vielleicht noch ein einfacheres System,

              Das einfachste System ist wirklich,

              Zugriff auf eine Liste (serialisiertees Array) zur Ermittlung der ID
                   und Beseitigung des Datensatzes.
                Wenn die Liste leer ist, wird sie neu generiert
                Wenn sie nach der Neugenerierung immer noch leer ist -> Aussprung aus der Schleife mit Fehler
                Holen des Datensatzes aus der Tabelle
                Wenn die ID nicht mehr vorhanden war, erneuter Zugriff auf die Tabelle

              So ist gewährleistet, dass alle Fragen der Reihe nach drankommen.

              ein weiteres Problem ist das ich einzelne User nicht unterscheiden kann, lösungen die ins diese richtung gingen werden also nicht funktionieren.

              Da muss man jetzt philosophieren.
              Soll jeder Besucher alle Fragen vorgeschlagen bekommen zur Auswahl?
              Dann muss die obige Liste in der Session des Users geführt werden.
              Damit kannst Du die User auch unterscheiden, aber eben nicht persönlich identifizieren.

              Session ist also das erste Zauberwort.

              Bei Benutzugn einer Session musst Du Dir auch keine Gedanken über die Serialisierung des ID-Arrays und über ein File-Locking machen. Das besorgt alles PHP für Dich.

              Harzliche Grüße vom Berg
              http://bergpost.annerschbarrich.de

              Tom

              --
              Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
              Nur selber lernen macht schlau
              Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

              1. Hi,

                ok ich glaub damit hab ich alles was ich brauche. Danke euch allen und wen es interessiert www.deutschlandquiz.de.vu   allerdings noch ohne verbesserte "zufallsausgabe"

                Michael

                1. Hello,

                  http://www.deutschlandquiz.de.vu

                  Schöne Idee.
                  Leider bekomme ich immer nur den Friedhof zu Gesicht, egal was ich mache...

                  Harzliche Grüße vom Berg
                  http://bergpost.annerschbarrich.de

                  Tom

                  --
                  Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                  Nur selber lernen macht schlau
                  Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

                  1. Hi!

                    http://www.deutschlandquiz.de.vu

                    Schöne Idee.
                    Leider bekomme ich immer nur den Friedhof zu Gesicht, egal was ich mache...

                    Versuch mal ne Frage richtig zu beantworten ;-)

                    Grüße
                    Andreas

                    1. Hello,

                      http://www.deutschlandquiz.de.vu

                      Schöne Idee.
                      Leider bekomme ich immer nur den Friedhof zu Gesicht, egal was ich mache...

                      Versuch mal ne Frage richtig zu beantworten ;-)

                      Welche Fragen?
                      Ich bekomme gar keine Fragen gestellt.

                      Harzliche Grüße vom Berg
                      http://bergpost.annerschbarrich.de

                      Tom

                      --
                      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                      Nur selber lernen macht schlau
                      Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

                      1. Hi!

                        Versuch mal ne Frage richtig zu beantworten ;-)

                        Welche Fragen?
                        Ich bekomme gar keine Fragen gestellt.

                        "Zum Quiz" klicken...

                        Grüße
                        Andreas

                        1. Hello,

                          Welche Fragen?
                          Ich bekomme gar keine Fragen gestellt.

                          "Zum Quiz" klicken...

                          Habe ich schon dutzende Male gemacht.
                          Auf meinem Schäuble-Rechner geht das nicht mehr.

                          (Ich könnte ja schlauer werden davon und die neuen Gesetzt zielen doch auf organisierte Verblödung...)

                          Harzliche Grüße vom Berg
                          http://bergpost.annerschbarrich.de

                          Tom

                          --
                          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                          Nur selber lernen macht schlau
                          Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

            2. Hallo!

              Das mit der "Strichliste" wie oft etwas dran war oder so könnte das Problem lösen aber kennt ihr vielleicht noch ein einfacheres System, das dafür sorgt das die Fragen einerseits nicht immer in der gleichen Reihenfolge kommen und andererseits regelmäßig alle Fragen drankommen so das nach spätestens 2000 aufrufen alle 450 Fragen einmal vorkamen? Und möglichst keine öfter als 8 mal.

              Wie gesagt hast Du 2 Alternativen für die Strichliste:

              1. eine globale Liste für alle User (Daten in APC, DB der Textdatei speichern), oder
              2. je eine Liste für jeden User (Daten in Session speichern)

              Gerade bei einem Quiz würde ich unbedingt die 2. Variante empfehlen, denn bei einem Quiz ist es doch inakzeptabel, wenn der User dieselbe Frage mehrmals gestellt bekommt, womöglich 8 mal. Daher würde ich das etwa wo wie in meinem obigen Posting beschrieben probieren, und an Stelle der apc_* Funktionen $_SESSION verwenden: http://de.php.net/session

              Einfacher geht es meiner Ansicht nur, wenn Du immer die gleiche Reihenfolge verwendest. Dann kannst Du an Stelle des Array mit der Strichliste einfach einen Counter verwenden. Um eine serverseitige Speicherung kommst Du allerdings nicht herum. Es sei denn, Du bastelst die Links direkt so, dass man automatisch nacheinander auf Frage 0 - 450 kommt.

              Grüße
              Andreas

  2. Hi!

    »» Hier mal mein Quelltext falls da ein Fehler sein sollte
    »»
    »»      mt_srand(microtime()*1000000);
    »»      $zufall = mt_rand(0,450);

    Ist denke ich kein Fehler, Du willst vermutlich nur was anderes als eine Zufallszahl die rand()/mt_rand() liefert.

    »» Kennt jemand eine gute alternative?

    Wenn Dir die "Güte" der Zufallszahl nicht so wichtig ist und dafür mehr Gleichmäßigkeit willst, könntest Du eine Art "Gedächtnis" einbauen, in dem sich das Script merkt welche Zahlen es bereits ausgegeben hat. Z.B. so:

      
    <?php  
    $available_numbers = apc_fetch('available_numbers');  
    if (!$available_numbers) {  
      $available_numbers = range(0, 450);  
    }  
    $random_number = array_rand($available_numbers);  
    unset($available_numbers[$random_number]);  
    apc_store('available_numbers', $available_numbers);  
    echo 'random number: ', $random_number;  
    ?>  
    
    

    Hierbei habe ich jetzt zur Vereinfachung mal Funktionen des APC verwendet, um den Array serverseitig zu speichern. Alternativ kann man auch z.B. eine Textdatei oder Datenbank verwenden, um die Daten zu speichern. Wahrscheinlich ist serialize() hierfür ganz hilfreich.

    Bedenke aber, dass die erreichte Gleichmäßigkeit nur für die Gesamtheit der User gilt. Wenn Du gleichzeitig mit 500 anderen Leuten auf der Seite bist, merkst Du davon vermutlich nicht mehr viel in Deinem eigenen Browserfenster. Wenn Du es aus User-Sicht gleichmäßig haben willst, könntest Du den Array in einer Session speichern, somit hat jeder User sein eigenes Gedächtnis. Kommt halt drauf an was genau Du erreichen willst.

    Grüße
    Andreas

    PS: Mensch, war ja schon lange nicht mehr hier... ;-)

    1. PS: Mensch, war ja schon lange nicht mehr hier... ;-)

      Wir hatten dich schon vermisst.. Welcome back :)

      Viele Grüße!
      _ds

      --
      Celebrity-Doku-Soap, was zur Hölle..? Im Grunde sowas wie eine Homestory mit Playback.
      Medienrauschen, In Love: Henne. Hahn.
      1. Hi Dirk!

        PS: Mensch, war ja schon lange nicht mehr hier... ;-)

        Wir hatten dich schon vermisst.. Welcome back :)

        Danke, Danke!

        Ist sogar schon so lange her, dass das Zitieren nicht mehr richtig klappt, ich mein Passwort kaum noch wusste und ich sogar in der Hilfe nachgucken musste, wie das noch gleich mit <@title...> bzw. [code] funktioniert... ;-)

        Viele Grüße
        Andreas