O(n!)的例子?

时间:2010-10-17 12:37:48

标签: java algorithm big-o factorial asymptotic-complexity

O(n!)函数的示例(代码中)是什么?应该参考n运行适当数量的操作;也就是说,我在问时间的复杂性。

17 个答案:

答案 0 :(得分:73)

你去吧。这可能是在O(n!)时间内运行的函数最简单的例子(其中n是函数的参数):

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

答案 1 :(得分:38)

一个典型的例子是traveling salesman problem通过暴力搜索。

如果有N个城市,蛮力方法会尝试这些N城市的每一个排列,以找出哪个城市最便宜。现在N个城市的排列数量为N!,这使得它具有复杂性因子(O(N!))。

答案 2 :(得分:8)

请参阅Orders of common functions文章的Big O Wikipedia部分。

根据这篇文章,通过强力搜索解决traveling salesman problem并找到determinant expansion by minors都是O(n!)。

答案 3 :(得分:6)

存在一些问题,即 NP-complete (在非确定多项式时间内可验证)。意思是如果输入缩放,那么解决问题所需的计算量会增加很多。

一些 NP-hard问题是:Hamiltonian path problem open img ),Travelling salesman problem open img
一些 NP-complete问题是:Boolean satisfiability problem (Sat.) open img ),N-puzzle open img ),Knapsack problem({{ 3}}), open img Subgraph isomorphism problem), open img Subset sum problem), open img Clique problem), open img Vertex cover problem), open img Independent set problem), open img Dominating set problem), open img Graph coloring problem),

来源: open img link 1

alt text
资料来源:link 2

答案 4 :(得分:5)

我想我有点晚了,但我发现snailsort是O(n!)确定性算法的最好例子。它基本上找到了数组的下一个排列,直到它对它进行排序。

看起来像这样:

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

答案 5 :(得分:5)

通过未成年人的扩张找到决定因素。

非常好的解释here

# 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个文件there

答案 6 :(得分:4)

最简单的例子:)

伪代码:

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!)

你去:)

作为一个真实的例子 - 如何生成一组项目的所有排列?

答案 7 :(得分:4)

计算给定数组的所有排列的任何算法都是O(N!)。

答案 8 :(得分:3)

printf("Hello World");

是的,这是O(n!)。如果您认为不是,我建议您阅读BigOh的定义。

我只是添加了这个答案,因为人们不得不总是使用BigOh而不管他们的实际意思是什么。

例如,我很确定这个问题打算问Theta(n!),至少cn!步骤,不超过Cn!一些常数的步骤c,C> 0,但选择使用O(n!)代替。

另一个例子:Quicksort is O(n^2) in the worst case,虽然技术上是正确的(在最坏的情况下,甚至heapsort是O(n ^ 2)!),它们实际上意味着Quicksort is Omega(n^2) in the worst case

答案 9 :(得分:2)

在维基百科

通过暴力搜索解决旅行商问题;找到未成年人扩张的决定因素。

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

答案 10 :(得分:1)

在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;
}

答案 11 :(得分:1)

你是正确的递归调用应该正好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);
    }

答案 12 :(得分:0)

Bogosort是我遇到的唯一一个冒险进入O(n!)区域的“官方”。但它不是一个保证的O(n!),因为它本质上是随机的。

答案 13 :(得分:0)

你可能学习的用于获取矩阵行列式的递归方法(如果你采用线性代数)需要O(n!)时间。虽然我并不特别喜欢编码。

答案 14 :(得分:0)

@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);
}

答案 15 :(得分:0)

添加到k功能

这是一个复杂度为O(n!)的函数的简单示例,其中给出了一个int参数数组和一个整数k。如果数组x + y = k中有两项,则返回true,例如:如果tab为[1、2、3、4]且k = 6,则返回值为true,因为2 + 4 = 6

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);
    }

答案 16 :(得分:0)

最简单的例子是阶乘函数:

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

O(n!)