JavaScript でアルゴリズムの複雑さを学ぶ

JavaScript でアルゴリズムの複雑さを学ぶ

この記事では、アルゴリズムの文脈における「二次」や「n log(n)」などの用語の意味について説明します。

[[314140]]

次の例では、5 つの要素を含む配列と 50 の要素を含む配列の 2 つを参照します。また、JavaScript の便利なパフォーマンス API を使用して、実行時間の違いを測定します。

  1. 定数smArr = [5, 3, 2, 35, 2];
  2.  
  3. const bigArr = [5, 3, 2, 35, 2, 5, 3, 2, 35, 2, 5, 3, 2, 35, 2, 5, 3, 2, 35, 2, 5, 3, 2, 35, 2, 5, 3, 2, 35, 2, 5, 3, 2, 35, 2, 5, 3, 2, 35, 2, 5, 3, 2, 35, 2];

Big O 表記法とは何ですか?

Big O 表記法は、データ セットのサイズが大きくなるにつれて計算タスクの難易度が全体的に増加することを表現する方法です。他にも表記法はありますが、最悪のシナリオに焦点を当てているため、定量化や検討が容易なビッグ O 表記法が一般的に最もよく使用されます。最悪のシナリオとは、タスクを完了するために最も多くの操作を必要とするシナリオを意味します。1 秒以内にキューブを解くことができたとしても、一度だけひねっただけでは最善の成果とは言えません。

これは、アルゴリズムをさらに深く理解するにつれて非常に役立ちます。コードを書くときにこの関係を理解し​​、どこに費やされているかがわかるからです。

Big O 表記法について詳しく学ぶと、次の図のさまざまなバリエーションがわかるようになります。複雑さはできるだけ低く抑え、できれば O(n) を超えないようにします。

オー(1)

これは理想的な状況であり、プロジェクトの数が 1 つであろうと 100 万であろうと、完了するまでの時間は同じままです。単一の操作を実行するほとんどの操作は O(1) です。配列へのデータの書き込み、特定のインデックスでの項目の取得、子要素の追加などは、配列の長さに関係なく、すべて同じ時間がかかります。

  1. 定数 a1 = パフォーマンス.now();
  2. smArr.push(27);
  3. 定数 a2 = パフォーマンス.now();
  4. console.log(` Time : ${a2 - a1}`); // 1ミリ秒未満
  5.  
  6.  
  7. b1 はパフォーマンスを今維持します。
  8. bigArr.push(27);
  9. 定数 b2 = パフォーマンス.now();
  10. console.log(` Time : ${b2 - b1}`); // 1ミリ秒未満

の上)

デフォルトでは、データのサイズと完了までの時間の間には 1 対 1 の関係があるため、すべてのループは線形に増加します。したがって、配列項目が 1,000 個ある場合は、1,000 倍の時間がかかります。

  1. 定数 a1 = パフォーマンス.now();
  2. smArr.forEach(item => console.log(item));
  3. 定数 a2 = パフォーマンス.now();
  4. console.log(` Time : ${a2 - a1}`); // 3ミリ秒
  5.  
  6. b1 はパフォーマンスを今維持します。
  7. bigArr.forEach(item => console.log(item));
  8. 定数 b2 = パフォーマンス.now();
  9. console.log(` Time : ${b2 - b1}`); // 13ミリ秒

(n^2)

指数関数的成長は私たち全員が陥る罠です。配列内のすべての項目に一致するペアを見つける必要がありますか? ループ内にループを配置すると、1,000 項目の配列を 100 万回の操作検索に変換して、ブラウザーが応答しなくなる可能性があります。二重にネストされたループを使用して 100 万回の操作を実行するよりも、2 つの別々のループで 2,000 回の操作を実行する方が適切です。

  1. 定数 a1 = パフォーマンス.now();
  2. smArr.forEach(() => {
  3. arr2.forEach(item => console.log(item));
  4. });
  5. 定数 a2 = パフォーマンス.now();
  6. console.log(` Time : ${a2 - a1}`); // 8ミリ秒
  7.  
  8.  
  9. b1 はパフォーマンスを今維持します。
  10. bigArr.forEach(() => {
  11. arr2.forEach(item => console.log(item));
  12. });
  13. 定数 b2 = パフォーマンス.now();
  14. console.log(` Time : ${b2 - b1}`); // 307 ミリ秒

O(logn) です

対数的増加の良い比喩としては、「記法」のような単語を辞書で調べることを想像することだと思います。用語ごとに検索するのではなく、最初に「N」セクションを見つけ、次に「OPQ」ページを見つけて、一致するものが見つかるまでアルファベット順にリストを検索します。

この「分割統治」アプローチでは、何かを見つけるのにかかる時間は辞書のサイズによって異なりますが、O(n) にはほど遠いです。データの大部分を参照せずに段階的に具体的な部分を検索するため、1,000 個のアイテムを検索する場合は 10 回未満の操作で済み、100 万個のアイテムを検索する場合は 20 回未満の操作で済み、効率が最大限に高まります。

この例では、簡単なクイックソートを実行できます。

  1. 定数ソート = arr => {
  2. (arr.length < 2) の場合はarrを返します
  3.  
  4. ピボットをarr[0]とします。
  5. 左を[]とします。
  6. 右に[] とします。
  7.  
  8. ( i = 1、total = arr.length、i < total、i++ とします) {
  9. もしarr[i] < pivot ならば、 arr[i]を左にプッシュします。
  10. それ以外 右に.push(arr[i]);
  11. };
  12. 戻る[
  13. ...ソート()、
  14. ピボット、
  15. ...並べ替え()
  16. ];
  17. };
  18. sort(smArr); // 0 ミリ秒
  19. sort(bigArr); // 1ミリ秒

の上!)

最悪の可能性は階乗成長です。典型的な例は巡回セールスマン問題です。距離がそれぞれ異なる都市がたくさんある場合、すべての都市から出発点に戻る最短ルートをどのように見つけるのでしょうか。力ずくのアプローチは、各都市間のすべての可能なルート距離をチェックすることですが、これは階乗であり、すぐに手に負えなくなります。

この問題はすぐに非常に複雑になる可能性があるため、短い再帰関数を使用してこの複雑さを示します。この関数は、ある数値をその数値自身で乗算し、その数値から 1 を引きます。階乗の各数値は 0 に達するまでこのように計算され、各再帰層ではその積が元の数値に加算されます。

階乗は、単に 1 から始まってその数まで増加する積です。すると、6! は 1x2x3x4x5x6 = 720 になります。

  1. 定数階乗 = n => {
  2. num = n とします。
  3.  
  4. (n === 0)の場合は1を返す
  5. ( i = 0; i < n; i++ とします) {
  6. num = n * 階乗(n - 1);
  7. };
  8.  
  9. 数値を返します
  10. };
  11. 階乗(1); // 2ミリ秒
  12. 階乗(5); // 3ミリ秒
  13. 階乗(10); // 85ミリ秒
  14. 階乗(12); // 11,942ミリ秒

当初は階乗(15)を表示するつもりでしたが、12を超える値は多すぎてページがクラッシュするため、これを避ける必要があることがわかります。

結論

パフォーマンスの高いコードを書く必要があるというのは議論の余地のない事実のように思えますが、ほぼすべての開発者が「とにかく機能するから」という理由で、少なくとも二重、あるいは三重にネストされたループを作成したことがあると思います。 Big O 表記法は、これまでにない方法で複雑さを表現し、考えるために不可欠です。

<<:  2020年に注目を集めるグラフ機械学習の研究動向とは?

>>:  5G消毒ロボットが武漢を支援し、人間の感染を効果的に防ぐことができる

推薦する

...

タイムトラベルが現実になる?人間はワームホールを通じて「時空の端」に到達できるかもしれないし、量子AIは機械に意識を与えるだろう

[[436484]]タイムトラベルは本当に可能なのでしょうか?新たな研究によれば、今から数千年後には...

[乾物] Tencent Cloud FPGA 上のディープラーニング アルゴリズム

テンセントクラウド基礎製品センターとテンセントアーキテクチャプラットフォーム部門で構成されたテンセン...

浙江大学がSFロボットの群れを作り上げました!自主的に考え、自律的に移動してターゲットを追跡できる

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

90年代以降の世代初登場!何凱明と孫建のチームが未来科学賞を受賞し、ResNetは18万回引用された。

先ほど、2023年未来科学賞の受賞者が発表されました!今年の「数学およびコンピューターサイエンス賞」...

2019年のテクノロジートレンド予測: 5Gが爆発的に普及し、人工知能も勢いを増す

テクノロジー業界にとって、2018年は忘れられない年になる運命にある。結局、シェアサイクルのバブルは...

Alibabaオープンソース!軽量ディープラーニングエッジ推論エンジンMNN

最近、アリババは軽量ディープラーニングエッジ推論エンジン「MNN」を正式にオープンソース化しました。...

MetaとMicrosoft、Nvidia GPUの代替として新しいAMD AIチップを購入することを約束

12月7日、Meta、OpenAI、Microsoftは、現地時間水曜日のAMD投資家向けイベントで...

Pytorchの核心部分である自動微分化を突破! !

こんにちは、Xiaozhuangです! PyTorch での自動微分演算に関して、この論文では Py...

Pythonアルゴリズムを使用して取引する方法

投資管理会社でシステム開発エンジニアとして働いていたとき、定量金融で成功するには、数学、プログラミン...

スマート運転の新たな戦い:「レーダーとビジョンの融合」に対抗、5つの勢力が別々に攻撃

[[440742]]この記事はLeiphone.comから転載したものです。転載する場合は、Leip...

...

GPT-5は来年登場?内部告発者は、マルチモーダルゴビはGPT-5であり、自己認識能力を示していることを明らかにした。

OpenAI 初の開発者会議は AI の饗宴です。 GPT-4 Turbo、大幅な値下げ、開発者向...

ショッキング? AIがKe Jieを完全に打ち負かす前に知っておくべきこと

[制作|網易智能計画/ 翻訳|炳漢]昨年3月、囲碁が打てる「AlphaGo」が人工知能を一躍有名にし...

SVM のマップ削減データマイニングアルゴリズム

元のアルゴリズムに並列戦略を適用するのは難しいため、他のアルゴリズムのバリアントである pegaso...