Zum Inhalt springen
  • Würfelsimulation


    Tellur

    *buddel buddel*

    Wollte keinen neuen Thread aufmachen, das dieser hier auch tut.

    Ich wurde vor kurzem gefragt, wies so mit Statistik und den beiden Würfelmethoden aussieht... Tja, also habe ich mich mal hingehockt und eine kleine Simulation geschrieben *g*

    (Die Simulation wird mit dem Programm Matlab für >>n<< "Messreihen" durchgeführt; ich habe 100000 genommen).

     

    Was kann die Simulation?

    Es werden (in unterschiedlichen Scripts) beide Würfelmethoden (Beste von 2 für jeden Wert, sofort zuteilen - kurz 12W; die 6 besten aus 9 - kurz 9W) simuliert und je 3 Histogramme erzeugt. Dabei wird die Minimalwertesumme von 350 berücksichtigt. Das erste Histogramm ist logischerweise der (arithmetische) Mittelwert (Summe/6). Die beiden anderen sind Primär- und Sekundärattribut des gewünschten Charakters. Für den 9er Wurf ist das natürlich sehr einfach, da einfach die beiden höchsten Werte genommen wurden.

    Beim 12er Wurf musste ich etwas "tricksen". Das Primärattribut wird "zufällig" aus den besten beiden Werten genommen, das Sekundärattribut aus den besten 4, wobei 2 und 3 den Fokus haben (Wahrscheinlichkeit: je 16,6% 1 und 4, je 33,3% 2 und 3); natürlich kann in jeder Messreihe das Primärattribut nicht gleichzeitig das Sekundärattribut sein.

     

    Kommen wir zur Auswertung auf 100.000 "Messungen":

    Die Plots wurden mit OriginPro 8 erstellt.

    [PRBREAK][/PRBREAK]

    Mittelwert

    9er Wurf:

    g_9_hist.png

     

    12er Wurf:

    g_12_hist.png

     

    Was hier auffällt (am Orginal sieht mans natürlich besser), ist dass einige Werte verboten sind - und zwar im unteren Teil mehr als im oberen.

    Unterhalb von 68 (Mittelwert) sind für die 1. Dezimalstelle nur 0,3,5,8 zulässig.

    Oberhalb von 68 0,2,3,5,7,8

    Der Grund hat etwas mit dem durch 6 teilen bei der Bildung des Mittelwerts zu tun. Aber ich bin zu faul, mathematisch zu begründen, warum nur diese Stellen zugelassen werden....

    Die Histogramme wurden mit einem Gauß gefittet.

    Der Mittelwert ist beim 12W etwas höher (um etwa 0,5), dafür ist dort die Peakbreite etwas kleiner (um 0,7).

    Da das FWHM (Full Width at Half Maximum) auf der linken Seite schon im "verbotenen" Bereich liegt spielt es eigentlich keine Rolle für den Mittelwert. Mit der 12W Methode bekommt man im Mittel einen minimal größeren Mittelwert (was nen Satz...), dafür ist beim 9W die Chance auf einen etwas größeren Mittelwert minimal größer (die Chance auf einen schlechteren Wert wird großteils durch den Cut bei 58,3 ausgeglichen).

     

    Primärattribut

    Primärattribute.png

     

    Hier gibt es nichts besonderes: natürlich hat man im 9er Wurf immer den besten Wert zur Verfügung. Etwas genauer:

    in 44,5% der Fälle hat man beim 9er Wurf einen Wert von 96 oder Höher. In immerhin noch 30,9% zwischen 90 und 95.

    Im Vergleich beim 12W: 32,3% (96-100) und 30% (90-95)

     

    Sekundärattribut

    Sekundärattribut.png

     

    Auch hier: der verlauf ist nicht weiter verwunderlich. Allgemein sind die Sekundärattribute beim 9W höher.

    Wie sieht es mit den Wahrscheinlichkeiten aus, einen Wert in den Bereichen 90-95 bzw. 96-100 zu haben?

    Für den 9er Wurf: 24,5% (90-95) und 9,2% (96-100)

    Für den 12er Wurf: 15,5% (90-95) und 10% (96-100)

     

    Hier kann man schon eine Tendenz erkennen: Ein Tertiärattribut wird wahrscheinlich beim 12er Wurf schon besser ausfallen.

    Ein etwas ausgefeilteres System (programmiertechnisch etwas aufwändig. Man müsste wirklich für jeden Wurf eine ganze Auswahl an Select Anweisungen machen, dann könnte man das ganze besser simulieren. Z.B. würde jeder Spieler bei einem 1. Wurf ab 96 als Primärattribut setzen) für den 12W würde die Prozentsätze etwas anheben, insbesondere für das Sekundärattribut. Ich würde mir für ein etwas intelligenteres System einen Zuwachs von je 2% für das Primärattribut bzw. 5% für das Sekundärattribut erwarten.

     

    Schauen wir uns noch kurz die Wahrscheinlichkeit an, dass beide Attribute in einem gewissen Bereich sind:

     

    9W:

    Primärattribut und Sekundärattribut in 96-100: 4,1%

    Primärattribut aus 96+, Sekundärattribut aus 90-95: 10,9%

    Primärattribut aus 96+, Sekundärattribut unter 90: 29,5%

    Primärattribut und Sekundärattribut aus 90-95: 7,6%

    Primärattribut aus 90-95, Sekundärattribut unter 90: 20,5%

    Beide unter 90: 24,6%

    (Summe etwas unter 100% => Rundungsfehler)

     

    12W:

    Primärattribut und Sekundärattribut in 96-100: 3,23%

    Primärattribut aus 96+, Sekundärattribut aus 90-95: 5%

    Primärattribut aus 96+, Sekundärattribut unter 90: 24,06%

    Primärattribut und Sekundärattribut aus 90-95: 4,65%

    Primärattribut aus 90-95 und Sekundärattribut aus 96+: 3%

    Primärattribut aus 90-95, Sekundärattribut unter 90: 22,35%

    Primärattribut aus unter 90, Sekundärattribut aus 96+: 3,77%

    Primärattribut unter 90, Sekundärattribut aus 90-95: 4,65%

    Beide unter 90: 28,09%

    (Summe etwas unter 100% => Rundungsfehler)

     

    Fazit: Ich müsste das ganze noch mit einem Tertiärattribut und einem besseren System für die Wertzuteilung beim 12W arbeiten.

    Ich würde jetzt schätzen, dass bei einem Charakter, der auf 3 Attributen basiert (Kampfzauberer vor allem) der 12W bessere Charaktere liefern kann, wohingegen der 9W definitiv für 2 Attributcharatere (hauptsächlich alle reinen Zauberer) besser geeignet ist.

     

    Sollte wer Fehler finden (*zu Solwac schiel*) - bitte melden!


    Benutzer-Feedback

    Empfohlene Kommentare



    Tellur

    Geschrieben

    Ah ok, da man ja nicht untern den 12 Würfen die 6 höchsten zufällig verteilt sondern ja jeweils nur 2 Werte hat stimmt meine Vermutung natürlich nicht.

    Da ihr ja bewiesen habt, dass die 12 Methode sinnlos ist, welchen alternativen Vorschlag habt ihr zum auswürfeln der den Geist der 12 Methode trägt, zumindestens den den ich darin gesehn habe (Charakter mit statistisch höheren Grundwerten aber ungeignet für Wunschcharaktere und potentiell ungünstigere Verteilung der höchsten Werte).

     

    Dabei sollte das Balancing mit 6/9 passen, aber eine wirkliche Alternative dazu sein.

     

    Da das Thema ja wieder aufgegriffen wurde...

     

    Ich habe gerade einen kleinen Code in MatLab geschrieben um eine Verbesserung zu finden. Da ich inzwischen die Stärken und Schwächen besser kenne, dauert eine Berechnung mit 1,2*10^7 Zufallszahlen nur noch wenige Sekunden.

    Zunächst habe ich mir angeschaut, was passiert, wenn man die Mindestpunktezahl auf 375, 380, 390 oder 400 anhebt bzw. die Mindestpunkte bei 350 lässt, allerdings die schlechteste zu behaltene Zahl mit der besten zu verwerfenden Zahl tauscht. Das Ergebnis:

     

    m350 = 67.0036

    m375 = 71.9719

    m380 = 72.3796

    m390 = 73.2500

    m400 = 74.1870

     

    Für den Tausch das ganze etwas differenzierter:

     

    Der Mittelwert über alle 6 finalen Werte:

    mswap = 73.8105

    m9 = 65.3323 (6 aus 9)

     

    Der Mittelwert des kleinsten behaltenen Werts ohne Tausch:

    mmin = 37.9269

    mit Tausch:

    mminswap = 50.8541

    im 9er System:

    mmin9 = 45.2792

     

    Also, das Tauschsystem ist mir persönlich etwas zu stark. Fast 60 Attributpuntke mehr und auch noch einen um fast 5 besseren schlechteren Wert...

    Reduziert man beim Tauschen die Mindestpunktezahl auf 340 wirds etwas besser. Der Minimalwert ändert sich kaum, allerdings hat die 12er mit Tausch Methode dann nur etwa 42 Punkte mehr.

     

     

    Für die Interessierten der MatLab Code:

    clear all
    n=1E6; % n Stichproben
    Zz=round(1+99.*rand(n,6,2)); % Erzeuge n*6*2 Sätze an Zufallszahlen zwischen 1 und 100
    Zz=sort(Zz,3); % Sortiere so, dass Z(x,y,2)>Z(x,y,1)
    Zz(:,:,2)=sort(Zz(:,:,2),2,'descend'); % Sortiere die zu behaltenden 6er-Tupel absteigend
    Zz(:,:,1)=sort(Zz(:,:,1),2,'ascend'); % Sortiere die zu verwerfenden 6er-Tupel aufsteigend
    Zs=sum(Zz(:,:,2),2); % Bilde die Summen über die behaltenen Tupel
    k350=find(Zs>349); % Finde Indices mit Summe >350
    Zs=sort(Zs); % Sortiere Summen Aufsteigend
    % Finde den ersten Index für den Gilt: Summe > 375, 380, 390 bzw. 400
    % und bilde den Mittelwert
    
    k375=find(Zs>374,1);
    k380=find(Zs>379,1);
    k390=find(Zs>389,1);
    k400=find(Zs>399,1);
    m350=mean(Zs(k350))./6
    m375=mean(Zs(k375:n))./6
    m380=mean(Zs(k380:n))./6
    m390=mean(Zs(k390:n))./6
    m400=mean(Zs(k400:n))./6
    mmin=mean(Zz(k350,6,2))
    
    Zz(:,6,2)=Zz(:,6,1); % Tausche den kleinsten behaltenen mit dem größten verworfenen.
    Zz(:,:,2)=sort(Zz(:,:,2),2,'descend'); % Sortiere nochmal
    Zs=sum(Zz(:,:,2),2); % Bilde wieder die Summen
    k=find(Zs>349); % Finde alle Einträge mit mindestens Summe=350
    k2=find(Zs>239); % Finde alle Einträge mit mindestesns Summe=340
    mminswap=mean(Zz(k,6,2)) % Berechne den Mittelwert des kleinsten Werts.
    mswap=mean(Zs(k))./6 % Berechne allgemeinen Mittelwert.
    mminswap2=mean(Zz(k2,6,2)) % Berechne den Mittelwert des kleinsten Werts für Summe=340
    mswap2=mean(Zs(k2))./6 % Berechne allgemeinen Mittelwert für Summe = 340
    
    % Berechne alles wichtige für 6 aus 9
    clear Zz
    Z9=round(1+99.*rand(n,9));
    Z9=sort(Z9,2,'descend');
    Z9s=sum(Z9(:,1:6),2);
    k9=find(Z9s>349);
    meanmin9=mean(Z9(k9,6))
    m9=mean(Z9s(k))./6
    

    Tarai

    Geschrieben

    Was nützt mir das stärkere System, wenn bei Zaubertalent einen hohen Wert möchte, aber theoretisch nur 67 erhalte?

     

    Gerade für zwei gute Werte in ganz konkreten Hauptattributen, wähle ich lieber aus, anstatt zehn bis zwanzig mal neu zu würfeln. :D

    Tellur

    Geschrieben

    Was nützt mir das stärkere System, wenn bei Zaubertalent einen hohen Wert möchte, aber theoretisch nur 67 erhalte?

     

    Gerade für zwei gute Werte in ganz konkreten Hauptattributen, wähle ich lieber aus, anstatt zehn bis zwanzig mal neu zu würfeln. :D

     

    Das soll ja auch weiterhin der Sinn des 6 aus 9 Systems bleiben. :rolleyes:

    Mit 6 aus 12 erstellt man Überaschungsei-Charaktere. Man schaut mal was kommt und lässt sich dazu was einfallen. Damit diese Charaktere durchschnittlich etwas bessere Werte haben als ihre 6 aus 9 Kollegen (die dafür nach allen Regeln der Kunst optimiert werden können) habe ich die zwei Möglichkeiten vorgestellt.

    Tony

    Geschrieben

    Moin zusammen!

     

    Ich habe mal exakt berechnet, wie der Durchschnitt der Werte aussieht, wenn man für jeden Wert 2 mal Würfelt und den besseren nimmt, und dabei Gesamtwerte von unter 350 verwirft.

    Dazu habe ich ein Programm geschrieben, dass sämtliche Fälle durchgeht und dabei Anzahl der Fälle und Summe aller Gesamtwerte berechnet.

     

    Hier das Ergebnis:

    346524693842282048565733500 / 821069192330201181675000 = 422,04079397844911428487062023303707

    422,04079397844911428487062023303707 / 6 = 70,340132329741519047478436705506

     

    Die genäherten Ergebnisse von 422 und 70,33 sind damit also sehr gut gewesen.

     

    Die Berechnungsdauer lag übrigens bei 69 Minuten.

     

    Gruß

    Tony

    • Like 2
    Tony

    Geschrieben

    Für 6 aus 9 habe ich jetzt auch mal ein Programm geschrieben. (Hab im Zug nicht immer Lust zu arbeiten und da mach ich halt mal so komische Dinge...)

    Es rechnet gerade mal 5 Sekunden und kommt auf folgendes Ergebnis:

     

    3909914035784388288 / 9281286030040641 = 421,2685637668325918730415591592

    421,2685637668325918730415591592 / 6 = 70,211427294472098645506926526533

     

    Gruß

    Tony

    • Like 1
    Tony

    Geschrieben (bearbeitet)

    Hier der c# Programmcode:

     

    using System;
    
    namespace Würfel
    {
       class Program
       {
           private static decimal _anz, _sum;
    
           static void Main()
           {
               var start = DateTime.Now;
               //Schnitt12();
               Schnitt6Aus9();
               var end = DateTime.Now;
               Console.WriteLine("Dauer: " + (end - start));
               Console.WriteLine(_sum + " / " + _anz + " = " + _sum / _anz);
               Console.WriteLine(_sum / _anz / 6);
               Console.ReadLine();
           }
    
           static void Schnitt12()
           {
               for (var st = 0; ++st <= 100; )
               {
                   var hSt = (st << 1) - 1;
                   var gs = 0;
                   var stGs = st;
                   while (++gs <= 100)
                   {
                       var hGsSt = ((gs << 1) - 1) * hSt;
                       var stGsGw = ++stGs;
                       var gw = 49 - stGsGw;
                       if (gw <= 0) gw = 0;
                       else stGsGw += gw;
                       while (++gw <= 100)
                       {
                           var hGwGsSt = ((gw << 1) - 1) * hGsSt;
                           var stGsGwKo = ++stGsGw;
                           var ko = 149 - stGsGwKo;
                           if (ko <= 0) ko = 0;
                           else stGsGwKo += ko;
                           while (++ko <= 100)
                           {
                               var hKoGwGsSt = ((ko << 1) - 1) * hGwGsSt;
                               var stGsGwKoIn = ++stGsGwKo;
                               var i = 249 - stGsGwKoIn;
                               if (i <= 0) i = 0;
                               else stGsGwKoIn += i;
                               while (++i <= 100)
                               {
                                   var zAnz = 0L;
                                   var zSum = 0L;
                                   var zt = Math.Max(0, 349 - ++stGsGwKoIn);
                                   while (++zt <= 100)
                                   {
                                       var hZtInKoGwGsSt = ((zt << 1) - 1) * ((i << 1) - 1) * (long)hKoGwGsSt;
                                       zAnz += hZtInKoGwGsSt;
                                       zSum += hZtInKoGwGsSt * (stGsGwKoIn + zt);
                                   }
                                   _anz += zAnz;
                                   _sum += zSum;
                               }
                           }
                       }
                   }
               }
           }
    
           private const int StGleichGs = 1;
           private const int GsGleichGw = 2;
           private const int GwGleichKo = 4;
           private const int KoGleichIn = 8;
           private const int InGleichZt = 16;
    
           private static readonly int[] Permutationen = new[]
           {
               720, // 00 Alle verschieden
               360, // 01 St = Gs
               360, // 02 Gs = Gw
               120, // 03 St = Gs = Gw
               360, // 04 Gw = Ko
               180, // 05 St = Gs, Gw = Ko
               120, // 06 Gs = Gw = Ko
                30, // 07 St = Gs = Gw = Ko
               360, // 08 Ko = In
               180, // 09 St = Gs, Ko = In
               180, // 10 Gs = Gw, Ko = In
                60, // 11 St = Gs = Gw, Ko = In
               120, // 12 Gw = Ko = In
                60, // 13 St = Gs, Gw = Ko = In
                30, // 14 Gs = Gw = Ko = In
                 6, // 15 St = Gs = Gw = Ko = In
               360, // 16 In = Zt
               180, // 17 St = Gs, In = Zt
               180, // 18 Gs = Gw, In = Zt
                60, // 19 St = Gs = Gw, In = Zt
               180, // 20 Gw = Ko, In = Zt
                90, // 21 St = Gs, Gw = Ko, In = Zt
                60, // 22 Gs = Gw = Ko, In = Zt
                15, // 23 St = Gs = Gw = Ko, In = Zt
               120, // 24 Ko = In = Zt
                60, // 25 St = Gs, Ko = In = Zt
                60, // 26 Gs = Gw, Ko = In = Zt
                20, // 27 St = Gs = Gw, Ko = In = Zt
                30, // 28 Gw = Ko = In = Zt
                15, // 29 St = Gs, Gw = Ko = In = Zt
                 6, // 30 Gs = Gw = Ko = In = Zt
                 1, // 31 St = Gs = Gw = Ko = In = Zt
           };
    
           static void Schnitt6Aus9()
           {
               for (var st = 101; --st > 0; )
               {
                   var stGleichGs = StGleichGs;
                   for (var gs = st + 1; --gs > 0; )
                   {
                       var gsGleichGw = GsGleichGw;
                       for (var gw = gs + 1; --gw > 0; )
                       {
                           var stGsGw = st + gs + gw;
                           if (350 - stGsGw - 3 * gw > 0) break;
                           var gwGleichKo = GwGleichKo;
                           for (var ko = gw + 1; --ko > 0; )
                           {
                               var sum = 0L;
                               var anz = 0L;
                               var stGsGwKo = stGsGw + ko;
                               if (350 - stGsGwKo - (ko << 1) > 0) break;
                               var koGleichIn = KoGleichIn;
                               for (var i = ko + 1; --i > 0; )
                               {
                                   var stGsGwKoIn = stGsGwKo + i;
                                   if (350 - stGsGwKoIn - i > 0) break;
                                   var inGleichZt = InGleichZt;
                                   for (var zt = i + 1; --zt > 0; )
                                   {
                                       var stGsGwKoInZt = stGsGwKoIn + zt;
                                       if (stGsGwKoInZt < 350) break;
                                       var a = zt * zt * zt * Permutationen[stGleichGs | gsGleichGw | gwGleichKo | koGleichIn | inGleichZt];
                                       anz += a;
                                       sum += (long)a * stGsGwKoInZt;
                                       inGleichZt = 0;
                                   }
                                   koGleichIn = 0;
                               }
                               _anz += anz;
                               _sum += sum;
                               gwGleichKo = 0;
                           }
                           gsGleichGw = 0;
                       }
                       stGleichGs = 0;
                   }
               }
           }
       }
    }
    

     

    Wenn jemand da durchsteigt und das verifiziert bzw. einen Fehler findet, wäre das schön...

     

    Gruß

    Tony

    Bearbeitet von Tony
    Kommentar hinzugefügt
    • Like 2



    Erstelle ein Benutzerkonto oder melde Dich an, um zu kommentieren

    Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können

    Benutzerkonto erstellen

    Neues Benutzerkonto für unsere Community erstellen. Es ist einfach!

    Neues Benutzerkonto erstellen

    Anmelden

    Du hast bereits ein Benutzerkonto? Melde Dich hier an.

    Jetzt anmelden

×
×
  • Neu erstellen...