2014-10-25 5 views
11

Python Binomialkoeffizient

import math 
x = int(input("Enter a value for x: ")) 
y = int(input("Enter a value for y: ")) 

if y == 1 or y == x: 
    print(1) 

if y > x: 
    print(0)   
else: 
    a = math.factorial(x) 
    b = math.factorial(y) 
    div = a // (b*(x-y)) 
    print(div) 

Diese binomischen KOEFFIZIENT Programm funktioniert, aber wenn i zwei Eingänge der gleichen Zahl, die angeblich auf 1 gleich oder, wenn y größer als x angenommen wird, auf 0 gesetzt, um gleich die Programm braucht ein wenig zwicken, wenn jemand kann mir bitte helfen

+1

Wofür brauchen Sie Hilfe? Die Formel, die Sie für Binomialkoeffizienten verwenden, sieht nicht ganz richtig aus, oder? – Joni

+0

Warum benutzen Sie 'while'? Du kannst einfach 'if' verwenden !! – Kasramvd

+0

Wenn ich eine Zahl größer als x eintrage, kommt ein Fehler oder wenn x und y gleich sind – user3396351

Antwort

1

Ihr Programm wird mit der zweiten if Anweisung im Fall von y == x, was eine ZeroDivisionError verursacht. Sie müssen die Aussagen gegenseitig ausschließen; die Art und Weise zu tun, ist elif („else if“) anstelle von if zu verwenden:

import math 
x = int(input("Enter a value for x: ")) 
y = int(input("Enter a value for y: ")) 
if y == x: 
    print(1) 
elif y == 1:   # see georg's comment 
    print(x) 
elif y > x:   # will be executed only if y != 1 and y != x 
    print(0) 
else:    # will be executed only if y != 1 and y != x and x <= y 
    a = math.factorial(x) 
    b = math.factorial(y) 
    c = math.factorial(x-y) # that appears to be useful to get the correct result 
    div = a // (b * c) 
    print(div) 
+0

Okay Okay, ich gebe zu, du hast Recht, danke, danke für deine Hilfe. – user3396351

+1

'wenn y == 1 oder y == x:' ist per Definition falsch, 'C (x, 1) = x'. – georg

+0

@georg: Danke, ich hatte mir nicht die Mühe gemacht zu prüfen, ob die Berechnungen des OP korrekt waren. Ich hoffe, es ist jetzt besser. –

16

Hier ist eine Version, die die correct formula tatsächlich nutzt. :)

#! /usr/bin/env python 

''' Calculate binomial coefficient xCy = x!/(y! (x-y)!) 
''' 

from math import factorial as fac 


def binomial(x, y): 
    try: 
     binom = fac(x) // fac(y) // fac(x - y) 
    except ValueError: 
     binom = 0 
    return binom 


#Print Pascal's triangle to test binomial() 
def pascal(m): 
    for x in range(m + 1): 
     print([binomial(x, y) for y in range(x + 1)]) 


def main(): 
    #input = raw_input 
    x = int(input("Enter a value for x: ")) 
    y = int(input("Enter a value for y: ")) 
    print(binomial(x, y)) 


if __name__ == '__main__': 
    #pascal(8) 
    main() 

...

Hier ist eine alternative Version von binomial() ich einige Jahren schrieb vor, die nicht math.factorial() nicht verwendet, die nicht in alten Versionen von Python noch nicht gab. Es gibt jedoch 1 zurück, wenn r nicht im Bereich ist (0, n + 1).

def binomial(n, r): 
    ''' Binomial coefficient, nCr, aka the "choose" function 
     n!/(r! * (n - r)!) 
    ''' 
    p = 1  
    for i in xrange(1, min(r, n - r) + 1): 
     p *= n 
     p //= i 
     n -= 1 
    return p 
+0

Bah, wen interessiert es, wenn die Formel richtig ist. Solange mein Code keine Ausnahmen enthält, ist es in Ordnung, oder? Recht? :) –

+0

@TimPietzcker Hey, es ist nicht deine Schuld, wenn der Kunde dir falsche Spezifikationen für die Software gibt, die er für sie schreiben soll. :) –

+2

Ihr (zweiter) Code scheint auch mit ganzzahliger Division zu arbeiten, was ein großartiges Feature ist, da für n größer als (60) Floats aufgrund von Präzisionsfehlern unkorrekte Ergebnisse liefern. – mmj

1

Was ist mit diesem? :) Es verwendet die korrekte Formel, vermeidet math.factorial und nimmt weniger Multiplikationen:

import math 
import operator 
product = lambda m,n: reduce(operator.mul, xrange(m, n+1), 1) 
x = max(0, int(input("Enter a value for x: "))) 
y = max(0, int(input("Enter a value for y: "))) 
print product(y+1, x)/product(1, x-y) 

Auch, um big-Integer-Arithmetik zu vermeiden Sie Gleitkommazahlen verwenden, konvertieren product(a[i])/product(b[i])-product(a[i]/b[i]) und schreiben Sie das obige Programm als :

import math 
import operator 
product = lambda iterable: reduce(operator.mul, iterable, 1) 
x = max(0, int(input("Enter a value for x: "))) 
y = max(0, int(input("Enter a value for y: "))) 
print product(map(operator.truediv, xrange(y+1, x+1), xrange(1, x-y+1))) 
+0

Warum ist "math.factorial" ein Vorteil? – BartoszKP

+0

@BartoszKP: Vielleicht ist es nicht, aber @ PM-2ring in seiner Antwort wies darauf hin, dass 'math.factorial' nicht in alten Pythons existiert, also beschloss ich, es nur zum Spaß zu vermeiden. Wie auch immer, ich habe 'Produkt' definiert. – firegurafiku

+0

@BartoszKP und firegurafiku: 'math.factorial()' läuft mit C-Geschwindigkeit, also ist es wahrscheinlich viel schneller als Lösungen, die Python-Schleifen verwenden. OTOH, factorial() wächst sehr schnell: faktoriell (13) ist zu groß, um in ein "int" zu passen, so dass die viel langsamere "lange" Arithmetik verwendet werden muss. Der Algorithmus von firegurafiku ist in diesem Punkt besser als der einfache faktorielle Algorithmus, aber er arbeitet immer noch mit großen Zahlen. Fortsetzung im nächsten Kommentar ... –

48

Diese Frage ist alt, aber da es hoch oben in den Suchergebnissen kommt, werde ich darauf hinweisen, dass scipy eine Binomialkoeffizient Funktion hat:

import scipy.special 
scipy.special.binom(10, 5) 

(documentation See.)

+5

Ich füge nur eine Warnung hinzu, dass scipy.special.binom eine Gleitkomma-Approximation zurückgibt. Dies ist für die meisten Anwendungen gut genug, reicht für theoretische Zwecke jedoch möglicherweise nicht aus. –

+2

Scipy bietet auch die [Kamm-Funktion] (https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.comb.html#scipy.special.comb), die verwendet werden kann, um genau zu berechnen Werte. –

1

Hier ist eine Funktion, die mit Hilfe der binomischen Koeffizienten berechnet rekursiv Bedingungsausdrücke

def binomial2(n,k): 
    return 1 if k==0 else (0 if n==0 else binomial(n-1, k) + binomial(n-1, k-1)) 
1

Für Python 3 hat die Funktion scipy scipy.special.comb, die schwimmende erzeugen kann Punkt sowie exakte ganzzahlige Ergebnisse

import scipy.special 

res = scipy.special.comb(x, y, exact=True) 

finden Sie in der Dokumentation für scipy.special.comb.

Für Python 2 ist die Funktion in scipy.misc gelegen, und es funktioniert auf die gleiche Art und Weise:

import scipy.misc 

res = scipy.misc.comb(x, y, exact=True) 
1

Also, diese Frage an erster Stelle steht, wenn Sie für „Binomialkoeffizienten in Python implementieren“ suchen. Nur this answer in seinem zweiten Teil enthält eine effiziente Implementierung, die auf der multiplicative formula beruht. Diese Formel führt die Mindestanzahl von Multiplikationen aus.Die Funktion unten hängt nicht von irgendwelchen Einbauten oder Importe:

def fcomb0(n, k): 
    ''' 
    Compute the number of ways to choose k elements out of a pile of n. 

    Use an iterative approach with the multiplicative formula: 
    \frac{n!}{k!(n - k)!} = 
    \frac{n(n - 1)\dots(n - k + 1)}{k(k-1)\dots(1)} = 
    \prod{i = 1}{k}\frac{n + 1 - i}{i} 

    Also rely on the symmetry: C_n^k = C_n^{n - k}, so the product can 
    be calculated up to min(k, n - k) 

    :param n: the size of the pile of elements 
    :param k: the number of elements to take from the pile 
    :return: the number of ways to choose k elements out of a pile of n 
    ''' 

    # When k out of sensible range, should probably throw an exception. 
    # For compatibility with scipy.special.{comb, binom} returns 0 instead. 
    if k < 0 or k > n: 
     return 0 

    if k == 0 or k == n: 
     return 1 

    total_ways = 1 
    for i in range(min(k, n - k)): 
     total_ways = total_ways * (n - i) // (i + 1) 

    return total_ways 

Schließlich, wenn Sie noch größere Werte brauchen, und nichts dagegen haben, etwas an Genauigkeit Handel, Stirling's approximation ist wahrscheinlich der Weg zu gehen.