一般に、O(N 4 ) がある場合、O(N 3 )、O(N 2 )、O(N)、および O(1)の用語も導入する必要があります。つまり、x 3、x 1、および x 0を曲線近似モデルに追加してみてください。
O(N!) があるこの特定のケースでは、非常に速く収束するように思われるため、私はアドバイスに従い、階乗部分のみを検討します。
ただし、いずれにせよ、実際に O(N!) がある場合は、推定する必要はありません。反復的な深化アプローチを使用してください。n=1,2,3,4,5,6,7... のケースをコンピューターに繰り返し実行させ、できる限り実行させます。
コンピューターの時間を無駄にしているように見えるかもしれませんが、それを分析すると、無駄な時間は取るに足らないものであることがわかります。たとえば、すでに n=12 であるため、n=13 の場合、必要な CPU C 13は 13*C 12、C 12 = 12*C 11などになります。測定値を導入すると、sum(C 13 ..C 0 )/C 13 = 1.082 となるため、0 から 13 までのすべての値に対して関数を実行すると、13 に対して実行するよりも 8% だけコストが高くなります。 N の値が大きいほど、このパーセンテージはさらに軽減されます。
更新:
複雑度レベルより下のすべてのべき乗に項を追加する必要がある理由:
複雑さが O(N 3 )の単純な 3 レベルのループを考えてみましょう。
void foo(int n) {
int i, j, k;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
for (k = 0; k < n; k++)
do_something(i, j, k);
}
foo(3);
do_something(i, j, k)
が n 3回呼び出されることは明らかです。
しかし、実行されるすべての命令を最初から考慮すると、関数の出入り、スタックの設定、およびその他の低レベルのタスクが 1 回実行されるよりもわかります。i=0
命令も 1 回実行されます。これらは、n 0コストに対応する命令です。
命令i < n
とは n 回呼び出されi++
、j=0
n 1項に対応します。
命令j < n
とは n 2回呼び出され、n 2 項に対応j++
します。k=0
まあ、など。
より複雑なケースも同じです。常に、複雑度レベルよりも下のすべての累乗に比例した回数実行される命令があります。
の測定に関してC(0) = 0
は、タイミングが十分に正確でないことが問題です。それは非常に小さいかもしれませんが、決して絶対的な 0 ではありません。
最後に、カーブ フィッティングが機能しない場合は、N が原因です。その場合のように、命令も実行されます (n-1)! 回、および (n-2!) 回など。