2

私はラムダ関数をいじっていて、それを使って簡単に何ができるかを理解していますが、もっと高度なものを試してみると、エラーが発生し、理由がわかりません。

これが私がどこで間違っているのか教えてくれれば私が試みていることです。

import math

C = lambda n,k: math.factorial(n)/(math.factorial(k))(math.factorial(n-k))

print C(10,5)

コードパッドでコードを実行しようとするとエラーが発生することに注意してください。アイドルにアクセスできません。

4

3 に答える 3

3

これを試して:

from math import factorial
from __future__ import division

C = lambda n, k : factorial(n) / factorial(k) * factorial(n-k)

print C(10,5)
> 3628800.0

がありませんでした。*また、除算で小数を考慮する必要がある可能性があるため、古い除算演算子/は機能しません。/そのため、小数除算を実行する新しい演算子をインポートしています。

アップデート:

結局、これは Codepad のせいのようです。これはPython 2.5.1 をサポートしfactorial、Python 2.6 で追加されました。独自の階乗関数を実装して終了するか、実際の Python インタープリターの使用を開始することをお勧めします。

def factorial(n):
    fac = 1
    for i in xrange(1, n+1):
        fac *= i
    return fac
于 2012-10-28T01:16:28.263 に答える
1

*2 番目の 2 つの階乗句の間にa が欠落していると思います。を実行しようとしているためにエラーが発生していますが、これは の(math.factorial(k))(math.factorial(n-k))ようなもの10(math.factorial(n-k)になり、意味がありません。

于 2012-10-28T01:16:09.167 に答える
1

おそらく、計算したい値は「n-choose-k」であり、一度にk個のn個のものの組み合わせの数です。そのための式は ですn!/(k! * (n-k)!)。欠損*値を計算に追加するとn!/k! * (n-k)!、 に等しい が生成されます(n!/k!)*(n-k)!。(注、k!均等に分割n!します。)たとえば、n=10 で k=5 の場合、C(10,5) は 3628800/(120*120) = 252 になるはずですが、計算すると 3628800/120*120 = 3628800 になります。これは 14400 倍間違っています。

もちろん、括弧を修正できます。

>>> C = lambda n,k: math.factorial(n)/(math.factorial(k)*math.factorial(n-k))
>>> C(10,5)
252

しかし、math.factorial(j) が計算に j-1 回の乗算を必要とする場合、C(n,k) は n-1+k-1+nk-1+1 = 2*n-2 回の乗算と 1 つの除算を必要とすることに注意してください。これは、必要な乗算操作の約 4 倍です。以下に示すコードは、j 回の乗算と j 回の除算を使用します。ここで、j は k と nk の小さい方であるため、j は最大でも n/2 です。一部のマシンでは、除算は乗算よりもはるかに遅くなりますが、ほとんどのマシンでは、j の乗算と j の除算は、2*n-2 の乗算と 1 つの除算よりもはるかに高速に実行されます。

さらに重要なことは、C(n,k) が n! よりもはるかに小さいことです。式による計算では、n!/(k!*(n-k)!)n が 20 を超える場合は常に 64 ビット以上の精度が必要です。たとえば、C(21,1) は値 21L を返します。対照的に、以下のコードは、D(62,31)=465428353255261088L を計算するために 64 ビット以上を必要とする前に、D(61,30)=232714176627630544 まで計算します。(名前の衝突を避けるために、以下の関数に「C」ではなく「D」という名前を付けました。)

大きな高速マシンでの小さな計算では、余分な乗算と余分な精度の要件は重要ではありません。ただし、小さなマシンでの大規模な計算では、それらが重要になります。

つまり、D() の乗算と除算の順序により、最小限に見える最大の中間値が維持されます。最大値は、for ループの最後のパスに表示されます。また、for ループでは、i は常に c*j の正確な除数であり、切り捨ては行われないことに注意してください。これは、「n-choose-k」を計算するためのかなり標準的なアルゴリズムです。

def D(n, k):
    c, j, k = 1, n, min(k,n-k)
    for i in range(1,k+1):
        c, j = c*j/i, j-1
    return c

通訳からの結果:

>>> D(10,5)
252
>>> D(61,30)
232714176627630544
>>> D(62,31)
465428353255261088L
于 2012-10-28T06:16:48.733 に答える