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

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

[[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: データ駆動型企業への次のステップ

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

ブログ    
ブログ    
ブログ    
ブログ    

推薦する

UAE、AIガバナンスに関する世界的合意を求める

UAEの人工知能、デジタル経済、リモートワークアプリケーション担当国務大臣オマール・オラマ氏は先週、...

初めて人間を超えた! 「絵を読んで意味を理解する」ことに関しては、AIは人間の目よりも優れている

[[417746]]この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI...

...

2024 年の人工知能に関するトップ 10 の予測

2023年の人工知能分野でキーワードを1つだけ選ぶとしたら、それはおそらく「ビッグモデル」でしょう。...

「質問の海」戦略を取り除き、モデルに人間のように考えることを学習させる

[[395305]]最近、Ant Security Tianzhu Labのセキュリティ専門家である...

自動運転開発ツールチェーンの現状と動向を20,000語で解説

要点: 1. 自動車会社が独自の自動運転システムを開発することがトレンドとなっている。 2. MBD...

AI: いつも HD ビデオが欲しいなら、ここにあります

Magnific の画像超解像度および強化ツールはまだテスト中ですが、その強力な画像アップスケーリン...

テンセントは顔認識技術を使って未成年者への薬物依存防止規制を強化

米国のメディアによると、子供や十代の若者はビデオゲームに関するほぼすべての制限に対処する方法を見つけ...

ビッグデータは私たちを新たな AI の冬に引きずり込むのか?

過去数年間の息を呑むようなニュースクリップの数は思い出すのが難しいが、人工知能の歴史は挫折と挫折に満...

小中学生の安全を守るためにロボットは今や欠かせない存在です!

安全性について話すと、誰もが必ずそれに共感します。時代の急速な発展に伴い、人々の個人的な安全がますま...

ヘルスケアにおける IoT と AI

IoT 対応デバイスの登場により、医療における遠隔モニタリングが可能になりました。ほぼすべての大手...

清華大学 IEEE 論文: 自動運転の判断を支援する新しいトレーニング方法を使用して「路側干渉」を排除

最近、清華大学の学者たちは、オートエンコーダーに基づく新しいトレーニング方法を提案しました。これによ...

研究によると、ChatGPT は科学的仮説の偽のデータセットを生成し、学術的誠実性に脅威を与える可能性がある。

ネイチャー誌は11月24日、現地時間水曜日に、今月初めに米国医師会眼科学会誌に掲載された論文で、著者...

AIを使って株取引で不正行為をしよう!この世代のプログラマーは本当に楽しみ方を知っている

ディープラーニングを使用して株価を予測することは、以前は少し神秘的に思えたかもしれませんが、新しいこ...