Ankündigung

Einklappen
Keine Ankündigung bisher.

Chancen Berechnung

Einklappen

Neue Werbung 2019

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

  • Chancen Berechnung

    Hallo Liebes php.de Forum,

    wünsche euch erst mal eine Frohes neues Jahr.

    Die funktion hat eine liste mit items und ihrer generations chance, und erstellt eine 2 liste die mit den items so oft gefüllt wird wie ihre chance ist.
    Nun wird mittels mt_rand eine zahl zwischen 0 und 100 generiert und mit dieser zahl wird dann das item aus der liste gewählt.

    Die funktion:
    PHP-Code:
        function randItem()
        {
            
    $items = [];
            
    $items["muni"] = 67;
            
    $items["reso"] = 12;
            
    $items["regu"] = 3;
            
    $items["gapa"] = 13;
            
    $items["nahp"] = 3;
            
    $items["lofi"] = 1;

            
    $items2 = [];
            foreach(
    $items as $key => $value)
            {
                for(
    $i 0$i<$value$i++) { $items2[] = $key; }
            }
            
    shuffle($items2);

            
    $x mt_rand(0100);

            return 
    $items2[$x];
        } 
    Zum beispiel:
    $items["muni"] = 67;
    hat eine 67% chance Generiert zu werden.

    $items2 enthält also 67 mal die value "muni" und 33 andere einträge.

    durch shuffle($items2) werden die einträge von $items2 per zufall angeordnet und durch $items2[$x] zurückgegeben.

    Beträgt die warscheinlichkeit das randItem() wirklich "muni" zurück gibt 67% und gibt es einen einfachen weg, weil das mit den 2 listen erscheint mir einwenig aufwendig, bzw. einen weg der Performanter ist.

    Mit freundlichen Grüßen Jack


  • #2
    So wie du das aufgebaut hast, wird dir dein Code einen Fehler werfen, wenn eine Zufallszahl ermittelt wird, die nicht in deinem Array vorkommt!

    Ich würde das so lösen (schnell runtergetippt, könnte man evtl. noch verbessern):

    PHP-Code:
    function randItem($items$p) {
        
    // Durchlaufe die Schleife bis der erste Eintrag gefunden wurde, der der Zufallszahl  entspricht.
        // Wurde die Zufallszahl nicht gefunden, verringere die Zahl um 1.
        
    while (true) {
            
    $item array_search($p$itemstrue);
            if (!
    $item$p--;
            else return 
    $item;
        }
    }
    $items = [];
    $items["muni"] = 67;
    $items["reso"] = 12;
    $items["regu"] = 3;
    $items["gapa"] = 13;
    $items["nahp"] = 3;
    $items["lofi"] = 1;

    // Shuffle items
    $random = [];
    $keys array_keys($items);
    shuffle($keys);
    foreach (
    $keys as $key) {
        
    $random[$key] = $items[$key];
    }

    echo 
    randItem($randomrand(199)); 
    Die Ausführungszeit für dieses Beispiel beim Aufruf der Funktion mit 1000 generierten Zufallszahlen liegt ungefähr im Bereich von 0.02 Sekunden.

    Nachtrag:
    Desweiteren hat dieser Beitrag auch nichts im Fortgeschrittenen Forum zu suchen!
    Siehe: https://www.php.de/forum/webentwickl...rf-hier-posten

    @Moderation bitte einmal verschieben, Danke.

    Kommentar


    • #3
      Eine bessere Lösung wäre, wenn du die Items in der Datenbank speicherst, dann könntest das Ganze einfach über eine SQL-Abfrage lösen.

      Beispiel (ungetestet):
      Code:
      SELECT `name` FROM `items` WHERE rating <= $res ORDER BY RAND() LIMIT 1

      Kommentar


      • #4
        PHP-Code:
        function randItem()
        {
        $items = [];
        $items["muni"] = 67// bei 1 - 67
        $items["reso"] = 12// bei 68 - 79
        $items["regu"] = 3// bei 80 - 82
        $items["gapa"] = 13// bei 83 - 95
        $items["nahp"] = 3// bei 96 - 98
        $items["lofi"] = 1// bei 99

        $random rand(1100);
        // $random = rand (1, array_sum($items));

        foreach($items as $key => $item)
        {
            if (
        $random <= $item)
            {
                return 
        $key;
            }
            
        $random -= $item;

        }
        ​​​​​​return null;
        /* da es nur 99% Wahrscheinlichkeit gibt dass etwas
        getroffen wird, verbleibt 1% für die Niete... Ergo "null"

        Falls es nicht Prozent , sondern Anteile/Wichtigen sein
        sollen, einfach oben die auskommen müssen Zeile
        für die Bestimmung von $random verwenden */

        Kommentar


        • #5
          [MOD: verschoben]

          Kommentar


          • #6
            Es bietet sich an das Array mit den Wichtungen (hier $items in #1) einer Funktion als Parameter zu übergeben. Eine solche Funktion hab ich mal vor Jahren erstellt (Algorithmus ähnlich #4). Für einen ersten Test ist es zweckmässig eine Häufigkeitsverteilung zu erzeugen.
            PHP-Code:
            $weights = [
              
            "muni" => 67,
              
            "reso" => 12,
              
            "regu" => 3,
              
            "gapa" => 13,
              
            "nahp" => 3,
              
            "lofi" => 1,
            ];

            $frequency array_fill_keys(array_keys($weights), 0);

            for(
            $i=0;$i<1000;$i++){
              
            $key statistic::weightRandom($weights);
              ++
            $frequency[$key];
            }

            debug::write($frequency); 
            Das Resultat ist ähnlich

            [10.01.2019 12:41:44,226][+802 μs](391k/414k) Debug::write "phpconsole.php" Line 18
            PHP-Code:
            array (
              
            'muni' => 677,
              
            'reso' => 119,
              
            'regu' => 25,
              
            'gapa' => 135,
              
            'nahp' => 33,
              
            'lofi' => 11,

            Die Zeit meine ich kann sich auch sehen lassen.


            Kommentar


            • #7
              Hatte etwas ähnliches letztens gesucht, hab darauf hin den folgenden Artikel gefunden. Die Funktion funktioniert ganz gut:
              https://rotering-net.de/tut/php-dwrand.html

              PHP-Code:
              function dw_rand ($space$errval false) {
               
              $res 1000000000;
               
              $rn mt_rand(0$res 1);

               
              $psum 0;
               foreach (
              $space as $element => $probability) {
                
              $psum += $probability $res;
                if (
              $psum $rn) return $element;
               }

               return 
              $errval;
              }

              $data = [
                 
              "muni" => 0.67,
                
              "reso" => 0.12,
                
              "regu" => 0.03,
                
              "gapa" => 0.13,
                
              "nahp" => 0.03,
                
              "lofi" => 0.01,
              ];


              echo 
              dw_rand($data); 

              Kommentar

              Lädt...
              X