Algorithmus für die Berechnung der Binomial-Koeffizienten
Brauche ich eine Möglichkeit, die Berechnung der Kombinationen ohne running out of memory. Hier ist, was ich habe, so weit.
public static long combination(long n, long k) //nCk
{
return (divideFactorials(factorial(n), ((factorial(k) * factorial((n - k))))));
}
public static long factorial(long n)
{
long result;
if (n <= 1) return 1;
result = factorial(n - 1) * n;
return result;
}
public static long divideFactorials(long numerator, long denominator)
{
return factorial(Math.Abs((numerator - denominator)));
}
Habe ich es markiert wie C#, aber die Lösung sollte idealerweise-unabhängigen Sprache.
- Diese zahlen werden als "Binomialkoeffizienten" und als ein sehr häufiges Objekt, die erschienen sind, bevor Sie in SO: stackoverflow.com/q/4256188/422353
- Welche Kombination genau versuchst du? Ist es einfach nCk, oder ist es etwas anderes? Ich bin nur gefragt, weil dein Kommentar am Anfang sagt "nCk" aber Ihr code nicht direkt berechnen.
- Ja, fügen Sie diese Zeile zu factorial():
if (n > 20) throw new OverflowException();
- Es ist einfach nCk.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einer der besten Methoden für die Berechnung der binomial-Koeffizienten, die ich gesehen habe vorgeschlagen, ist durch Mark Dominus. Es ist viel weniger wahrscheinlich zu überlaufen mit größeren Werten für N und K als einige andere Methoden.
Hier ist eine Lösung, die sehr ähnlich zu dem Bob Byran, aber prüft zwei weitere Voraussetzungen, um die Geschwindigkeit des Codes.
n == k
sollte wohl nicht da sein. Es ist eine Optimierung für einen statistisch seltenen Fall.Suchen Sie in Ihrer code, ist es kein Wunder, dass der Speicher ziemlich schnell. Ihre Methode
divideFactorials
ruft die Methode factorial und verwendet als argument den Unterschied "Zähler-Nenner". Dieser Unterschied ist sehr wahrscheinlich gehen zu werden sehr groß nach Ihren code und Sie werden stecken in einer sehr langen Schleife im faktoriellen Methode.Wenn es wirklich nur darum, nCk (was ich vermute, weil Ihr Kommentar in deinem code), verwenden Sie einfach:
Natürlich mit dieser Methode wird die Reichweite sehr schnell, weil eine lange nicht wirklich support sehr lange zahlen, also n und k muss kleiner sein als 20.
Angenommen, dass Sie tatsächlich die Arbeit mit sehr großen zahlen, die Sie nutzen könnten doubles anstelle der sich danach sehnt, als die Kräfte mehr und mehr an Bedeutung.
Edit:
Wenn Sie große zahlen konnte man auch mit Stirling ' s Formel:
Wie n groß wird ln(n!) -> n*ln(n) - n.
Setzt das in code:
Ich nur vorschlagen, diese Antwort, wie Sie sagten, die Sprache unabhängig ist, ist der C# code wird nur verwendet, um vorzuführen. Seit Sie brauchen, um große zahlen für n und k für diese zu arbeiten, ich schlage vor, dies als einen Allgemeinen Weg für die Suche nach der binomial-Koeffizient für große Kombinationen.
Für Fälle wurden n und k sind beide kleiner als rund 200-300, sollten Sie die Antwort Victor Mukherjee vorgeschlagen, wie es genau ist.
Edit2:
Bearbeitet meinen ersten code.
Nur zur Vervollständigung: die standard -
C
math-Bibliothek hat Implementierungen der beiden Γ und lnΓ (genannttgamma
undlgamma
), woΓ(n) = (n-1)!
Die Bibliothek Berechnung ist zweifellos schneller und genauer als Fazit Logarithmen. Für viel mehr Informationen finden Sie unter Wikipedia und Mathworld.