Algoritmos: explicación sobre complejidad y optimización

Estoy tratando de encontrar una fuente o dos en la web que los expliquen en términos simples. Además, ¿se puede utilizar esta noción de manera práctica para mejorar un algoritmo? ¿Si es así, cómo? A continuación se muestra una breve explicación que recibí de un contacto.

No sé dónde puede encontrar una explicación simple. Pero trato de explicarte. La complejidad del algoritmo es un término que explica la dependencia entre la información de entrada y los recursos que necesitan procesarla. Por ejemplo, si necesita encontrar max en la matriz, debe enumerar todos los elementos y compararlos con su variable (por ejemplo, max). Suponga que hay N elementos en una matriz. Entonces, la complejidad de este algoritmo es O (N), porque enumeramos todos los elementos por una vez. Si enumeramos todos los elementos 2 veces, la complejidad será O (N * N). La búsqueda binaria tiene complejidad O (log2 (N)), porque su área de búsqueda disminuye a la mitad durante cada paso. Además, puede calcular la complejidad espacial de su algoritmo: dependencia entre el espacio, requerido por el programa, y ​​la cantidad de datos de entrada.

preguntado el 09 de enero de 11 a las 00:01

"Si enumeramos todos los elementos 2 veces, la complejidad será O (N * N)". Enumerar dos veces es (O(2*N) o en realidad) O(N). -

Las primeras 60 páginas de un libro sobre algoritmos lo explicarán todo. -

6 Respuestas

No es fácil decir todas las cosas sobre la complejidad, pero creo que wiki tiene una buena explicación y para el inicio es bueno, consulte:

  1. Gran notación para introducir este aspecto (también puede ver las notaciones teta y omega).
  2. Análisis de algoritmo, para saber más sobre la complejidad.
  3. Y también debes Complejidad computacional, que es una gran teoría en informática.

y acerca de la optimización, puede buscar en la web y la wiki para encontrarlo, pero con cinco líneas sus amigos dan una buena muestra para la introducción, pero estos no son un esfuerzo de una noche para comprender su uso, cálculo y miles de teorías.

En total, puede estar familiarizado con ellos según sea necesario, leyendo wiki, leyendo libros más avanzados como Gary y Johnson o leer Complejidad computacional, un enfoque moderno, pero no espere que sepa todo sobre ellos después de eso. También puedes ver estas notas de clase: http://www.cs.rutgers.edu/~allender/lecture.notes/.

Respondido el 09 de enero de 11 a las 16:01

Como insinuó su amigo, este no es un tema simple. Pero vale la pena invertir algo de tiempo para aprender. Verificar este libro, comúnmente utilizado como libro de texto en cursos de informática sobre algoritmos.

Respondido el 09 de enero de 11 a las 03:01

El lector del curso utilizado en las clases de introducción a la programación de Stanford tiene un gran capítulo sobre análisis algorítmico del legendario educador de informática Eric Roberts. Todo el texto está en línea en este enlace, y podría valer la pena ver el Capítulo 8.

Respondido el 09 de enero de 11 a las 03:01

Tú puedes ver Estructura e interpretación de programas informáticos. Es un buen curso del MIT.

Respondido el 09 de enero de 11 a las 03:01

Also, can this notion be used in a practical fashion to improve an algorithm? If so, how?

No se usa tanto para mejorar un algoritmo, sino para evaluar el rendimiento de los algoritmos y decidir qué algoritmo elige usar. Para cualquier problema dado, realmente desea evitar algoritmos que tengan O (N!) U O (N ^ x), ya que disminuyen drásticamente cuando aumenta el tamaño de N (su entrada). Lo que quieres es O (N) u O (log (N)) o incluso mejor O (1).

O (1) es un tiempo constante, lo que significa que el algoritmo tarda la misma cantidad de tiempo en ejecutarse para un millón de entradas que para una. O (N) es, por supuesto, lineal, lo que significa que el tiempo que se tarda en ejecutar el algoritmo aumenta en proporción a su entrada.

Incluso hay algunos problemas en los que cualquier algoritmo desarrollado para resolverlos termina siendo O (N!). Básicamente, no se puede desarrollar un algoritmo rápido para resolver el problema por completo (esta clase de problemas se conoce como NP-completo). Una vez que se dé cuenta de que está lidiando con un problema de este tipo, puede relajar un poco sus requisitos y resolver el problema de manera imperfecta "haciendo trampa". Estos trucos no necesariamente encuentran la solución óptima, sino que se conforman con lo suficientemente bueno. Mis trucos favoritos son los algoritmos genéticos / evolutivos y las tablas de arco iris.

Otro ejemplo de cómo la comprensión de la complejidad algorítmica cambia su forma de pensar sobre la programación son las microoptimizaciones. O mejor dicho, no hacerlo. A menudo ves a novatos haciendo preguntas como is ++x faster than x++. A los programadores experimentados en su mayoría no les importa y normalmente responderán the first rule of optimization is: don't.

La respuesta más útil debería ser que cambiar x++ a ++x no altera de ninguna manera la complejidad de su algoritmo. La complejidad de su algoritmo tiene un impacto mucho mayor en la velocidad de su código que cualquier forma de microoptimización. Por ejemplo, es mucho más productivo para usted mirar su código y reducir el número de bucles for profundamente anidados que preocuparse por cómo su compilador convierte su código en ensamblador.

Otro ejemplo más es cómo, en la programación de juegos, acelerar el código implica agregar aún más código en lugar de reducirlo. El código agregado está en forma de filtros (básicamente declaraciones if..else) que decide qué bit de datos necesita procesamiento adicional y cuál puede descartarse. Forme un punto de vista de micro-optimizador, agregar código significa más instrucciones para que la CPU las ejecute. Pero en realidad, esos filtros reducen el espacio del problema al descartar datos y, por lo tanto, se ejecutan más rápido en general.

Respondido el 09 de enero de 11 a las 03:01

Por supuesto, comprenda las estructuras de datos, los algoritmos y big-O.
Diseñe el código con cuidado y bien, manteniéndolo lo más simple posible.

Pero eso no es suficiente.

La clave para optimizar es saber cómo encontrar problemas, después de que se escribe el código.

Aquí hay un ejemplo.

contestado el 23 de mayo de 17 a las 15:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.