タグ付けされた質問 「algorithm-analysis」

アルゴリズムの特性を決定する科学と芸術に関する質問。多くの場合、正確性、実行時間、スペースの使用法が含まれます。アルゴリズムのランタイムに関する質問には、[runtime-analysis]タグを使用します。

3
アルゴリズム分析の魔法の背後にあるシステムはありますか?
アルゴリズムの実行時間を分析する方法については、多くの質問があります(たとえば、ランタイム分析およびアルゴリズム分析を参照)。多くは似ています。たとえば、ネストされたループのコスト分析や、分割統治アルゴリズムを求めるものですが、ほとんどの答えはオーダーメイドのようです。 一方、別の一般的な質問への回答では、いくつかの例を使用してより大きな全体像(特に漸近解析に関する)を説明していますが、手を汚す方法はありません。 アルゴリズムのコストを分析するための構造化された一般的な方法はありますか?コストは、実行時間(時間の複雑さ)、または実行された比較の数、スペースの複雑さなどのコストのその他の尺度である場合があります。 これは、初心者を指すのに使用できる参照質問になるはずです。したがって、通常よりも広い範囲です。少なくとも1つの例で説明されているが、多くの状況をカバーする、一般的で教訓的に提示された答えを与えるように注意してください。ありがとう!

13
「いくつかのテストケースを試す」ヒューリスティックを欺く方法:正しいように見えるが実際は正しくないアルゴリズム
ある問題のアルゴリズムが正しいかどうかをテストするための通常の出発点は、いくつかの単純なテストケースでアルゴリズムを手動で実行してみることです。 「。これは優れたヒューリスティックです。これは、アルゴリズムに対する誤った試行の多くを迅速に排除し、アルゴリズムが機能しない理由を理解するための優れた方法です。 ただし、アルゴリズムを学習するとき、一部の学生はそこでやめようとします:試行することを考えられるすべてのコーナーケースを含む少数の例でアルゴリズムが正しく機能する場合、アルゴリズムが正しい必要があると結論付けます。「いくつかのテストケースで試してみることができるのに、なぜアルゴリズムが正しいことを証明する必要があるのか​​」と尋ねる学生が常にいます。 それでは、「多数のテストケースを試す」ヒューリスティックをどのように欺くのでしょうか。このヒューリスティックでは不十分であることを示す良い例を探しています。言い換えれば、表面的には正しいように見えるアルゴリズムの1つ以上の例を探しており、だれかが思い付く可能性のあるすべての小さな入力に対して正しい答えを出力しますが、アルゴリズムは実際には動作しません。たぶん、アルゴリズムはたまたますべての小さな入力で正しく動作し、大きな入力に対してのみ失敗するか、異常なパターンを持つ入力に対してのみ失敗します。 具体的には、私は探しています: アルゴリズム。欠陥はアルゴリズムレベルである必要があります。実装のバグを探していません。(たとえば、最低限、この例は言語にとらわれず、ソフトウェアエンジニアリングや実装の問題ではなく、アルゴリズムの問​​題に関連する必要があります。) 誰かがもっともらしく思いつくかもしれないアルゴリズム。擬似コードは、少なくとももっともらしいように見えるはずです(たとえば、難読化された、または明らかに疑わしいコードは良い例ではありません)。宿題や試験の問題を解決しようとするときに、一部の学生が実際に思いついたアルゴリズムである場合、ボーナスポイントがあります。 妥当な手動テスト戦略に高い確率で合格するアルゴリズム。手作業でいくつかの小さなテストケースを試みる人は、欠陥を発見する可能性は低いはずです。たとえば、「12個の小さなテストケースで手動でQuickCheckをシミュレート」しても、アルゴリズムが正しくないことを明らかにすることはできません。 好ましくは、決定論的アルゴリズム。私は多くの学生が「手作業でいくつかのテストケースを試す」が決定論的アルゴリズムが正しいかどうかをチェックする合理的な方法であると考えているのを見てきましたが、ほとんどの学生はいくつかのテストケースを試すことは確率論を検証する良い方法だとは思わないでしょうアルゴリズム。確率的アルゴリズムの場合、特定の出力が正しいかどうかを確認する方法がないことがよくあります。また、出力分布に関する有用な統計テストを実行するのに十分な例をクランクすることはできません。したがって、決定論的アルゴリズムは学生の誤解の中心により明確になるため、決定論的アルゴリズムに焦点を当てることを好みます。 私はあなたのアルゴリズムが正しいことを証明することの重要性を教えたいです。そして、このようないくつかの例を使って、正当性の証明の動機付けを助けたいと思っています。私は比較的単純で学部生がアクセスしやすい例を好むでしょう。重い機械や数学的/アルゴリズム的背景を必要とする例はあまり有用ではありません。また、「不自然」なアルゴリズムも必要ありません。ヒューリスティックを欺くための奇妙な人工アルゴリズムを構築するのは簡単かもしれませんが、非常に不自然に見えるか、このヒューリスティックを欺くためだけに明らかなバックドアが構築されている場合、おそらく学生には納得しません。良い例はありますか?

6
数値の基本的な操作に一定の時間がかかると仮定するにはどうすればよいですか?
通常、アルゴリズムでは、数値の比較、加算、減算を気にしません-それらが時間実行されると仮定します。たとえば、比較ベースの並べ替えがであると言うときにこれを想定しが、数値が大きすぎてレジスタに収まらない場合、通常は配列として表現するため、基本操作には要素ごとに追加の計算が必要です。O (n log n )O(1)O(1)O(1)O(nlogn)O(nlog⁡n)O(n\log n) で2つの数値(または他のプリミティブな算術関数)の比較ができることを示す証拠はありますか?そうでない場合、比較ベースの並べ替えがと言っているのはなぜですか?O (n log n )O(1)O(1)O(1)O(nlogn)O(nlog⁡n)O(n\log n) SOの質問に答えたときにこの問題が発生し、遅かれ早かれbig-intを処理する必要があるため、アルゴリズムがはないことに気付きました。また、擬似多項式時間アルゴリズムではなく、でした。PO(n)O(n)O(n)PPP

4
(いつ)ハッシュテーブルルックアップはO(1)ですか?
ハッシュテーブルルックアップは一定の時間で動作するとよく言われます。ハッシュ値を計算すると、配列ルックアップのインデックスが得られます。しかし、これは衝突を無視します。最悪の場合、すべてのアイテムが同じバケットに到着し、ルックアップ時間は線形()になります。Θ(n)Θ(n)\Theta(n) ハッシュテーブルルックアップを本当にすることができるデータの条件はありますか?それは平均的にのみですか、またはハッシュテーブルにO (1 )最悪のケースルックアップを含めることができますか?O(1)O(1)O(1)O(1)O(1)O(1) 注:ここではプログラマーの視点から来ています。ハッシュテーブルにデータを格納すると、ほとんど常に文字列またはいくつかの複合データ構造であり、データはハッシュテーブルの有効期間中に変更されます。したがって、完璧なハッシュについての答えはありがたいですが、それらはかわいいですが、逸話的であり、私の観点からは実用的ではありません。 PSフォローアップ:ハッシュテーブル操作O(1)はどのようなデータですか?

5
最悪の場合、このソートアルゴリズムはΘ(n³)であり、Θ(n²)ではありませんか?
データ構造とアルゴリズムの講座を始めたばかりで、ティーチングアシスタントは整数の配列を並べ替えるための次の擬似コードを提供してくれました。 void F3() { for (int i = 1; i < n; i++) { if (A[i-1] > A[i]) { swap(i-1, i) i = 0 } } } 明確ではないかもしれませんが、ここではソートしようとしている配列のサイズです。nnnA いずれにしても、ティーチングアシスタントはクラスにこのアルゴリズムは時間(最悪の場合、私は信じている)であると説明しましたが、逆に並べ替えられた配列で何度も調べても、私には、ではなくであるように思われます。Θ (n 2)Θ (n 3)Θ(n3)Θ(n3)\Theta(n^3)Θ(n2)Θ(n2)\Theta(n^2)Θ(n3)Θ(n3)\Theta(n^3) 誰かがこれがΘ(n3)Θ(n3)Θ(n^3)ではなくΘ(n ^ 3)である理由を説明できΘ(n2)Θ(n2)Θ(n^2)ますか?

3
バイナリ検索が3項検索よりも高速なのはなぜですか?
バイナリ検索を使用して要素の配列を検索するには、最悪の場合、回の反復が必要です。これは、各ステップで検索スペースの半分をトリミングするためです。代わりに、「三分探索」を使用した場合、各反復で探索空間の3分の2を切り捨てるので、最悪の場合は反復が必要です...log 2 N log 3 N &lt; log 2 NNNNlog2Nlog2⁡N\log_2 Nlog3N&lt;log2Nlog3⁡N&lt;log2⁡N\log_3 N < \log_2 N 三項検索の方が速いように思えますが、なぜ二項検索を使用するのですか?

2
Reynolds&Tymannによる成長の定義の順序
カール・レイノルズとポール・タイマンが書いた「プリンセス・オブ・コンピューター・サイエンス」(2008)という本を読んでいます(Schaum's Outlinesから出版)。 2番目の章では、名前のリストを単純に反復処理し、リスト内で特定の名前が見つかった場合にTRUEを返す順次検索の例を使用してアルゴリズムを紹介します。 著者は続けて言っています(17ページ): 順次検索アルゴリズムの「成長の順序」はnであると言います。この表記はT(n)です。また、成長の順序がT(n)の一定の因子内にあるアルゴリズムは、シータがNLであると言います。「シーケンシャル検索のシータはnです。」問題のサイズはn(検索されるリストの長さ)です。 これを理解するのは本当に難しいと思います。この本はエラーに満ちているので、何かが欠けているのか、上記の段落にタイプミスがあるのか​​はわかりません。一般的な英語では、「... say」で終わる文はめったにありません。 私は非常に混乱しています。 Tは何の略ですか?本は説明しません。時間ですか、シータですか? 「NLのシータ」が「シーケンシャル検索のシータがnである」ことを意味する場合 Lは何の略ですか?「線形」または「長さ」? 出版社に説明を求めて書いた。彼らは私のメッセージを著者に転送すると言った。彼らは答えていない。私は他のソースも調べてみましたが、それでも何かを誤解しているというしつこい感じがします。したがって、この段落を解読するまで休むことはできません。 誰かがその本のコピーを持っており、その段落を理解している場合。次に、その段落が正確かどうか、または他の言葉で説明してもらえれば幸いです。ありがとう。

3
関数型言語のアルゴリズムの複雑さはどのようにモデル化されますか?
アルゴリズムの複雑さは、下位レベルの詳細に依存しないように設計されていますが、命令型モデルに基づいています。たとえば、ツリー内のノードへの配列アクセスや変更にはO(1)時間かかります。これは、純粋な関数型言語では当てはまりません。Haskellリストへのアクセスには直線的な時間がかかります。ツリー内のノードを変更するには、ツリーの新しいコピーを作成する必要があります。 次に、関数型言語のアルゴリズムの複雑さの代替モデリングが必要ですか?

4
「ソート度」の測定方法
配列の「ソート度」を測定する標準的な方法があるかどうか疑問に思っていますか?可能性のある反転の中央値を持つ配列は、最大限にソートされていないと見なされますか?つまり、基本的には、並べ替えまたは逆並べ替えのいずれかが可能な限り行われないということです。

2
素朴なシャッフルはどの程度漸近的に悪いのでしょうか?
各アイテムをランダムに選択された別のアイテムと交換して配列をシャッフルするこの「ナイーブ」アルゴリズムが正しく機能しないことはよく知られています。 for (i=0..n-1) swap(A[i], A[random(n)]); 具体的には、nnn回の反復のそれぞれで、n nnn選択肢の1つが(一様な確率で)行われるため、計算にはnnnnn^n可能な「パス」があります。可能な順列のn!n!n!は、パスの数に均等に分割されないnnnnn^nため、このアルゴリズムがそれぞれを生成することは不可能です!n!n!n!等しい確率の順列。(代わりに、いわゆるFischer-Yatesシャッフルを使用する必要があります。これは基本的に[0..nから乱数を選択する呼び出しを変更する]と[i..n)から乱数を選択する呼び出しです。それは私の質問には意味がありません。) 私が疑問に思っているのは、素朴なシャッフルはどの程度「悪い」のでしょうか?より具体的には、せるP(n)P(n)P(n)すべての順列及び組ことC(ρ)C(ρ)C(\rho)得られた順列生成ナイーブアルゴリズムを通じてパスの数であるρ∈P(n)ρ∈P(n)\rho\in P(n)、関数の漸近挙動が何を M(n)=n!nnmaxρ∈P(n)C(ρ)M(n)=n!nnmaxρ∈P(n)C(ρ)\qquad \displaystyle M(n) = \frac{n!}{n^n}\max_{\rho\in P(n)} C(\rho) そして m(n)=n!nnminρ∈P(n)C(ρ)m(n)=n!nnminρ∈P(n)C(ρ)\qquad \displaystyle m(n) = \frac{n!}{n^n}\min_{\rho\in P(n)} C(\rho)? 主な要因は、これらの値を「正規化」することです。ナイーブシャッフルが「漸近的に良好」であれば、 limn→∞M(n)=limn→∞m(n)=1limn→∞M(n)=limn→∞m(n)=1\qquad \displaystyle \lim_{n\to\infty}M(n) = \lim_{n\to\infty}m(n) = 1。 私は(私が見たいくつかのコンピューターシミュレーションに基づいて)実際の値は1から離れていると疑っていますが、が有限であるか、が0?これらの量の振る舞いについて何がわかっていますか?lim m (n )limM(n)limM(n)\lim M(n)limm(n)limm(n)\lim m(n)

4
OとΩは最悪の場合と最良の場合にどのように関係しますか?
今日の講義では、バイナリサーチを使ってソートされた配列の要素を見つけるための非常に簡単なアルゴリズムについて議論しました。要素の配列の漸近的な複雑さを判断するように求められました。nnn 私の考えは、は最悪の場合の操作の数であるため、より具体的にはまたはことは明らかです。しかし、たとえば、最初に検索された要素にヒットした場合など、より良い結果を得ることができます-下限はです。O(logn)O(log⁡n)O(\log n)O(log2n)O(log2⁡n)O(\log_2 n)log2nlog2⁡n\log_2 nΩ(1)Ω(1)\Omega(1) 通常、アルゴリズムの最悪の場合の入力のみを考慮するため、講師はソリューションをとして提示しました。Θ(logn)Θ(log⁡n)\Theta(\log n) しかし、最悪の場合のみを考えるとき、与えられた問題のすべての最悪の場合が同じ複雑さを持っているとき、と表記を持つことのポイントは何ですか(は私たちが必要なすべてでしょう?)。OOOΩΩ\OmegaΘΘ\Theta ここで何が欠けていますか?

3
ハードウェア/実装は、アルゴリズムの時間/空間の複雑さに影響しますか?
私はCSの学生でもないので、これはばかげた質問かもしれませんが、どうか私に耐えてください... プレコンピューター時代では、引き出しの配列のようなものでのみ配列データ構造を実装できます。値を抽出する前に、対応するインデックスでドロワーを見つける必要があるため、配列検索の時間の複雑さはバイナリ検索を想定。O(log(n))O(log(n))O(log(n)) しかし、コンピューターの発明は大きな違いをもたらしました。最近のコンピューターはRAMから非常に高速に読み取ることができるため、配列ルックアップの時間の複雑さはと考えています(技術的にはそうではありません。O(1)O(1)O(1) 別の例は、Python辞書です。誤って記述されたオーバーロードマジックメソッド(または、途方もなく不運、つまり、多くのハッシュ衝突を伴うキーで辞書アクセスの複雑さを得るかもしれませんが、通常はと推定されます。この場合、時間の複雑さは、Python辞書のハッシュテーブル実装と、ハッシュ関数のキーの実装の両方に依存します。O(n)O(n)O(n)__hash__O(1)O(1)O(1) これは、ハードウェア/実装がアルゴリズムの時間の複雑さに影響する可能性があることを意味しますか?(両方の例はアルゴリズムではなくデータ構造に関するものですが、後者は前者に基づいて構築されており、データ構造の時間の複雑さを聞いたことがないため、ここでは「アルゴリズム」という用語を使用しています) 私にとって、アルゴリズムは抽象的かつ概念的であり、時間/空間の複雑さなどの特性は、特定の方法で実装されているかどうかによって影響されるべきではありませんが、そうですか?

8
計算の複雑さに関する知識のないプログラマーになることは問題ですか?
私は大学で運動を割り当てられました。私はそれを家に持ち帰り、それを解決するためのアルゴリズムをプログラムしようとしました。 それから、私が思いついた最も些細なことを作り、講師に見せました。簡単な観察の後、彼は私のソリューションの実行時の複雑さは実現不可能であり、より効率的なものを示していると感じました。そして、計算の複雑さについて何も知らないプログラマーの伝統があります(私はそれらの1つでした)。

2
欲張りアルゴリズムが正しいことを証明する方法
私は正しいと思われる貪欲なアルゴリズムを持っていますが、よくわかりません。正しいかどうかを確認するにはどうすればよいですか?貪欲なアルゴリズムが正しいことを証明するために使用するテクニックは何ですか?一般的なパターンやテクニックはありますか? これが参考質問になることを願っています初心者に向けられるしています。したがって、通常よりも広い範囲です。少なくとも1つの例で説明されているが、多くの状況をカバーする、一般的で教訓的に提示された答えを与えるように注意してください。ありがとう!

2
Cのvoid型がempty / bottom型と類似していないのはなぜですか?
ウィキペディアと私が見つけた他のソースはvoid、空のタイプではなくユニットタイプとしてリストCのタイプを見つけました。void空の/下の型の定義によりよく適合するように思えるので、この混乱を見つけます。 void私が知る限り、値は存在しません。 戻り値の型がvoidの関数は、関数が何も返さないため、何らかの副作用しか実行できないことを指定します。 タイプのポインターvoid*は、他のすべてのポインタータイプのサブタイプです。また、void*C との間の変換は暗黙的です。 最後の点voidに、空の型であることの引数としてのメリットがあるかどうかはわかりvoid*ませんvoid。 一方、voidそれ自体は他のすべてのタイプのサブタイプではありません。これは、タイプがボトムタイプであるための要件であると言えます。
28 type-theory  c  logic  modal-logic  coq  equality  coinduction  artificial-intelligence  computer-architecture  compilers  asymptotics  formal-languages  asymptotics  landau-notation  asymptotics  turing-machines  optimization  decision-problem  rice-theorem  algorithms  arithmetic  floating-point  automata  finite-automata  data-structures  search-trees  balanced-search-trees  complexity-theory  asymptotics  amortized-analysis  complexity-theory  graphs  np-complete  reductions  np-hard  algorithms  string-metrics  computability  artificial-intelligence  halting-problem  turing-machines  computation-models  graph-theory  terminology  complexity-theory  decision-problem  polynomial-time  algorithms  algorithm-analysis  optimization  runtime-analysis  loops  turing-machines  computation-models  recurrence-relation  master-theorem  complexity-theory  asymptotics  parallel-computing  landau-notation  terminology  optimization  decision-problem  complexity-theory  polynomial-time  counting  coding-theory  permutations  encoding-scheme  error-correcting-codes  machine-learning  natural-language-processing  algorithms  graphs  social-networks  network-analysis  relational-algebra  constraint-satisfaction  polymorphisms  algorithms  graphs  trees 

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