5

タプルのベクトル(剰余、モジュラス)から中国剰余定理を計算する場合、次のコードは失敗します。

c = ((1,5),(3,7),(11,13),(19,23))

def crt(c):
        residues, moduli = zip(*c)
        N = product(moduli)
        complements = (N/ni for ni in moduli)
        scaled_residues = (product(pair) for pair in zip(residues,complements))
        inverses = (modular_inverse(*pair) for pair in zip(complements,moduli))
        si = (product(u) for u in zip(scaled_residues,inverses))
        result = sum(si) % N
        return result

結果を0として与えます(生成された反復可能オブジェクトは空だと思います)。しかし、次のコードは完全に機能します:

def crt(c):
        residues, moduli = zip(*c)
        N = product(moduli)
        complements = list((N/ni for ni in moduli)) # <-- listed
        scaled_residues = (product(pair) for pair in zip(residues,complements))
        inverses = (modular_inverse(*pair) for pair in zip(complements,moduli))
        si = (product(u) for u in zip(scaled_residues,inverses))
        result = sum(si) % N
        return result

これにより、(a) 8851の正しい結果が得られます。

なぜlist(最初のジェネレーターの1つを使用する必要があるのですか?後続のジェネレーターに追加listしても、失敗(0)の結果は変わりません。この最初のジェネレーターをリストするだけで、正しい結果が得られます。ここで何が起こっているのですか?

4

2 に答える 2

6

を2回繰り返しcomplementsます。ジェネレータ式を反復処理できるのは1回だけです。

Python 2.xを使用している場合は、zip(residues,complements)を消費complementsし、に何も残っていませんzip(complements,moduli)。Python 3.xではジェネレーター自体であり、実際にジェネレーターを実行するzipと、コードの後半で問題が発生します。反復ごとにsum()2つのアイテムをプルします。complements

于 2013-02-01T06:43:57.170 に答える
0

回答の提案に基づいた参考のために、質問のコードを次のように再実装しました。

def complements(moduli,N):
        return (N/ni for ni in moduli)

def scaled_residues(residues,complements):
        return (product(pair) for pair in zip(residues,complements))

def inverses(complements,moduli):
        return (modular_inverse(*pair) for pair in zip(complements,moduli))

def crt_residue_terms(scaled_residues,inverses):
        return (product(u) for u in zip(scaled_residues,inverses))

 def crt(c):   
    residues, moduli = zip(*c)
    N = product(moduli)
    return sum(
            crt_residue_terms(
                    scaled_residues(residues,complements(moduli,N)),
                    inverses(complements(moduli,N),moduli)
            )) % N

これで、リストを使用せずに8851の正しい結果が生成されます。涼しい。

于 2013-02-01T07:03:40.540 に答える