web-dev-qa-db-ja.com

2 ^ nのBig Oの例

したがって、ネストされたforループの数だけで、n ^ cの複雑さを持つアルゴリズムが何であるかを想像できます。

for (var i = 0; i < dataset.len; i++ {
    for (var j = 0; j < dataset.len; j++) {
        //do stuff with i and j
    }
}

ログは毎回データセットを半分に分割するもので、バイナリ検索はこれを行います(このコードがどのように見えるかは完全にはわかりません)。

しかし、c ^ nまたはより具体的には2 ^ nであるアルゴリズムの簡単な例は何ですか。 O(2 ^ n)はデータのループに基づいていますか?または、データはどのように分割されますか?それとも完全に何か?

21
dlkulp

実行時間O(2 ^ N)のアルゴリズムは、サイズN-1の2つの小さな問題を再帰的に解くことにより、サイズNの問題を解決する再帰的アルゴリズムであることがよくあります。

このプログラムは、たとえば、擬似コードのN個のディスクの有名な「ハノイの塔」問題を解決するために必要なすべての動きを出力します。

_void solve_hanoi(int N, string from_peg, string to_peg, string spare_peg)
{
    if (N<1) {
        return;
    }
    if (N>1) {
        solve_hanoi(N-1, from_peg, spare_peg, to_peg);
    }
    print "move from " + from_peg + " to " + to_peg;
    if (N>1) {
        solve_hanoi(N-1, spare_peg, to_peg, from_peg);
    }
}
_

T(N)をN個のディスクにかかる時間とします。

我々は持っています:

_T(1) = O(1)
and
T(N) = O(1) + 2*T(N-1) when N>1
_

最後の用語を繰り返し展開すると、次のようになります。

_T(N) = 3*O(1) + 4*T(N-2)
T(N) = 7*O(1) + 8*T(N-3)
...
T(N) = (2^(N-1)-1)*O(1) + (2^(N-1))*T(1)
T(N) = (2^N - 1)*O(1)
T(N) = O(2^N)
_

これを実際に把握するには、繰り返し関係の特定のパターンが指数関数的な結果につながることを知る必要があります。通常、T(N) = ... + C*T(N-1)は_C > 1_でO(x ^ N)を意味します。見る:

https://en.wikipedia.org/wiki/Recurrence_relation

24
Matt Timmermans

たとえばセットのすべての可能なサブセットを反復処理します。この種のアルゴリズムは、一般的なナップザック問題などに使用されます。

サブセットの反復がO(2 ^ n)に変換される方法を理解するのが難しい場合は、n個のスイッチのセットを想像してください。各スイッチはセットの1つの要素に対応しています。これで、各スイッチをオンまたはオフにできます。 「オン」はサブセット内にあると考えてください。可能な組み合わせの数に注意してください:2 ^ n。

コードで例を参照したい場合、ここでは再帰について考えるのが通常は簡単ですが、od他のニースで不安定な例は今のところ考えられません。

10
Marandil
  int Fibonacci(int number)
 {
  if (number <= 1) return number;

  return Fibonacci(number - 2) + Fibonacci(number - 1);
 }

入力データセットへの追加ごとに成長が倍増します。 O(2N)関数の成長曲線は指数関数的です-非常に浅いところから始まり、その後、気象的に上昇します。

public void solve(int n, String start, String auxiliary, String end) {
   if (n == 1) {
       System.out.println(start + " -> " + end);
   } else {
       solve(n - 1, start, end, auxiliary);
       System.out.println(start + " -> " + end);
       solve(n - 1, auxiliary, start, end);
   }

この方法では、プログラムは「ハノイの塔」問題を解決するためにすべての動きを印刷します。どちらの例も再帰を使用して問題を解決しており、O(2 ^ n)の実行時間が長くなりました。

1
darthir21

c ^ N = nサイズのアルファベットのc要素のすべての組み合わせ。

より具体的には、2 ^ NはすべてNビットで表現可能な数値です。

一般的なケースは、次のような再帰的に実装されます。

vector<int> bits;
int N
void find_solution(int pos) {
   if (pos == N) {
     check_solution();
     return;
   }
   bits[pos] = 0;
   find_solution(pos + 1);
   bits[pos] = 1;
   find_solution(pos + 1);
}
0
Sorin

以下は、goods配列のすべての値の組み合わせの値の合計を計算するコードクリップです(valueはグローバル配列変数です)。

fun boom(idx: Int, pre: Int, include: Boolean) {
    if (idx < 0) return
    boom(idx - 1, pre + if (include) values[idx] else 0, true)
    boom(idx - 1, pre + if (include) values[idx] else 0, false)
    println(pre + if (include) values[idx] else 0)
}

ご覧のとおり、再帰的です。ループを挿入してPolynomialの複雑度を取得し、再帰を使用してExponentialの複雑度を取得できます。

0
boileryao

python Big O/Landau(2 ^ N)の2つの簡単な例を示します。

#fibonacci 
def fib(num):    
    if num==0 or num==1:
        return num
    else:
        return fib(num-1)+fib(num-2)

num=10
for i in range(0,num):
    print(fib(i))


#tower of Hanoi
def move(disk , from, to, aux):
    if disk >= 1:
        # from twoer , auxilart 
        move(disk-1, from, aux, to)
        print ("Move disk", disk, "from rod", from_rod, "to rod", to_rod)
        move(disk-1, aux, to, from)

n = 3
move(n, 'A', 'B', 'C')
0
grepit