2017-10-24 11 views
-1

私は、次の3つの機能のうち1ヶ月の日数を調べる最速の方法を見つけようとしていました。アルゴリズムの速度

def f1(): 
    t=time.time() 
    for month in range(1,13): 
     for year in range(10001): 
      leap_year=(year%4==0 and year%100!=0) or year%400==0 
      n=[29,31,28,31,30,31,30,31,31,30,31,30,31][month-2*leap_year*(month==2)] 
    return time.time()-t1 
def f2(): 
    t=time.time() 
    for month in range(1,13): 
     for year in range(10001): 
      leap_year=(year%4==0 and year%100!=0) or year%400==0 
      n=[31,28,31,30,31,30,31,31,30,31,30,31][month-1]+leap_year*(month==2) 
    return time.time()-t 
def f3(): 
    t=time.time() 
    for month in range(1,13): 
     for year in range(10001): 
      leap_year=(year%4==0 and year%100!=0) or year%400==0 
      n={1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31}[month]+leap_year*(month==2) 
    return time.time()-t 
print(sum(f1() for i in range(100))) 
print(sum(f2() for i in range(100))) 
print(sum(f3() for i in range(100))) 

辞書のアルゴリズムが最も高速であると予想していました。しかし、私はこれを持っています:

3.7855005264282227 
3.625513792037964 
9.0009183883667 

明らかに、私は間違っていました。誰かがdictアルゴリズムのスピードが遅い理由を説明することはできますか?それは時間(O(1))を最小限に取るべきであり、リストアルゴリズムはO(n)を取るべきです。これは私が得た結果と矛盾します。私はプログラミングに非常に新しいです。ありがとう!

+0

私はこれについて多くの研究をしませんでしたが、あなたのnがかなり小さいことに気付きました(12)。私は、ハッシュを計算し、ハッシュテーブル内の要素を見つけることは、リストの12要素を通過するよりも長い時間がかかることが分かった。あなたのn(もっと月)を増やして、スピードアップを試してみてください。 –

+4

さらに、各反復でリストと辞書*を作成しています。 –

+2

また、リストとdictで実行している操作はアイテムにアクセスしているだけです。リストとdictの両方はアイテムにアクセスするためには一定の時間(つまりO(1))の複雑さを持っています。しかし、リストから実際にアクセスする速度は速くなければなりません。しかし、根本的に、あなたはアルゴリズムの複雑さが何を意味するのか混乱しています。それはあなたの事例で本当に対処していないアルゴリズム*のスケール*についてです。 –

答えて

3

すべての繰り返しでリスト/辞書を作成しています。 これを一度しかビルドしないと、f3()メソッドが最も速くなります。listとdictの両方のアクセス時間はO(1)です。

def f1(): 
    t=time.time() 
    m=[29,31,28,31,30,31,30,31,31,30,31,30,31] 
    for month in range(1,13): 
     for year in range(10001): 
      leap_year=(year%4==0 and year%100!=0) or year%400==0 
      n=m[month-2*leap_year*(month==2)] 
    return time.time()-t 
def f2(): 
    t=time.time() 
    m=[31,28,31,30,31,30,31,31,30,31,30,31] 
    for month in range(1,13): 
     for year in range(10001): 
      leap_year=(year%4==0 and year%100!=0) or year%400==0 
      n=m[month-1]+leap_year*(month==2) 
    return time.time()-t 



def f3(): 
    t=time.time() 
    m={1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31} 
    for month in range(1,13): 
     for year in range(10001): 
      leap_year=(year%4==0 and year%100!=0) or year%400==0 
      n=m[month]+leap_year*(month==2) 
    return time.time()-t 


print(sum(f1() for i in range(100))) 
print(sum(f2() for i in range(100))) 
print(sum(f3() for i in range(100))) 
+0

ありがとう、私はそれを持っています! 1か月の日数を計算する良い方法はありますか? –