habe leider in der system.math nichts gefunden wo und unter was muss ich suchen
sollte so ne formel berechnen
im notfall würde die fakultät und der binomialkoffizient auch mit eigenen funktionen gehen
nur wie mach ich das mit der summe richtig
for schleife?
wer ne idee
Das musst du alles selbst implementieren. Ist ja aber nicht weiter schwer.
Du solltest dir aber unbedingt überlegen, wie genau du das Ergebnis wissen willst. Schon die Fakultät von 21 bringt Int64 zum Überlauf.
Da hilft entweder Double zu verwenden, wodurch du leichte Ungenauigkeiten verkraften musst, oder du suchst dir eine BigInteger Bibliothek für beliebig große ganze Zahlen (wie z.B. bei IronPython mitgeliefert).
Und du solltest so wenig wie möglich Fakultäten benutzen. Siehe die Definition von Wikipedia:
Wenn du double benutzt, wirst du wohl mit der Formel nach dem 1. = am günstigsten Fahren. Wenn du BigInteger benutzt, solltest du die Formel nach dem 2. = benutzen (da sonst gerundet wird).
Und beachte:
Wähle die Variante, wo der untere Teil kleiner ist.
e.f.q.
Aus Falschem folgt Beliebiges
Die Summe machst du mit einer for-Schleife.
Ein größeres Problem sehe ich jedoch bei den Fakultäten. Bereits 13! überschreitet den Zahlbereich von int, 21! den von long. Damit könntest du nur auf BigInts ausweichen, welcher aber wiederum sehr langsam sind.
Die Fließkommatypen sind auch nicht genau genug.
Ich würde mir eine eigene Methode schreiben, welche Zahlen als Dictionary ihrer Faktorpotenzen darstellt. Damit kannst du dann den Binominalkoeffizient durch Kürzen derselben darstellen.
Also:
// Dictionary<Faktor, Potenz>
public Dictionary<int, int> Fakultät( int Zahl )
{
Dictionary<int,int> intern;
if (Zahl == 0)
{
intern = new Dictionary<int, int>( 0 );
}
else
{
intern = new Dictionary<int, int>( Zahl );
for( int i = 1; i <= Zahl ; i++ )
{
intern[ i ] = 1;
}
}
return intern;
}
// ZusammenfassenModeEnum
public enum ZME : int
{
Multiplikation = +1;
Division = -1;
}
public Dictionary<int, int> Zusammenfassen( Dictionary<int, int> Z, Dictionary<int, int> N, ZME Mode )
{
Dictionary<int, int> intern = new Dictionary<int, int>( Z );
List<int> nullExponent = new List<int>();
foreach( KeyValuePair<int, int> kvp in N )
{
intern[kvp.Key] = ((intern.ContainsKey(kvp.Key)) ? intern[kvp.Key] : 0 ) + ((int)Mode * kvp.Value);
if (intern[kvp.Key] == 0)
nullExponent.Add( kvp.Key );
}
// x hoch null entfernen
foreach( int val in nullExponent )
intern.Remove( val );
}
public Dictionary<int, int> BinKoeff( int n, int k )
{
if (k > n)
throw new ArgumentException( "n >= k" );
// [n über k] = n! / (k! * (n-k!));
return Zusammenfassen( Fakultät(n), Zusammenfassen(Fakultät(k), Fakultät(n-k), ZME.Multiplikation), ZME.Division );
}
public Dictionary<int, int> Summenterm( int K, int G, int O, int i )
{
// summenterm = BinKoeff( K - O; i ) * BinKoeff( O; G - i ) / BinKoeff( K; G )
return Zusammenfassen( Zusammenfassen( BinKoeff( K - O, i ), BinKoeff( O, G - i ), ZME.Multiplikation ), BinKoeff( K, G ), ZME.Division );
}
public double Berechne( Dictionary<int, int> Zahl )
{
double intern = 1;
foreach( kvp<int, int> in Zahl)
{
intern *= Math.Pow( kvp.Key, kvp.Value );
}
return intern;
}
public double BerechneWahrscheinlichkeit( int K, int O, int G )
{
double intern = 0.0;
for( int i = 0; i <= G - 1; i++ )
{
intern += Berechne( Summenterm( K, G, O, i ) );
}
return 100*i;
}
Ungetestet, Aufruf per BerechneWahrscheinlichkeit( K, O, G ).
EDIT: Code angepasst
muss grad mal abchecken wie gross die werte überhaupt werden können
danke für die antworten
Normalerweise berechnet man solche Terme logarithmisch, dann sind die grossen Zahlen kein Problem (und exp/ln kürzt sich praktischerweise oft weg). Also:
(a1a2)/(b1b2) = exp(ln(a1) + ln(a2) - ln(b1) - ln(b2))
Der Binomialkoeffizient ist übrigens in Math.NET Iridium fertig implementiert:
das ist ja wirklich ein problem hab ich mir gar nicht gedacht muss mir wirklich was
überlegen vieleicht fällt mir ja nohc was ein
aber 52! oder 50! ist schon ne wirklich große zahl
naja danke
52! = 80658175170943878571660636856403766975289505440883277824000000000000
ln(52!) = 156.3608363
Wie gesagt: Du must für deine Formel keine einzige Fakultät tatsächlich berechnen...