¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Cuánto tarda un algoritmo: contar pasos

Después de esta lección: Puedo comparar dos algoritmos por cómo crece su número de pasos.

Lección de 50 min3 comandosLaboratorio JupyterLab de ciencia de datos: pandas, Matplotlib y scikit-learn en el navegador

Dos programas, mil datos

Para comparar dos algoritmos no basta con decir que uno es "más rápido". Hay que decir cuánto crece su trabajo cuando los datos crecen. A eso se le llama eficiencia, y se mide contando pasos.

Una app con 10 usuarios funciona con cualquier programa. Con un millón, solo funciona el que crece despacio.

Al final de esta lección

Nota

Puedo comparar dos algoritmos por cómo crece su número de pasos.

Palabras clave

PalabraQué significaEjemplo
Pasouna operación sencilla, como comparar dos números
Tamaño de la entradacuántos datos recibe el algoritmo, que se llama n
Eficienciacuánto trabajo necesita un algoritmo
O grandeuna forma de decir cómo crece el número de pasosO(n)
Crecimiento linealel doble de datos son el doble de pasos
Crecimiento cuadráticoel doble de datos son cuatro veces más pasos

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Se cuentan pasos, no segundos

Un segundo no sirve para comparar. Tu móvil y el ordenador del colegio dan tiempos distintos con el mismo programa, y hasta tu móvil cambia de una vez a otra.

Un paso sí es siempre el mismo. Si el programa compara 173 veces, compara 173 veces en cualquier máquina.

Contar los pasos de la búsqueda lineal

Código: python
def count_linear(items, target):
    steps = 0
    for item in items:
        steps = steps + 1
        if item == target:
            return steps
    return steps

numbers = list(range(1, 101))
print(count_linear(numbers, 1))
print(count_linear(numbers, 100))
print(count_linear(numbers, 500))

Los pasos dependen de n

El programa imprime 1, 100 y 100. Si el dato es el primero, es un paso. Si es el último o no está, son 100: tantos como elementos.

Llamamos n al número de elementos. En el peor caso, la búsqueda lineal hace n pasos. Se dice que es de orden n, y se escribe O(n).

La O grande dice cómo crece el trabajo

No importa si son 173 pasos o 175. Importa cómo cambia el número cuando n crece.

La búsqueda binaria es O(log n): cada paso descarta la mitad. La lineal es O(n). La burbuja es O(n²), que se lee "n al cuadrado": compara casi cada elemento con todos los demás. La mezcla es O(n log n).

Cuenta las comparaciones de la burbuja

Comando
docker exec jupyter python3 -c "print([(n, n * (n - 1) // 2) for n in (10, 100, 1000)])"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Cuenta cuántas mitades hay

Comando
docker exec jupyter python3 -c "print([(n, n.bit_length()) for n in (10, 100, 1000)])"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Ejemplo resuelto: pasos según el número de datos

Datos (n)Binaria, en mitadesLinealBurbuja, en comparaciones
1041045
10071004950
1000101000499500

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Qué enseñan los Run y la tabla

El primer Run imprime [(10, 45), (100, 4950), (1000, 499500)]. Con diez veces más datos, la burbuja hace cien veces más comparaciones.

El segundo imprime [(10, 4), (100, 7), (1000, 10)]. La binaria casi no se entera: con mil datos solo hace 10 pasos.

Un error frecuente

Advertencia

Mucha gente cree que un programa que va bien con 10 datos irá bien con un millón. Con pocos datos casi no hay diferencia entre algoritmos. La diferencia aparece cuando n crece, y entonces un algoritmo O(n²) deja de funcionar.

Contar con dos bucles: n por n

Un bucle dentro de otro repite el de dentro una vez por cada vuelta del de fuera. Por eso la burbuja crece tanto.

Con 4 elementos hace 3 + 2 + 1 = 6 comparaciones. Con 10 hace 9 + 8 + ... + 1 = 45. Ese es el número de parejas distintas.

Contar las comparaciones de dos bucles

Código: python
def count_pairs(n):
    comparisons = 0
    for turn in range(n - 1):
        for at in range(n - 1 - turn):
            comparisons = comparisons + 1
    return comparisons

for n in [4, 10, 100]:
    print(n, count_pairs(n))

Cuenta las comparaciones para los 365 días

Comando
docker exec jupyter python3 -c "import csv; h=[int(r['hires']) for r in csv.DictReader(open('hires.csv'))]; print(len(h) * (len(h) - 1) // 2, len(h) * len(h).bit_length())"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Burbuja contra mezcla con 365 días

El Run imprime 66430 3285. Ordenar los 365 alquileres con la burbuja hace 66430 comparaciones. La mezcla hace unas 3285.

Con una lista de un millón de datos, la burbuja haría unos quinientos mil millones de comparaciones. La mezcla, unos veinte millones.

Para ir más lejos: mide el tiempo tú

En el cuaderno, escribe una celda con %timeit para ordenar 1000 números y otra para ordenar 2000. Mira cuánto cambia el tiempo.

Repite la medida y apunta lo que ves. El tiempo cambia de una vez a otra. El número de pasos de la tabla no cambia nunca.

Sobre este laboratorio y su código: Laboratorio JupyterLab de ciencia de datos: pandas, Matplotlib y scikit-learn en el navegador

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.