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

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

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

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

[[424052]]

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

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

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

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

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

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

「明白な」解決策:

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

  1. インポートシステム
  2. # 実際の実行コード
  3. 交差を定義します(リスト1、リスト2):
  4. 結果 = []
  5. list1xの場合:
  6. リスト2yについて:
  7. x == yの場合:
  8. 結果.append(y)
  9. 結果を返す
  10. # コマンドラインからプログラムを実行し、さまざまなサイズのリストを扱いやすくするための定型文
  11. def run(n):
  12. # n+1 個の要素を持つ 2 つのリストを定義する
  13. リスト1 = リスト(範囲(3, n)) + [2]
  14. リスト2 = リスト(範囲(n+1, 2*n)) + [2]
  15. # 交差を取って結果を出力します
  16. print(リスト(交差(リスト1, リスト2)))
  17. # 最初のコマンドライン引数を入力として使用してプログラムを実行します
  18. 実行( int (sys.argv[1]))

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

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

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

  1. $時間python3 quadratic.py 10
  2. [2]
  3. 実数0分0.037秒
  4. $時間python3 quadratic.py 100
  5. [2]
  6. 実数0分0.053秒
  7. $時間python3 quadratic.py 1000
  8. [2]
  9. 実数0分0.051秒
  10. $時間python3 quadratic.py 10000 # 10,000
  11. [2]
  12. 実数0分1.661秒

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

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

  1. $時間python3 quadratic.py 100000 # 100,000
  2. [2]
  3. 実数2分41秒059

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

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

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

高速バージョン: linear.py

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

  1. インポートシステム
  2. # 実際に実行されるアルゴリズム
  3. 交差を定義します(リスト1、リスト2):
  4. set1 = set (list1) # これはハッシュセットです 
  5. 結果 = []
  6. リスト2yについて:
  7. yがset1にある場合:
  8. 結果.append(y)
  9. 結果を返す
  10. # コマンドラインからプログラムを実行し、さまざまなサイズのリストを扱いやすくするための定型文
  11. def run(n):
  12. # n+1 個の要素を持つ 2 つのリストを定義する
  13. リスト1 = 範囲(3, n) + [2]
  14. リスト2 = 範囲(n+1, 2*n) + [2]
  15. # 交差結果を出力する
  16. print(交差(リスト1, リスト2))
  17. 実行( 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. $時間python3 linear.py 100
  2. [2]
  3. 実数0分0.056秒
  4. $時間python3 linear.py 1000
  5. [2]
  6. 実数0分0.036秒
  7. $時間python3 linear.py 10000 # 10,000
  8. [2]
  9. 実数0分0.028秒
  10. $時間python3 linear.py 100000 # 100,000
  11. [2]
  12. real 0m0.048s < -- この場合、quadratic.py に 2 分かかりました。今では 0.04 秒で実行しています。とても速いです!  
  13. $時間python3 linear.py 1000000 # 1,000,000
  14. [2]
  15. 実数0分0.178秒
  16. $時間python3 linear.py 10000000 # 10,000,000
  17. [2]
  18. 実数0分1.560秒

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

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

  1. $時間python3 linear.py 10000000000
  2. トレースバック(最新の呼び出しが最後):
  3. ファイル"/home/bork/work/homepage/linear.py" 、行 18 <module>
  4. 実行( int (sys.argv[1]))
  5. ファイル「/home/bork/work/homepage/linear.py」、13行目、実行
  6. リスト1 = [1] * n + [2]
  7. メモリエラー
  8. 実数0分0.090秒
  9. ユーザー0m0.034s
  10. システム 0分0.018秒

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

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

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

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

  1. 交差を定義します(リスト1、リスト2):
  2. set1 = set (list1) # これはハッシュセットです 
  3. 結果 = []
  4. リスト2yについて:
  5. yがset1にある場合:
  6. 結果.append(y)
  7. 結果を返す

list1 と list2 はどちらも約 10,000,000 個の一意の要素を持つリストだとします。これは非常に多い数です。

では、なぜこんなに速く実行できるのでしょうか? それはハッシュマップのおかげです!!!

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

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

  1. yがset1にある場合:
  2. 結果.append(y)

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

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

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

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

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

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

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

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

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

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

<<:  インテリジェントコンピューティングセンター構築の「サンゴ礁」と「灯台」

>>:  Alimama は曲率空間学習フレームワークと連合学習ソリューションをオープンソース化し、共通の進歩のために AI 技術を一般に公開します。

ブログ    
ブログ    

推薦する

高速ドローンは森の中を自律的に飛行し、旅の間中独自のルートを計画し、最高時速40キロメートルで飛行する。

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

Google の 15 のオープンソース無料人工知能プロジェクト!開発者: 了解しました

開発者は人工知能に関するオープンソース プロジェクトを数多く目にしてきたと思いますし、Github ...

人間の顔の価値はどれくらいでしょうか?顔認識グレー産業チェーン

[[335658]]現在、数十のスタートアップ企業や大手テクノロジー企業が、ホテル、小売店、さらには...

Pangu-Agentの5つのイノベーション

大規模言語モデル (LLM) の開発と応用により、人工知能の分野で LLM ベースの自律エージェント...

Llama 2 の中国語版はオープンソースであり、言語モデルとマルチモーダルモデルの両方を備えているため、完全に商用利用可能です。

7月19日、Metaはついに無料の商用版Llama 2をリリースし、オープンソースの大規模モデルの...

プロンプトの可能性を探り、ChatGPT スキルを向上させましょう

まとめこの記事では主に、プロンプトを最適化することで ChatGPT の使用を改善する方法について説...

6つの新しいことに焦点を当て、新境地を開拓し、プロジェクトは変革を促進するための王様です。2020年中国(太原)人工知能会議が開催されました

2002年から2012年までの石炭の「黄金の10年」を経験した後、「古い工業基地」である山西省太原市...

強風にも耐えられるドローン?カリフォルニア工科大学は12分間の飛行データを使い、ドローンに風の中での飛行を教える

傘が吹き飛ばされるほど風が強いときでも、ドローンは次のように安定した状態を保ちます。風に乗ることは、...

ICDM の選択: データ マイニングの代表的なアルゴリズム トップ 10

2006 年 12 月、国際的に有名な学術組織である IEEE 国際データマイニング会議 (ICD...

AIビデオ分析が業務を強化できる4つの方法

私たちが知っている食品の消費とレストラン体験の変革は、1921 年にカンザス州ウィチタでアメリカ初の...

Claude3 が GPT4 に教訓を与えました!オープンAI最強の対戦相手の深夜爆弾、全貌解析付き!

制作:51CTO テクノロジースタック(WeChat ID:blog)深夜、OpenAI の最大のラ...

ガイドはここにあります! GPT3.5を微調整して大規模モデルをカスタマイズしましょう!

著者 | 崔昊レビュー | Chonglou一般的なモデルは優れていますが、技術者は、独自の大規模な...

Google エンジニア: AI テクノロジーにより、5 年以内に人間とコンピューターの会話が実現する

人間の言語を習得することはコンピューターにとって依然として課題だが、グーグルのエンジニアは人工知能(...

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

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