遅い二次アルゴリズムと高速ハッシュマップについての簡単な説明

遅い二次アルゴリズムと高速ハッシュマップについての簡単な説明

[[424110]]

こんにちは、みんな!昨日、プログラミング面接の準備をしていて、アルゴリズムの基礎を学ぼうとしている友人とチャットをしていました。

私たちは話しました二次時間二次時間そして線形時間線形時間アルゴリズムの話題については、ここでそれについて書くのは楽しいだろうと思いました。なぜなら、二次時間アルゴリズムを避けることは、面接で重要であるだけでなく、実生活でそれについて知っておくと便利な場合があるからです。 「二次時間アルゴリズム」とは何かについては後で簡単に説明します :)

ここで議論する 3 つの事項は次のとおりです。

  1. 二次関数は一次関数よりもはるかに遅い
  2. ハッシュマップを使うことで、二次アルゴリズムを線形アルゴリズムに変換できる場合がある。
  3. これは、ハッシュマップの検索が非常に高速であるためです (即時検索!)

数学の専門用語は避け、実際のコード例と、実際にどれくらい速いか遅いかに焦点を当てたいと思います。

目標問題: 2つのリストの共通部分を見つける

2 つの数値リストの共通部分を取得するという、簡単なインタビュー形式の問題について説明しましょう。 たとえば、 intersect([1,2,3], [2,4,5]) [2]を返します。

この問題には現実世界への応用もいくつかあります。2 つの ID リストの正確な交差を必要とする実際のプログラムを想像してみてください。

「明白な」解決策:

2 つのリストの共通部分を取得するコードを書いてみましょう。以下は、この要件を実装するquadratic.pyという名前のプログラムです。

  1. import sys
  2. # 实际运行的代码
  3. def intersection ( list1 , list2 ):
  4. result = []
  5. for x in list1 :
  6. for y in list2 :
  7. if x == y :
  8. result . append ( y )
  9. return result
  10. # 一些样板,便于我们从命令行运行程序,处理不同大小的列表
  11. def run ( n ):
  12. # 定义两个有 n + 1 个元素的列表
  13. list1 = list ( range ( 3 , n )) + [ 2 ]
  14. list2 = list ( range ( n + 1 , 2 * n )) + [ 2 ]
  15. # 取其交集并输出结果
  16. print ( list ( intersection ( list1 , list2 )))
  17. # 使用第一个命令行参数作为输入,运行程序
  18. run ( int ( sys . argv [ 1 ]))

プログラムの名前がquadratic.pyなのは、 list1list2のサイズがnの場合、内部ループ ( if x == y ) がn^2回実行されるためです。数学では、 x^2のような関数は「二次」関数と呼ばれます。

quadratic.pyはどれくらい遅いですか?

このプログラムを異なる長さのリストで実行すると、2つのリストの共通部分は常に同じになります: [2]

  1. $ time python3 quadratic . py 10
  2. [ 2 ]
  3. real 0m0.037s
  4. $ time python3 quadratic . py 100
  5. [ 2 ]
  6. real 0m0.053s
  7. $ time python3 quadratic . py 1000
  8. [ 2 ]
  9. real 0m0.051s
  10. $ time python3 quadratic . py 10000 # 10 , 000
  11. [ 2 ]
  12. real 0m1.661s

これまでのところ順調です。プログラムの実行時間は依然として 2 秒未満です。

次に、それぞれ 100,000 要素の 2 つのリストでプログラムを実行しましたが、長い時間待たなければなりませんでした。結果は次のとおりです。

  1. $ time python3 quadratic . py 100000 # 100 , 000
  2. [ 2 ]
  3. real 2m41.059s

かなり遅いですね!これには合計 160 秒かかり、10,000 要素で実行した場合 (1.6 秒) のほぼ 100 倍の時間がかかりました。したがって、ある時点以降、リストを 10 倍大きくするたびに、プログラムの実行にかかる時間が約 100 倍長くなることがわかります。

このプログラムを 1,000,000 個の要素で実行しようとはしませんでした。100 倍の時間がかかることがわかっていたからです (おそらく 3 時間程度)。こんな時間はないよ!

おそらくこれで、2 次時間アルゴリズムがなぜ問題になるのかがお分かりいただけたと思います。この非常に単純なプログラムでさえ、すぐに非常に遅くなる可能性があるのです。

高速バージョン: linear.py

さて、プログラムの簡単なバージョンを書いてみましょう。まずプログラムがどのようなものかを示し、その後分析します。

  1. import sys
  2. # 实际执行的算法
  3. def intersection ( list1 , list2 ):
  4. set1 = set ( list1 ) # this is a hash set
  5. result = []
  6. for y in list2 :
  7. if y in set1 :
  8. result . append ( y )
  9. return result
  10. # 一些样板,便于我们从命令行运行程序,处理不同大小的列表
  11. def run ( n ):
  12. # 定义两个有 n + 1 个元素的列表
  13. list1 = range ( 3 , n ) + [ 2 ]
  14. list2 = range ( n + 1 , 2 * n ) + [ 2 ]
  15. # 输出交集结果
  16. print ( intersection ( list1 , list2 ))
  17. run ( int ( sys . argv [ 1 ]))

(これは Python を使用する最も慣用的な方法ではありませんが、Python を知らない人でも理解しやすいように、Python のアイデアをあまり使用せずにコードを書きたかったのです)

ここでは、低速バージョンとは異なる 2 つのことを行います。

  1. list1 set1という名前のセットに変換します。
  2. 2つのforループではなく1つのforループのみを使用する

linear.pyプログラムの速さを見てみましょう

このプログラムがなぜ高速なのかを説明する前に、実際に高速であることを示すために、いくつかの大きなリストでプログラムを実行してみましょう。ここでは、プログラムが 10 から 10,000,000 までのサイズのリストに対して順番に実行されている様子が示されています。 (前のプログラムは 100,000 要素で非常に遅くなり始めたことを思い出してください)

  1. $ time python3 linear . py 100
  2. [ 2 ]
  3. real 0m0.056s
  4. $ time python3 linear . py 1000
  5. [ 2 ]
  6. real 0m0.036s
  7. $ time python3 linear . py 10000 # 10 , 000
  8. [ 2 ]
  9. real 0m0.028s
  10. $ time python3 linear . py 100000 # 100 , 000
  11. [ 2 ]
  12. real 0m0.048s <-- quadratic . py took 2 minutes in this case ! we 're doing it in 0.04 seconds now!!! so fast!
  13. $ time python3 linear.py 1000000 # 1,000,000
  14. [2]
  15. real 0m0.178s
  16. $ time python3 linear.py 10000000 # 10,000,000
  17. [2]
  18. real 0m1.560s

非常に大きなリストでlinear.pyを実行する

これを非常に大きなリスト (100 億 / 10,000,000,000 要素) で実行しようとすると、別の問題が発生します。十分に高速ですが (リストは 4.2 秒かかったリストの 100 倍しかないため、おそらく 420 秒以内に終了できるはずです)、コンピューターにはリストのすべての要素を格納するのに十分なメモリがないため、終了する前にプログラムがクラッシュします。

  1. $ time python3 linear . py 10000000000
  2. Traceback ( most recent call last ):
  3. File "/home/bork/work/homepage/linear.py" , line 18 , in < module >
  4. run ( int ( sys . argv [ 1 ]))
  5. File "/home/bork/work/homepage/linear.py" , line 13 , in run
  6. list1 = [ 1 ] * n + [ 2 ]
  7. MemoryError
  8. real 0m0.090s
  9. user 0m0.034s
  10. sys 0m0.018s

ただし、この記事ではメモリ使用量については説明していないため、この問題は無視できます。

では、なぜlinear.pyは高速なのでしょうか?

ここで、 linear.pyが高速である理由を説明します。

もう一度コードを見てみましょう:

  1. def intersection ( list1 , list2 ):
  2. set1 = set ( list1 ) # this is a hash set
  3. result = []
  4. for y in list2 :
  5. if y in set1 :
  6. result . append ( y )
  7. return result

list1list2どちらも約 10,000,000 個の異なる要素を持つリストであるとします。この要素数は非常に大きいと言えます。

では、なぜそんなに速く走るのでしょうか?ハッシュマップのせいだ! ! !

ハッシュマップの検索は瞬時に行われます(「一定時間」)

プログラムのクイック バージョンのifステートメントを見てみましょう。

  1. if y in set1 :
  2. result . append ( y )

set1 1,000 万の要素が含まれている場合、 if y in set1検索は、 set1に 1,000 の要素が含まれている場合よりも遅くなると思われるかもしれません。しかし、そうではありません! set1がどれだけ大きくても、必要な時間は基本的に同じです (超高速)。

これは、 set1がハッシュ セットであり、キーのみで値のないハッシュマップ (ハッシュ テーブル) 構造であるためです。

この記事ではハッシュマップ検索がなぜ瞬時に行われるのかについては説明しません。ただし、ハッシュ テーブルとハッシュ関数に関する Vaidehi Joshi の素晴らしい basecs シリーズでは、ハッシュマップ検索がなぜ瞬時に行われるのかについて説明しています。

偶然の二次方程式: 現実世界における二次方程式アルゴリズム!

2 次時間アルゴリズムは非常に遅く、私たちが目にする問題は現実世界で実際に遭遇したものです。Nelson Elhage は、Accidentally Quadratic という素晴らしいブログを運営しており、そこには、誤って 2 次時間でコードを実行し、パフォーマンスの問題を引き起こした事例が紹介されています。

二次時間アルゴリズムが突然現れるかもしれない

二次時間アルゴリズムの奇妙なところは、少数の要素 (1000 個など) で実行すると、それほど悪くないように見えることです。そんなに遅くないよ!しかし、1,000,000 個の要素を指定すると、実行に文字通り数時間かかります。

したがって、特に線形時間アルゴリズムを簡単に記述できる場合 (ハッシュマップを使用するなど) は、誤って二次時間アルゴリズムを使用することを避けるために、これについてさらに学習する価値があると思います。

いつもちょっと魔法のようなハッシュマップを感じさせてくれる

ハッシュマップは確かに魔法ではありません (ハッシュマップ検索がなぜ瞬時に行われるのかを知ることができます。本当にすごいです!) が、いつも少し魔法のような気分になり、ハッシュマップを使用してプログラムを高速化するたびに幸せな気持ちになります :)

<<:  AI: データ駆動型企業への次のステップ

>>:  スマートエコノミーの時代において、人工知能技術をどのように活用して、より多くの技術的利益をもたらすことができるのでしょうか?

ブログ    
ブログ    

推薦する

SQL クエリ エンジンの自然言語として GPT を使用する方法

翻訳者 |李睿レビュー | Chonglou 今日では、 ChatGPTのような生成AI技術のおかげ...

600以上のベーキングレシピを分析し、機械学習を使用して新製品を開発しました

焼き菓子は、世界中のさまざまな料理の中で常に重要な位置を占めてきました。柔らかいパン、繊細なケーキ、...

飛んでくる花穂は人々を不安にさせますが、人と機械の組み合わせで不安を防ぐことができます!

「霧深い春の朝、緑の枝に雪の結晶が舞い散る。」さあ、また雪のように雪の結晶が舞い散る季節がやってき...

...

...

アルゴリズム取引におけるビッグデータ分析の活用

ウォーレン・バフェットの資産が 5000G あることをご存知ですか? 反対派や懐疑派の意見に反して、...

人工知能は科学研究に革命を起こす力を持っている

人工知能 (AI) は、コンピューター サイエンス、数学、心理学、言語学などの分野が関わる学際的な分...

...

360、認知汎用大型モデル「360 Brain 4.0」をリリース、360ファミリーバケットに完全統合

「デジタルヒューマン『周紅一』を我が社のスポークスマンにしよう。彼が正しいことを言ったら、それは私の...

...

...

...

AIが人々の恋愛探しをどうサポートするか

過去10年間で、多数のカップルがオンラインで出会いました。出会い系アプリを使って恋人を見つけることは...

RAGからマルチモーダル検索まで、OpenAIの技術進化

著者 | 崔昊レビュー | Chonglouまとめこの記事では、情報検索とテキスト生成の最新の進歩に...

世界の顔認識技術応用地域分布マップ

世界中の多くの規制当局は、公開ビデオフィード上の人物を識別するなどのアプリケーションに顔認識を使用し...