Probleme mit gewichteter Verteilung

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Probleme mit gewichteter Verteilung

    Moin.

    Ich hab folgende Funktion:
    PHP-Code:
    srand ((double) microtime() * 1000000);

    //Array anlegen: die Werte als Indizes, Gewichte als Werte.
    $a = array (1=>4,2=>3,3=>3,4=>2,5=>2,6=>2);
    //Dann holst du die Summe aller Gewichte mit
    $x array_sum ($a);
    //Zufallszahl ermitteln:
    $r floor(rand (0,$x));
    // und raussuchen, welcher Wert damit gemeint ist:
    $s 0;
    for (
    reset($a); list($z$w) = each($a); )
    {
      
    $s+=$w;             // bisherige Summe ums aktuelle Gewicht erhoehen
      
    if ($s>$r) break;   // Abbruch wenn Gewichtsumme>Zufallszahl
    }
    // und ausgeben
    echo $z
    Die hat Berni mal vor ewigen Zeiten mal hier in den Codeschnipseln gepostet.

    Das ganze läuft ohne Problem, wenn alle Array-Elemente unterschiedliche Wichtungen haben.

    Hab ich aber mehrere Elemente mit der gleichen Wichtung, wird immer nur das im Array als erstes vorkommende Element genommen.

    Wie kann man das abändern, dass auch wenn mehrere Elemente die gleiche Wichtung haben eines daraus zufällig gewählt wird?

    Danke schonmal im Voraus.
    it's not a bug,
    it's a feature!

  • #2
    mhmm ... ich versteh nicht ganz, was du meinst.

    PHP-Code:
    <pre>
    <?
    function random()
    {
        srand ((double) microtime() * 1000000);
        //Array anlegen: die Werte als Indizes, Gewichte als Werte.
        $a = array (1=>8,2=>8,3=>3,4=>2,5=>2,6=>2);
        //Dann holst du die Summe aller Gewichte mit
        $x = array_sum ($a);
        //Zufallszahl ermitteln:
        $r = floor(rand (1,$x));
        // und raussuchen, welcher Wert damit gemeint ist:
        $s = 0;
        for (reset($a); list($z, $w) = each($a); )
        {
            $s+=$w;             // bisherige Summe ums aktuelle Gewicht erhoehen
            if ($s>$r)
                break;   // Abbruch wenn Gewichtsumme>Zufallszahl
        }
        // und ausgeben
        return $z;
    }
    $k=0;
    for($i=0; $i<1000; $i++)
    {
        $o1 = random();
        if(!is_null($o1))
        {
            $out[$k] = $o1;
            $k++;
        }
    }
    print_r(array_count_values($out));
    ?>
    ... habs zu testen mal in eine fkt gepackt. die ausgabe scheint mir wie erwartet:
    Code:
    Array
    (
        [1] => 333
        [2] => 327
        [3] => 114
        [4] => 68
        [5] => 64
        [6] => 64
    )
    ... zuwenig durchläufe?
    Kissolino.com

    Kommentar


    • #3
      Hab zur Zeit keine Möglichkeit zu testen.

      Code:
      Array
      (
          [1] => 333
          [2] => 327
          [3] => 114
          [4] => 68
          [5] => 64
          [6] => 64
      )
      Nochmal mein Problem.
      Bei dem obigen Array, sind die Elemente 5 und 6 am wahrscheinlichsten.
      Ich möchte immer nur ein Element auslesen.
      Bei der Ursprungsversion würde aber immer nur Element 5 ausgwählt werden. Element 6 bekam ich nie als Ergebnis zurückgeliefert. Ich möchte aber, da die beiden Elemente die gleiche Wahrscheinlichtkeit besitzen, auch ungefähr gleich oft die beiden Elemente als Ergebnisse zurückgeliefert bekommen.

      Was du jetzt mit deiner for-Schleife machen willst kapier ich da nicht so ganz.

      Ich hoffe mein Problem ist jetzt etwas leichter zu verstehen.
      it's not a bug,
      it's a feature!

      Kommentar


      • #4
        Original geschrieben von XGremliN
        Was du jetzt mit deiner for-Schleife machen willst kapier ich da nicht so ganz.
        vielleicht hatte ich keinen bock, das script 1000x händisch aufzurufen und mir die ergebnisse zu merken?
        Bei dem obigen Array, sind die Elemente 5 und 6 am wahrscheinlichsten.
        nein, am unwahrscheinlichsten, weil 4,5 und 6 den niedrigsten wert haben
        Ich möchte immer nur ein Element auslesen.
        ohne schleife kommt ja auch nur einer zurück

        Bei der Ursprungsversion würde aber immer nur Element 5 ausgwählt werden. Element 6 bekam ich nie als Ergebnis zurückgeliefert. Ich möchte aber, da die beiden Elemente die gleiche Wahrscheinlichtkeit besitzen, auch ungefähr gleich oft die beiden Elemente als Ergebnisse zurückgeliefert bekommen.
        womit wir wieder bei der häufigkeit der aufrufe wären ... wer versteht jetzt wen nicht?
        Kissolino.com

        Kommentar


        • #5
          Na gut. Ich werds heut abend mal testen.

          Danke erstmal für deine Mühe.
          it's not a bug,
          it's a feature!

          Kommentar


          • #6
            Es funktioniert doch!

            Ich hab nur den Array mit Werten gefüllt, die ich aus einer Datenbank geholt habe und habe da einen Fehler gemacht, deshalb tauchte der eine Wert garnicht erst im Array auf.
            Deshalb habe ich auch nie dieses Element zurückbekommen.

            Danke nochmals.
            it's not a bug,
            it's a feature!

            Kommentar

            Lädt...
            X