web-dev-qa-db-ja.com

プログラムでアルゴリズムのランダウ記法(Big Oまたはシータ記法)を見つける?

私は自分のアルゴリズムのLandau(Big O、Theta ...)表記を手作業で検索して、できる限り最適化されていることを確認するのに慣れていますが、関数が本当に大きく複雑になると、それがうまくいきます手作業では時間がかかりすぎます。また、人為的ミスが発生しやすくなります。

Codility(コーディング/アルゴエクササイズ)に少し時間を費やしましたが、提出されたソリューションのランダウ表記が(時間とメモリの両方で)提供されることに気付きました。

彼らはどうやってそれをしているのだろうと思っていました...どうしますか?

字句解析またはコードの解析以外の方法はありますか?

この質問は主にPHPおよびまたはJavaScriptに関するものですが、私はあらゆる言語と理論に開放されています。

11
Julien L

彼らはどうやってそれをしているのだろうと思っていました...どうしますか?

私はそれらが実際に推定 Big Oメジャーであると想像します...さまざまな問題サイズに対してプログラムを実行し、時間とスペースの使用状況を測定し、結果に曲線を適合させます。

このアプローチの問題は、Nが大きくなるにつれてコスト関数の形状が変化した場合に誤解するになる可能性があることです。例えば1000 N + N^1.5

字句解析またはコードの解析以外の方法はありますか?

字句解析と構文解析では不十分です。また、アルゴリズムの動作についても何らかの推論を行う必要があります。そして、以前は未知であったアルゴリズムに対してそれを自動的に行うことは困難です。

13
Stephen C

彼らはコードを分析することなくしてはなりません。

以下の複雑な人工的な「インフレ/デフレ」の例は、プログラムの実行時間を測定するだけではBig-Oを確実に推定するには不十分であることを証明しています

void lets_trick_runtime(int n) {
   if (n == 10 || n == 25 || n == 118) {
      // unfair speed-up
      do_precalculated_solution_in_constant_time(n);
      return;
   }
   if (n == 11 || n == 26 || n == 119) {
      // unfair slow-down
      do_some_fake_processing_in_n_cube_time(n);
      return;
   }
   // fair solution
   do_general_solution_in_quadratic_time(n);
}

上記の実行時間の見積もりは、偽の見積もり-事前に計算されたソリューションがあるnの値の一定時間とunfair slow-downが開始する値の3次時間-は「公平」ではない二次時間。

3
gnat

これは不可能だと思います。

固定数の異なる入力サイズでいくつかのテストを実行する場合、多項式を簡単に計算できます。これは、測定した実行時間を非常によく近似します。したがって、すべての可能なプログラムに対して多項式が得られます。つまり、P = NP(ええ!;))。

記号操作でそれを行おうとすると、halting problem。プログラムが停止するかどうかを決定することはできないため、実行時の複雑さを決定することはできません。

ただし、非常に特殊な場合があり、後者の方法が可能です。しかし、これらのケースはおそらくそれほど小さいものであり、努力が払われたのかどうかは疑問です。

1
SpaceTrucker

私の直感は、この問題の一般的な解決策は不可能だということです。主張するように、アルゴリズムを実行せずにアルゴリズムのランタイムについてアプリオリ事実を表明します(語彙分析をほのめかします)。とは言っても、(おそらく大きい)アルゴリズムのクラスのヒューリスティックアルゴリズムは常に可能ですが、これを行う一般的なアルゴリズムはEntscheidungsproblemを解くことと同等です。これは不可能であることがよく知られています(Church、Turingなどを参照)。私はそれについて考えた今、私はこれの〜99.9%確信しています...

0
veryfoolish

どうすればいいですか?私が座ってほしくないほとんどすべての問題を解決する方法solve。シミュレートします。

多くの問題では、さまざまなサイズを使用してアルゴリズムを何度も実行し、回帰曲線をそれらの結果に適合させるだけで十分な場合があります。これにより、アルゴリズムの特定の「固定」オーバーヘッドコスト(曲線の切片)と、問題のサイズが大きくなるにつれてどのようにスケーリングするかをすばやく特定できます。

特に複雑なソリューションをキャプチャするには、いじくり回す必要がありますが、特に大まかな見積もりを探しているだけの場合は、その方法でそれを取得し、見積もりが実際の結果とどのように異なるかを確認して、それがそうであるかどうかを判断できます。許容できる近似。

この方法での私の心の最大の弱点は、アルゴリズムのスケーリングがreally不十分である場合、その最初の「全体を何度も実行する」ステップが醜くなることです。しかし、率直に言って、それは事実であり、それだけで、後戻りして再考したいと思う指標になるはずです。

0
Fomite