Feedback

C# - Zufallszahen mit verschiedenen Wahrscheinlichkeiten

Veröffentlicht von am 01.01.2015
(0 Bewertungen)
Mit dieser Klasse kann man Zufallszahlen mit verschiedenen Wahrscheinlichkeiten erzeugen.
Bsp.:
1 ==> 0.4
2 ==> 0.3
3 ==> 0.3
ACHTUNG! Man sollte nicht alle Wahrscheinlichkeiten angeben, auch wenn sie in der Summe 1 ergeben. Bei mir ist ein Wert vorgekommen, der nahe 0 war. Dieser Fehler kann auftreten. Um das zu vermeiden sollte höchstens alle Wahrscheinlichkeiten eintragen, außer eine. Die Wahrscheinlichkeit wird für die übrigen Zahlen automatisch ermittelt und gleichmäßig auf die übrigen Zahlen aufgeteilt.
Im Beispiel würde es dann ausreichen, die 1 anzugeben. Für 2, 3 bleiben 0.6, also für jeden 0.3
GFU-Schulungen  [Anzeige]

VB.NET Aufbau

Sie verfügen nach der Schulung über fundierte Kenntnisse in der Arbeit mit objektorientierten Modellen in VB.NET und können wiederverwendbare Komponenten eigenständig erzeugen.

JavaScript für .NET-Entwickler

Sie sind .NET-Entwickler und nun stehen Sie vor der Aufgabe, JavaScript in Ihre Arbeit einzubinden. Die Schulung vermittelt Ihnen die JavaScript Grundlagen und die Funktionen der Scriptsprache. Sie wissen, wie objektorientierte Programmierung in JavaScript funktioniert und lernen abschließend Best Practicies Fälle kennen.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassLibrary1
{
    public class RandomP
    {
        System.Random rnd = new System.Random();
        public RandomP(List<KeyValuePair<int, double>> probabilities, int min, int max)
        {
            double P = 1;                                                                                                      //Restwahrscheinlichkeit
            int[] Keys = new int[probabilities.Capacity];
            int iL1 = 0;
            foreach (KeyValuePair<int, double> el in probabilities)
            {
                P -= el.Value;
                Keys[iL1] = el.Key;
                iL1++;
            }
            if (P < 0 || ((max - min + 1) == probabilities.Capacity && P > 0))
            { throw new Exception("Die Summe aller Wahrscheinlichkeiten muss 1 betragen!"); }
            else if (P > 0 && P < 1)
            {
                double PKey = P / (max - min - probabilities.Capacity);                                                        //Einzelwahrscheinlichkeit für übrige Zahlen
                List<KeyValuePair<int, double>> unsorted = new List<KeyValuePair<int, double>>(max - min + 1) { };
                for (int i = 0; i != unsorted.Capacity; i++)
                {
                    if (Keys.Contains(min + i))
                    {
                        int iL2 = 0;
                        foreach (KeyValuePair<int, double> el in probabilities)
                        {
                            if (el.Key == min + i)
                            { break; }
                            iL2++;
                        }
                        unsorted.Insert(i, new KeyValuePair<int, double>(min + i, probabilities[iL2].Value));
                    }
                    else
                    {
                        unsorted.Insert(i, new KeyValuePair<int, double>(min + i, PKey));
                    }
                }
                Probabilities = unsorted;
            }
            else { Probabilities = probabilities; }
            Comparer<int, double> compare = new Comparer<int, double>();
            Probabilities.Sort(compare);                                                                                        //Liste sortieren
        }

        List<KeyValuePair<int, double>> Probabilities
        { get; set; }

        public int NextInt()                                                                                                    //Zufallszahl bestimmen
        {
            double p = rnd.NextDouble();
            double cummulativ = 0;
            int Out = 0;
            foreach (KeyValuePair<int, double> el in Probabilities)
            {
                cummulativ += el.Value;
                if (p < cummulativ)
                {
                    Out = el.Key;
                    break;
                }
            }
            return Out;
        }

        class Comparer<TKey, TValue> : IComparer<KeyValuePair<TKey, TValue>> where TValue : IComparable
        {
            public int Compare(KeyValuePair<TKey, TValue> x, KeyValuePair<TKey, TValue> y)
            {
                if (x.Value == null)
                {
                    if (y.Value == null)
                    { return 0; }
                    else
                    { return -1; }
                }
                else
                {
                    if (y.Value == null)
                    { return 1; }
                    else
                    {
                        return x.Value.CompareTo(y.Value);
                    }
                }
            }
        }
    }
}

Abgelegt unter Zufall, Random, Wahrscheinlichkeit.

2 Kommentare zum Snippet

Gwinn schrieb am 08.01.2015:
Hey,
das mit den sich wiederholenden zahlen kannst du einfach vermeiden, indem du 'rnd' als Feld deiner Klasse einmal erstellst und nicht jedes Mal in der Funktion NextInt()...
Fuzzi59 schrieb am 09.01.2015:
Stimmt die systemeigene Zufallsklasse (Random) muss global sein und nicht jedes mal neu erstellt werden. Danke für den Hinweis, ich werde es gleich ändern.
 

Logge dich ein, um hier zu kommentieren!