同じ目的に役立つさまざまなアルゴリズム/データ構造を学ぶ理由は何ですか?


91

私は学部生だったので、この質問について疑問に思っていました。これは一般的な質問ですが、以下の例で詳しく説明します。

私は多くのアルゴリズムを見てきました-例えば、最大流量の問題については、問題を解決できる3つのアルゴリズムを知っています:Ford-Fulkerson、Edmonds-Karp&Dinic、Dinicが最も複雑です。

データ構造(たとえば、ヒープ)には、バイナリヒープ、二項ヒープ、およびフィボナッチヒープがあり、フィボナッチヒープは全体的な複雑さが最適です。

私を混乱させているのは、すべてを知る必要がある理由はありますか?なぜ最高の複雑さを学び、慣れるだけではありませんか?

すべてを知っているのが最善だと知っています。BでなくAを使用することでしか解決できない問題/アルゴリズムなど、「より有効な」理由があることを知りたいだけです。


17
私がいつも言うように:これらは(通常)「最高」ではありません。「より良い」という意味を明確に定義すると、答えが明らかになります。
ラファエル

2
これは良い質問ですが、あなたが修正を検討するかもしれないあなたの教育の穴と私が考えるものに話します。それは実際の経験です。教育中にこれらのアルゴリズムを実際に書いていない場合は、今すぐ書くことを検討するかもしれません。それらの使用法を見つけようとすると、この質問に対する答えはすぐに明らかになると思います。
サム

@Sam私の経験から、私は講義や一部の教科書では有益であり、多くのアルゴリズム、分析などを紹介しているが、AがBを凌ぐ多くの実用的なケースやサンプルシナリオではないと思った。アルゴリズムAからZのジャンル、およびいくつかの宿題の問題がありますが、私にとってはそれらはすべてAのみ、またはZのみなどで解決できるため、質問がありました。
ホール

5
学問的な興味を無視することを主張する場合、最適なアルゴリズムよりも少ない学習をするための最良の実用的な理由は、それらが何であるかを認識し、最適なアルゴリズムにリファクタリングすることで最適化できるようにすることです。弓矢の目的がわからない場合、弓矢を銃にアップグレードすることはできません。
candied_orange

1
実際に、このようなCS教育の質問に特に役立つStackExchangeサイトを提案しました。:ここで私たちをサポートして来area51.stackexchange.com/proposals/92460/...
vk2015

回答:


121

データ構造、アルゴリズム、トレードオフの作業タイトルが付けられた、ある時点で執筆を待っている教科書があります。学部レベルで学習する可能性のあるほぼすべてのアルゴリズムまたはデータ構造には、一部のアプリケーションで他のアプリケーションよりも優れた機能があります。

誰もが標準のソートアルゴリズムに精通しているため、ソートを例に取りましょう。

まず、複雑さだけが問題ではありません。実際には、一定の要因が重要です。そのため、クイックソートは最悪の場合の複雑さにもかかわらず、ヒープソートよりもクイックソートを使用する傾向があります。

第二に、奇妙な制約の下でプログラミングをしている状況にいる可能性が常にあります。私はかつて、適度なサイズ(1000程度)のサンプルのコレクションから可能な限り高速でクォンタイル抽出を行う必要がありましたが、予備の読み書きメモリがほとんどない小さなマイクロコントローラーであったため、ほとんどのアルゴリズムをソートします。シェルの並べ替えは、2次関数であり、追加のメモリを必要としないため、最良のトレードオフでした。O(nlogn)

その他の場合、アルゴリズムまたはデータ構造からのアイデアは、特殊な目的の問題に適用できる場合があります。バブルの並べ替えは、実際のハードウェアでの挿入の並べ替えよりも常に遅いように見えますが、バブルパスを実行するというアイデアは、まさに必要なものです。

たとえば、現代のビデオカードでの3D視覚化やビデオゲームのようなものを考えてみます。パフォーマンス上の理由から、カメラに最も近いものからカメラから最も遠いものまで順番にオブジェクトを描画しますが、正確な順序がわからない場合は、ハードウェアが処理します。3D環境を移動する場合、オブジェクトの相対的な順序はフレーム間であまり変化しないため、フレームごとに1つのバブルパスを実行するのが妥当なトレードオフになる可能性があります。(ValveのSourceエンジンは、パーティクル効果のためにこれを行います。)

永続性、同時実行性、キャッシュの局所性、クラスター/クラウドへの拡張性、および気になる操作の計算の複雑さが同じであっても、あるデータ構造またはアルゴリズムが別のデータ構造またはアルゴリズムより適切である可能性のある他の多くの理由があります。

そうは言っても、万が一に備えてたくさんのアルゴリズムとデータ構造を覚えておく必要があるわけではありません。戦いの大部分は、そもそも悪用されるトレードオフがあることを認識しており、適切な何かがあると思われる場合にどこを調べるべきかを知っています。


7
素晴らしい例と素晴らしい答え!
バブルパスでさえ

1
@sholeゲームビジネスの経験はあまりありませんが、上記のすべてはさまざまな程度で重要です。(明らかに、ゲームに必要なアルゴリズム、データ構造、および数学の種類は、データベースやバイオインフォマティクスに必要なものや、あなたが持っているものとはおそらく異なるでしょう)。 org また、gamedev.stackexchange.comに
Pseudonym

1
キャッシュの効率性は、あまり研究されていない大きな要因です(Googleの「メモリウォール」)。
ラファエル

6
慎重に、QuicksortはHeapsort より平均的にはるかに高速ですが、Heapsortはより一貫性があります(実行時間の変動は少なく、最悪の場合ははるかに優れています)。そして、Heapsortの配列内のジャンプと、左右からのQuicksortの線形スキャンは、キャッシュ/ページングが機能するようになると、大きな違いをもたらします。
フォンブランド

1
@sholeどんなゲーム開発に興味がありますか?少なくとも2つの非常に異なるサブフィールド、3Dグラフィックスとゲームプレイ(AIを含む)があります。私はグラフィックスの経験しかありませんが、データ構造と数学はグラフィックスとアルゴリズム、そしてより少ない範囲で非常に重要であると言えます。エンジンを使用している場合、これらのほとんどはもちろん処理されますが、3Dジオメトリの基本的な数学を理解する必要があります。
ガーデンヘッド

51

無数のマシンモデル(TM、RAM、PRAMなど)に無数のコスト測定(実行時間、メモリ使用量、キャッシュミス、分岐予測ミス、実装の複雑さ、検証の実現可能性など)があるという事実は別として、平均対最悪のケース、および相互に比較検討するための償却の考慮事項は、多くの場合、基本的な教科書の仕様の範囲を超えて機能的な違いもあります

いくつかの例:

  • Mergesortは、Quicksortがそうでない場合でも安定しています。
  • バイナリ検索ツリーでは、順序どおりの反復が行われますが、ハッシュテーブルでは行われません。
  • ベルマン・フォードは負のエッジ重みを処理できますが、ダイクストラは処理できません。

教訓的な考慮事項もあります。

  • より複雑なソリューションを理解するのは、より単純なソリューションよりも簡単ですか?(BSTなしのAVLツリー(およびその分析); Ford-FulkersonなしのDinic; ...)
  • 多くのソリューションにさらされている場合と比較して、問題ごとに1つのソリューションにしかさらされていない場合、同じ原則とパターンを見ますか?
  • 問題ごとに1つのソリューションのみに説明することで、十分なトレーニングが提供されますか(習得に向けて)
  • 解決策が見つかったことの幅を知っている必要があります(何度も何度も車輪の再発明を防ぐため)。
  • 問題ごとに1つのソリューションにしか触れていない場合、実際のプログラミングライブラリなどで実際に見つかっている他のソリューションを理解できますか?

  1. これは、自由に使えるリッチなCSツールボックスを持っていないプログラマーのタイプから多く見られるものです。

4
教訓的根拠を含めるための+1!いくつかの理論的根拠(特に2番目と3番目)に関連して、アルゴリズムとデータ構造の開発と最適化の方法を見ると、開発と最適化の手法とトレードオフの理解が得られます)。
ポールA.クレイトン

2
さらに考慮すべき点の1つは、さまざまな代替案を分析することで、おそらく通常とは異なる設定の新しいアルゴリズムを分析するための便利なツールの例を提供できることです。
フォンブランド

1
良い点、@ vonbrand。スプレイツリーの動作を理解するために、償却複雑度分析が考案されましたが、実際にはスプレイツリーはほとんど使用されません。とにかく、公開されているようなスプレイツリーではありません。Windows NTカーネルは、仮想メモリマップを実装するためにスプレイツリーを使用することで有名ですが、ルックアップごとに並べ替えるわけではありません。
仮名

1
@vonbrandはい。ただし、アルゴリズムクラスのツールボックスの次元に主に興味を持っている人が、その理由でsc笑するのは理解できます。
ラファエル

7

では、現実の世界、ある時点で、あなたは他の人のチームによって書かれたソフトウェアで作業する可能性があります。このソフトウェアのいくつかは、あなたが生まれる前に書かれているでしょう!

使用されるアルゴリズム/データ構造を理解するために、「最先端」と見なされなくなったオプションを含む多数のアルゴリズム/データ構造を知ることは非常に役立ちます。

また、標準ではなく、作業中のアプリケーションで使用されるだけのアルゴリズムに取り組む必要があります。これらのアルゴリズムを改善する必要があるとき、他の人がどのようにアルゴリズムを改善したかを研究したので、あなたの脳はアルゴリズムを改善する有用な方法で満たされていることがわかります。

これが、コンピューターサイエンスを研究した人と、プログラミングの方法を学んだばかりの人を区別するものです。私が働いてきたほとんどの仕事で、コンピューターサイエンスを勉強したときに「本から学んだ」プログラマーができない問題を解決できる時がありましたが、コンピューターサイエンスを勉強したことで私に利益がなかったことがわかった時間の95%他の経験豊富なプログラマーより


解決しようとしているものの95%が機械学習に関連している場合を除きます。通常のプログラマーが、実際のMLの問題が直面している問題のどれかを試行する適切な機会さえ得られるかどうかはわかりません。
ピノキオ

3
目標:5%よりも良い割合で仕事を得ます。
ラファエル

CSの学習は、アルゴリズムとデータ構造に関する知識を収集するための優れた方法であることを忘れないでください。コーディング最高の職業です-コーダーにとって。
-greybeard

5

多くの人々は、多くの場合、最適なアルゴリズムは存在しないことを正しく述べています。これは状況に依存します。

また、いつの日か不慣れな状況に出くわす可能性もあります。アルゴリズムが多くなればなるほど、ベースとして使用できるソリューションに近いものを知る可能性が高くなります。


5
この回答は、古いものからのポイントのみを繰り返します。
ラファエル

1

ラファエロの答えはこれにいくらか言及しているが、多くの素晴らしい答え、私が欠けていると思うものだけだ。

実装の容易さも考慮する必要があります。
ほとんどのプラットフォーム/言語には既に実装されているため(多くの場合、実行できるものよりも優れているため)、ソートアルゴリズムでは通常これは問題になりませんが、より珍しいアルゴリズムは利用できない場合があります。
問題によっては、実装時間が1週間対2週間の場合、絶対的な最適なアルゴリズムを必要としない場合があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.