O(n!)函数的示例(代码中)是什么?应该参考n运行适当数量的操作;也就是说,我在问时间的复杂性。
答案 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),
资料来源: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;
}
答案 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的调用次数)
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)
这是一个复杂度为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!)