2016-10-25 4 views
0

Ich mache Projekt Euler und ich bin bei Problem 15 jetzt, hier ist ein Link: https://projecteuler.net/problem=15. Ich versuche das mit Binomialkoeffizienten zu lösen. Hier ist eine Seite, die es erklärt: http://www.mathblog.dk/project-euler-15/. Sie können es unten finden.Warum ist der folgende Code falsch? Binomialkoeffizient

Meine Frage ist, warum ist der folgende Code falsch? Da dies dem mathematischen Algorithmus folgt, denke ich: n-k + i/i

 int grid = 20; 
     long paths = 1; 
     for (int i = 0; i < grid; i++) 
     { 
      paths *= (grid * 2) - (grid + i) 
      paths /= (i + 1); 
     } 
     Console.WriteLine(paths); 
     Console.ReadKey(); 

Und warum ist dieser Code falsch? Dies ist genau wie die Mathblog-Seite, aber in 1 Zeile.

 int grid = 20; 
     long paths = 1; 
     for (int i = 0; i < grid; i++) 
     { 
      paths *= ((grid * 2) - i)/(i + 1); 
     } 
     Console.WriteLine(paths); 
     Console.ReadKey(); 

Aber warum ist dieser Code dann richtig? Ist es nicht dasselbe wie der vorherige Code? Und es folgt nicht genau dem mathematischen Algorithmus, oder? Weil es n-k + i/i ist, und dieser Code tut n-i/i

Thnx Jungs!

+0

Versuchen Sie es mit 'Doppelpfaden' anstelle von' Lang'. So lange eine Ganzzahl ist, könnte Ihr Problem die Aufrundung in der Abteilung – Magnetron

+0

sein. Ihr zweiter Codeblock ist nicht derselbe wie in der URL, die Sie verlinkt haben. Sollte 'paths = (Pfade * (grid * 2) - i)/(i + 1);' wenn du es einzeilen willst. Was Sie geschrieben haben ist das gleiche wie 'Pfade = Pfade * (((Grid * 2) - i)/(i + 1));' –

+0

Der letzte Code funktioniert, aber ich verstehe nicht warum: P Weil in meinen Augen Wenn ich dem mathematischen Algorithmus richtig folge, sollte ich den ersten Code in meinem Kommentar verwenden. (Ich bin kein Mathematiker, damit ich falsch liegen könnte). Ist der 2. Code und der letzte Code nicht gleich? In jedem Fall funktioniert der letzte Code. – Mathijs

Antwort

2

Wenn Sie die Berechnung combain wollen es wie dieses

paths = (path *((grid * 2) - i))/(i + 1); 
+0

Vielen Dank! Weißt du, warum es nicht (Raster * 2) - (Raster + I) statt (Raster * 2) - ich aber im richtigen Code? – Mathijs

+0

Siehe meinen Kommentar - Ihr Code vereinfacht zu (Grid - ich) – PaulF

+0

Ja PaulF hat Recht. siehe sein Kommentar – volkinc

0

Vereinbarungs sein sollte, in vielen Programmiersprachen, int/int gibt einen int, * keine Gleitkommazahl. Ihre Methode impliziert, dass "Pfade" Werte annehmen sollten, die nicht int sind. In der Tat sollte keine der drei Methoden funktionieren, aber durch einen glücklichen Zufall funktionierte der letzte: Im Grunde, weil alle Zwischenwerte von "Pfaden" auch Binomialkoeffizienten sind.

Hinweis zum Debugging: Bitten Sie Ihr Programm, die Zwischenwerte auszugeben. Das hilft sehr.

*: Als Mathematiker brauche ich diese Funktion fast nie. Tatsächlich hätte die andere Konvention (int/int -> double) mein Leben als Programmierer im Durchschnitt einfacher gemacht.


Ich habe mir den Blog angesehen, den Sie erwähnen. Dies macht Ihre Nachricht viel verständlicher. Der Blog erwähnt eine Formel: das Produkt für i von 1 bis k von (n-k + 1)/i. So ist es mimick Sie würden

for (int i = 1; i <= grid; i++) // bounds! 
    { 
     paths *= (grid * 2) - (grid - i) // minus sign! 
     paths /= (i + 1); 
    } 

über die Tatsache schreiben müssen, dass dies mit ints arbeitet: Dies ist ein Unfall aufgrund der Tatsache, dass in den Zwischenwerten des Produkts (am Ende jeder Schleife) sind Binomialkoeffizienten während der gesamten Berechnung. Wenn Sie die Produkte und Divisionen in einer anderen Reihenfolge berechnen würden, könnten Sie sehr gut Nicht-Ganzzahlen erhalten, so dass die Berechnung wegen der Konvention int/int -> int mit einem Integer-Variablentyp für Pfad fehlschlagen würde. Der Blog ist nicht sehr hilfreich darin, dies nicht zu erwähnen.

+0

Ich verstehe das Minuszeichen zwar nicht, weil ich denken würde, zu imitieren (n-k + i)/ich müsste das Pluszeichen anstelle des Minuszeichens wie folgt verwenden: 'paths * = (grid * 2) - (grid + i) ' – Mathijs

+0

n-k + i bedeutet (nk) + i, nicht n - (k + i): In der üblichen Mathematik/und/Programmierung hat der Minus-Operator Vorrang vor dem Plus Operator – Arnaud