Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Stazer

Alter Hase

  • »Stazer« ist der Autor dieses Themas

Beiträge: 468

Wohnort: Berlin

Beruf: Student

  • Private Nachricht senden

1

13.11.2013, 23:04

Unausgeglichene Wahrscheinlichkeit

Moin,

ich habe eine Frage bezüglich der Wahrscheinlichkeit.
Wenn ich mit der PHP-Funktion Rand ( 1 , 10 ) einen zufälligen Wert zwischen 1 - 10 generieren lassen, beträgt die Wahrscheinlichkeit für jedes Ereignis 1/10.
Meine Frage ist nun, wie ich diese Wahrscheinlichkeit für das Ereignis verschieben kann ( zum Beispiel 2/10 für die 1, 1/20 für die 2 und 3, und 1/10 für den Rest ).
Einerseits besteht die Möglichkeit mit mehreren If-Statements die Zahl zu prüfen und daraus die Wahrscheinlichkeit zu setzen, was ich jedoch für sehr umständlich halte.

Anhand einer Funktion die Wahrscheinlichkeit für ein Ereignis auszurechnen, funktioniert leider nicht ganz, da ich nie die passenden Funktionen finde.

Wie kann ich mein Problem lösen?

Freundliche Grüße
Stazer

2

13.11.2013, 23:35

z.B. durch Poisson-Verteilung. Gibt auch viele Beispiele online.

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

3

13.11.2013, 23:36

Du suchst den kleinsten gemeinsamen Nenner der verschiedenen Wahrscheinlichkeiten(wäre hier wohl 20) und wählst in als neuen Bereich für für die rand Funktion. Jede Ziffer von 1 bis 10 bekommt seinen Zähler zugewiesen, die seine Größe in diesem Bereich definiert. Die 1 bekommt also vier Zahlen zugewiesen, die 2 und 3 kriegen ein Feld und der Rest jeweils zwei.
Dann kannst du jede Ziffer durchgehen, immer seine Feldgröße addieren und wenn der Wert der Randfunktion in seinem Bereich liegt kannst du die Ziffer ausgeben.

Vielleicht gibt es noch einen eleganteren Weg, aber das ist mir dazu eingefallen.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

4

14.11.2013, 08:18

Ich habe mir da mal was ausgedacht.
Kürzer geht's wohl kaum:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
int RandomChoice(double[] probabilities)
{
    // Die Summe der Werte in "probabilities" muss 1 sein!
    
    double p = 0;
    double r = RandomNumberBetweenZeroAndOne();
    for (int i = 0; i < probabilities.Length - 1; ++i)
        if (r < (p += probabilities[i])) return i;
    
    return probabilities.Length - 1;
}


Kleines Testprogramm zum Nachvollziehen der Korrektheit:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;

namespace RandomTest
{
    class Program
    {
        private static Random rng = new Random();

        private static int RandomChoice(double[] probabilities)
        {
            // Die Summe der Werte in "probabilities" muss 1 sein!

            double p = 0;
            double r = rng.NextDouble();
            for (int i = 0; i < probabilities.Length - 1; ++i)
                if (r < (p += probabilities[i])) return i;

            return probabilities.Length - 1;
        }

        private static void Main(string[] args)
        {
            double[] probabilities = { 0.3, 0.4, 0.2, 0.05, 0.05 };
            int numSamples = 100000000;

            int[] count = new int[probabilities.Length];
            for (int i = 0; i < numSamples; ++i)
                ++count[RandomChoice(probabilities)];

            foreach (int n in count)
                Console.WriteLine((double)n / numSamples);
        }
    }
}


Ausgabe:

Quellcode

1
2
3
4
5
0,30000489
0,40006654
0,19993
0,05001256
0,04998601

Werbeanzeige