¿Qué es un ejemplo (en código) de una función O (n!)? Debe ejecutar el número apropiado de operaciones en referencia a n; es decir, estoy preguntando sobre la complejidad del tiempo.Ejemplo de O (n!)?
Respuesta
Ahí lo tiene. Este es probablemente el ejemplo más trivial de una función que se ejecuta en el tiempo O(n!)
(donde n
es el argumento de la función):
void nFacRuntimeFunc(int n) {
for(int i=0; i<n; i++) {
nFacRuntimeFunc(n-1);
}
}
Dado que este es un cálculo uno a uno de n !, esta es * la misma definición * de O (n!) Orden de crecimiento. –
¿no es esta O (N)? –
Pensándolo bien, ¿afectará el método recursivo nFac a la complejidad temporal de este algoritmo? –
Un ejemplo clásico es el traveling salesman problem a través de la búsqueda de fuerza bruta.
Si hay N
ciudades, el método de fuerza bruta probará todas y cada una de las permutación de estas ciudades N
para encontrar cuál es la más barata. Ahora el número de permutaciones con N
ciudades es N!
haciendo su complejidad factorial (O(N!)
).
No vi DV, pero tal vez es porque no tiene código de muestra, y la notación de big-o no se proporciona ... – aioobe
@aioobe: ya que la pregunta es "¿Qué es un problema de O (n!)" Y la respuesta es "aquí hay uno", no creo que tengas que decir O (n!) explícitamente ... – Claudiu
Imagina 3 ciudades. Para verificar cualquier ruta potencial, debe verificar la distancia entre dos ciudades dos veces. A-> B y B-> C. Tienes que comenzar desde las 3 esquinas. Sume la distancia en la primera ciudad, por lo que en total son 3 cheques, luego sume la distancia de la 2da ciudad a la 3ra para un total de 6 cheques. ¡eso es 3! = 6. Haga esto para 4 ciudades y los cheques pasen a 24. –
el ejemplo más simple :)
pseudocódigo:
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!)
ahí va :)
Como un ejemplo real: ¿qué hay de generar todas las permutaciones de un conjunto de elementos?
Encontrar el determinante con expansión por menores.
Muy buena explicación 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;
}
Código de here. También encontrará los archivos .hpp
necesarios there.
Hay problemas, que son NP-complete
(verificables en tiempo polinominal no determinista). Es decir, si las escalas de entrada, su cálculo necesario para resolver el problema aumenta más que un montón.
Algunos NP-hard
problemas son: Hamiltonian path problem ( open img), Travelling salesman problem ( open img)
Algunos NP-complete
problemas son: Boolean satisfiability problem (Sat.) ( open img), N-puzzle ( open img), Knapsack problem ( 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),
Fuente: link
NP significa Nondeterministic ** Polynomial **, que significa más rápido que el tiempo exponencial (pero solo en teoría). Factorial es más lento que exponencial, en teoría y en práctica. Entonces, esto es totalmente irrelevante. – Potatoswatter
Consulte la sección Orders of common functions del artículo Big O Wikipedia.
De acuerdo con el artículo, resolver el traveling salesman problem a través de la búsqueda de fuerza bruta y encontrar el determinant con expansion by minors son ambos O (n!).
En Wikipedia
Resolver el problema del viajante de comercio a través de la búsqueda de fuerza bruta; encontrar el determinante con la expansión de menores.
http://en.wikipedia.org/wiki/Big_O_notation#Orders_of_common_functions
Creo que estoy un poco tarde, pero creo que snailsort es el mejor ejemplo del algoritmo determinista O (n!). Básicamente encuentra la siguiente permutación de una matriz hasta que la ordena.
Parece que este:
template <class Iter>
void snail_sort(Iter first, Iter last)
{
while (next_permutation(first, last)) {}
}
¡Desde n! se puede definir como la cantidad de formas de permutar una lista de n objetos, este es mi ejemplo favorito, aunque el pseudocódigo sería mejor que C++. ;) – clocksmith
No es del todo obvio que esto tome O (n!) Tiempo. 'next_permutation' toma tiempo lineal, por lo que un cálculo ingenuo da O (n * n!) tiempo (que es estrictamente mayor que O (n!)). Debes argumentar que 'next_permutation' toma O (1) tiempo en promedio para que esto funcione. –
Vale la pena señalar que esto funciona porque 'next_permutation' devuelve la próxima permutación lexicográfica y devuelve verdadero, o devuelve el más pequeño (que es la permutación clasificada) y devuelve falso si no existe una próxima permutación. – Dukeling
El método recursivo que probablemente aprendió por tomarse el determinante de una matriz (si se toma el álgebra lineal) toma tiempo O (n!). Aunque particularmente no tengo ganas de codificar todo eso.
Cualquier algoritmo que calcule toda la permutación de una matriz dada es O (N!).
En C#
¿No sería esto O (N!) En la complejidad del espacio? porque, la cadena en C# es inmutable.
string reverseString(string orgString) {
string reversedString = String.Empty;
for (int i = 0; i < orgString.Length; i++) {
reversedString += orgString[i];
}
return reversedString;
}
printf("Hello World");
Sí, esto es O (n!). Si crees que no es así, te sugiero que leas la definición de BigOh.
Solo agregué esta respuesta debido al hábito molesto que las personas tienen que usar siempre BigOh independientemente de lo que realmente signifiquen.
Por ejemplo, estoy bastante seguro de que la pregunta tenía como objetivo preguntar a Theta (n!), Al menos cn! pasos y no más que Cn! pasos para algunas constantes c, C> 0, pero eligió usar O (n!) en su lugar.
Otra instancia: Quicksort is O(n^2) in the worst case
, aunque técnicamente correcta (¡Even heapsort es O (n^2) en el peor de los casos!), Lo que en realidad quieren decir es Quicksort is Omega(n^2) in the worst case
.
Aunque es matemáticamente verdadero, la notación O (n) se usa de manera general casi todo el tiempo, incluso para aquellos que * saben * mejor.En particular, se considera engañoso utilizar una clase O superior a la estrictamente necesaria; entonces ningún practicante se referirá a un algoritmo O (n) como O (n²), aunque cualquier algoritmo que esté en O (n) también (por definición) en O (n²) – tucuxi
Esto parece más apropiado como comentario que una respuesta, ya que se limita a señalar un tecnicismo en la pregunta y claramente pasa por alto lo que se preguntó. – Dukeling
@clocksmith Tienes toda la razón. Esto no está calculando n !. Tampoco es de O (n!). Lo ejecuté recolectó los datos en la tabla a continuación. Por favor compare la columna 2 y tres. (#nF es la cantidad de llamadas a 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
Así que claramente si funciona mucho peor que O (n!). A continuación se muestra un código de muestra para calcular n! recursivamente. notarás que es de orden O (n).
int Factorial(int n)
{
if (n == 1)
return 1;
else
return n * Factorial(n-1);
}
Tiene razón, las llamadas recursivas deberían tomar exactamente n! hora. aquí hay un código como para probar el tiempo factorial para n valores diferentes. ¡El lazo interno corre para n!tiempo para diferentes valores de j, por lo que la complejidad de bucle interior es 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;
}
}
Éstos son el resultado de la prueba para n = 5, es iterar tiempo exactamente factorial.
N Fn N!
1 1 1
2 2 2
3 6 6
4 24 24
5 120 120
Función exacta con la complejidad del tiempo 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. ¿Podemos calcular esto en menos de O (n * n) ... (nlogn o n)
- 2. ¿Es O (log n) siempre más rápido que O (n)
- 3. Ejemplo de arquitectura de 4 niveles (para N-Tier)?
- 4. Big-O complejidad de c^n + n * (log n)^2 + (10 * n)^c
- 5. Obtiene n objetos aleatorios (por ejemplo 4) de nsarray
- 6. Diferencia entre O (n) y O (log (n)) - ¿cuál es mejor y qué es exactamente O (log (n))?
- 7. lo hace O (N) significa
- 8. ¿Qué es O (log * N)?
- 9. ¿Se pueden ordenar n enteros en O (n) complejidad amortizada?
- 10. ¿Por qué está ordenando una cadena O (n log n)?
- 11. ¿Cuál es la diferencia entre '\ n' o "\ n" en C++?
- 12. Regex para despojar \ r \ n o \ r \ n
- 13. ¿Existe un término abreviado para O (n log n)?
- 14. Algún algoritmo de ordenación de O (n)
- 15. Cualquier idea de cómo transformar este O (n^2) algo en un O (n)
- 16. Erlang corba tutorial o ejemplo?
- 17. NSString con \ n o salto de línea
- 18. transformando de 'S' o 'N' al bit
- 19. Unparse AST <O (exp (n))?
- 20. Error de sintaxis, inesperado '\ n', esperando tCOLON2 o '[' o '.'
- 21. Ejemplo de implementación de 'TryParse' o 'TryGetValue'
- 22. ¿Qué compila para un código más rápido: "n * 3" o "n + (n * 2)"?
- 23. ¿Cuál es la prueba de (N-1) + (N-2) + (N-3) + ... + 1 = N * (N-1)/2
- 24. ¿Qué significa O (log (log (n)))) - competitivo?
- 25. Contando subseries palindrómicas en O (n)
- 26. SPOJ ARRAYSUB: O (n) Complejidad Enfoque
- 27. Casting Y o N to bool C#
- 28. ¿Cambia el bit O (1) u O (n)?
- 29. ¿Qué significa esto: O (n) pasos y O (1) espacio?
- 30. ¿Debería considerar memmove() O (n) u O (1)?
http://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/ –
Para ser pedante, que quiere decir Ω (n!) [Límite inferior sobre crecimiento asintótico] o "tiempo proporcional a n!" [superior e inferior], no O (n!) [límite superior en crecimiento asintótico]. Como O (n!) Es solo el límite superior, muchos algoritmos son O (n!) De forma poco interesante, porque son O (n) u O (n log n) u O (1) o algo así. – jacobm