web-dev-qa-db-ja.com

O(n!)?の例?

O(n!)関数の例(コード内)とは何ですか? nを参照して実行するには、適切な数の操作が必要です。つまり、時間の複雑さについて尋ねています。

51
Derek Long

行くぞこれは、おそらくO(n!)時間(nは関数の引数です)で実行される関数の最も単純な例です。

void nFacRuntimeFunc(int n) {
  for(int i=0; i<n; i++) {
    nFacRuntimeFunc(n-1);
  }
}
75
sepp2k

古典的な例の1つは、ブルートフォース検索による 巡回セールスマン問題 です。

N都市がある場合、ブルートフォースメソッドは、これらのN都市のすべての順列を試行して、最も安い都市を見つけます。 N cityの順列の数は_N!_であるため、複雑さの要因となります(O(N!))。

38
codaddict

Big O Wikipedia の記事の 共通機能の順序 セクションを参照してください。

記事によると、ブルートフォース検索で 巡回セールスマン問題 を解き、 決定子未成年者による拡大 で見つけることは両方ともO(n! )。

8
Bill the Lizard

問題があります。NP-complete(非決定的な多項式時間で検証可能)。入力がスケールする場合、つまり、問題を解決するために必要な計算が大幅に増えます。

一部NP-hard問題ハミルトニアンパス問題open img )、 旅行セールスマン問題開くimg
一部NP-complete問題ブール充足可能性問題(土)open img )、 N-パズルopen img )、 ナップザック問題open img )、 サブグラフ同型問題open img )、 サブセット和問題open img )、 クリーク問題open img )、- 頂点カバー問題open img )、 独立セット問題open img )、 セット問題の支配imgを開く )、 グラフの色付けの問題imgを開く )、

ソース: リンク1リンク2

alt text
出典: link

6
Margus

未成年者による展開で行列式を見つける。

非常に良い説明 ここ

# include <cppad/cppad.hpp>
# include <cppad/speed/det_by_minor.hpp>

bool det_by_minor()
{   bool ok = true;

    // dimension of the matrix
    size_t n = 3;

    // construct the determinat object
    CppAD::det_by_minor<double> Det(n);

    double  a[] = {
        1., 2., 3.,  // a[0] a[1] a[2]
        3., 2., 1.,  // a[3] a[4] a[5]
        2., 1., 2.   // a[6] a[7] a[8]
    };
    CPPAD_TEST_VECTOR<double> A(9);
    size_t i;
    for(i = 0; i < 9; i++)
        A[i] = a[i];


    // evaluate the determinant
    double det = Det(A);

    double check;
    check = a[0]*(a[4]*a[8] - a[5]*a[7])
          - a[1]*(a[3]*a[8] - a[5]*a[6])
          + a[2]*(a[3]*a[7] - a[4]*a[6]);

    ok = det == check;

    return ok;
}

here のコード。また、必要な.hppファイル あり

5
Jungle Hunter

特定の配列のすべての順列を計算するアルゴリズムは、O(N!)です。

5
John

私は少し遅れていると思うが、 snailsort はO(n!)決定論的アルゴリズムの最良の例であると思う。基本的に、並べ替えるまで、配列の次の順列を見つけます。

次のようになります。

template <class Iter> 
void snail_sort(Iter first, Iter last)
{
    while (next_permutation(first, last)) {}
}
5
Gabi Purcaru

最も簡単な例:)

擬似コード:

input N
calculate N! and store the value in a vaiable NFac - this operation is o(N)
loop from 1 to NFac and output the letter 'z' - this is O(N!)

そこに行きます:)

実際の例として-アイテムのセットのすべての順列を生成するのはどうですか?

4
Armen Tsirunyan

printf("Hello World");

はい、これはO(n!)です。そうでないと思われる場合は、BigOhの定義を読むことをお勧めします。

この答えを追加したのは、人々が実際に何を意味しているかに関係なく、常にBigOhを使用しなければならない迷惑な習慣があるからです。

たとえば、少なくともcn!という質問はTheta(n!)に尋ねることを意図したものです。 Cnを超えないステップ数!いくつかの定数c、C> 0のステップですが、代わりにO(n!)を使用することを選択しました。

別のインスタンス:Quicksort is O(n^2) in the worst case、技術的には正しいが(最悪の場合でもヒープソートはO(n ^ 2)!)、実際に意味するのはQuicksort is Omega(n^2) in the worst caseです。

3
Aryabhatta

ウィキペディアで

総当たり検索による巡回セールスマン問題の解決。未成年者による展開で行列式を見つける。

http://en.wikipedia.org/wiki/Big_O_notation#Orders_of_common_functions

C#で

スペースの複雑さにおいてこれはO(N!)ではないでしょうか?なぜなら、C#の文字列は不変だからです。

string reverseString(string orgString) {
    string reversedString = String.Empty;

    for (int i = 0; i < orgString.Length; i++) {
        reversedString += orgString[i];
    }

    return reversedString;
}
1
user623429

再帰呼び出しは正確にnを要するはずです。時間。これは、n個の異なる値の階乗時間をテストするようなコードです。内部ループはnで実行されます! jの異なる値の時間、したがって内部ループの複雑さはBig O(n!)

public static void NFactorialRuntime(int n)
    {
        Console.WriteLine(" N   Fn   N!");
        for (int i = 1; i <= n; i++)  // This loop is just to test n different values
        {
            int f = Fact(i);
            for (int j = 1; j <= f; j++)  // This is Factorial times
            {  ++x; }
            Console.WriteLine(" {0}   {1}   {2}", i, x, f);
            x = 0;
        }
    }

N = 5のテスト結果は次のとおりです。正確に階乗時間を繰り返します。

  N   Fn   N!
  1   1   1
  2   2   2
  3   6   6
  4   24   24
  5   120   120

時間の複雑さnを持つ正確な関数!

// Big O(n!)
public static void NFactorialRuntime(int n)
    {
        for (int j = 1; j <= Fact(i); j++) {  ++x; }
        Console.WriteLine(" {0}   {1}   {2}", i, x, f);
    }
1
techdips

おそらく行列の行列式を取得するために学習した再帰的方法(線形代数を取得した場合)はO(n!)時間かかります。私は特にそれをすべてコーディングする気はしませんが。

0
user477556

@clocksmithあなたは絶対に正しいです。これはn!を計算していません。 O(n!)でもありません。下の表のデータを収集して実行しました。列2と3を比較してください。 (#nFはnFacRuntimeFuncの呼び出し回数です)

n #nF n!

0    0      1
1    1      1
2    4      2
3    15     6
4    65     24
5    325    120
6    1956   720
7    13699  5040

したがって、O(n!)よりもパフォーマンスがはるかに悪い場合は明らかです。以下は、nを計算するためのサンプルコードです。再帰的に。そのO(n)順序。

int Factorial(int n)
{
   if (n == 1)
      return 1;
   else
      return n * Factorial(n-1);
}
0
user3416507

Up k関数に追加

これは、パラメーターintと整数kの配列が与えられた複雑さO(n!)を持つ関数の簡単な例です。配列x + y = kから2つの項目がある場合、trueを返します。たとえば、tabが[1、2、3、4]およびk = 6の場合、2 + 4 = 6であるため、戻り値はtrueになります。

public boolean addToUpK(int[] tab, int k) {

        boolean response = false;

        for(int i=0; i<tab.length; i++) {

            for(int j=i+1; j<tab.length; j++) {

                if(tab[i]+tab[j]==k) {
                    return true;
                }

            }

        }
        return response;
    }

ボーナスとして、これはjUnitを使用した単体テストであり、正常に動作します

@Test
    public void testAddToUpK() {

        DailyCodingProblem daProblem = new DailyCodingProblemImpl();

        int tab[] = {10, 15, 3, 7};
        int k = 17;
        boolean result = true; //expected result because 10+7=17
        assertTrue("expected value is true", daProblem.addToUpK(tab, k) == result);

        k = 50;
        result = false; //expected value because there's any two numbers from the list add up to 50
        assertTrue("expected value is false", daProblem.addToUpK(tab, k) == result);
    }
0
Achraf Bellaali

これの最も簡単な例は階乗関数です:

function factorial(n){
    let fact=1;
    for(var i=1; i<=n;i++){
        fact=fact*i;
    }
    return fact;
}

O(n!)

0
Mayank Tolani

Bogosort は、私が遭遇した唯一の「公式」なもので、O(n!)エリアへの冒険です。しかし、それは本質的にランダムであるため、保証されたO(n!)ではありません。

0
MdaG