No en Google, pero tenemos conversaciones como esta todo el tiempo.
Cuanto más grandes sean sus datos, mayor será la complejidad.
Un ejemplo reciente de mi trabajo proviene de un requisito básico:
- Cómo resolver la recurrencia t (n) = 2t (n / 2) + n / logn
- ¿Por qué se han desarrollado los algoritmos de ordenamiento O (n ^ 2) (como el ordenamiento por inserción y el ordenamiento por burbuja) y para qué se utilizan?
- ¿Cuál es el algoritmo más utilizado a nuestro alrededor?
- ¿Cómo funciona la búsqueda 'YouTube'? ¿Cómo te señala con precisión una canción con solo unas pocas palabras de la letra?
- ¿Cuáles serían las implicaciones si pudiera demostrar que he descifrado el algoritmo criptográfico RSA en tiempo polinómico? ¿Qué debería hacer después?
“Dada una lista de hogares y una lista de negocios, encuentre el negocio más cercano a cada hogar”
La solución ingenua fue algo así como “tomar el producto cruzado de la distancia entre todos los hogares y empresas y luego seleccionar la fila con la distancia mínima para cada hogar”.
Pensé en el diseño y le expliqué que no funcionaría para nosotros. El tiempo de ejecución, incluso si le proporcionáramos unos pocos miles de núcleos en el clúster Spark, sería prohibitivo y los datos intermedios requerirían demasiada memoria y / o almacenamiento para completarse.
Me pidieron que explicara mi razonamiento ya que las pruebas a pequeña escala funcionaban bien.
Para n hogares ym empresas, esto creará filas de O (nm) y luego se agregará y ordenará para volver a n filas de salida. Esto significa que usamos el espacio O (nm) y realizamos comparaciones O (nm * m log m) (suponiendo una clasificación O (m log m)). Una optimización trivial podría llevarlo a O (nm ^ 2) al buscar la ubicación más cercana, pero no fue así como se me presentó.
Si estamos comparando hogares en Raleigh (n = ~ 200,000) con los lugares de barbacoa de Carolina en Raleigh (m = ~ 20), entonces este algoritmo debería estar bien. Si nos estamos comparando solo con los excelentes lugares de barbacoa de Carolina, esto se puede hacer en O (n) tiempo, porque todos sabemos que Mel’s es el mejor.
Pero, ¿qué sucede si estamos tratando de encontrar la ubicación de Cricket Mobile más cercana a cualquier hogar en los Estados Unidos? Ahora n = 125M ym = 58,138.
Esto significa que el producto cruzado creará O (nm) o (125000000 * 58138) o 7,267,250,000,000 filas y realizará operaciones O (mn * m log m) … eso es aproximadamente 6.68704e + 18 operaciones.
Dado que cada fila intermedia tenía 56 bytes (excluyendo cualquier sobrecarga de almacenamiento o compresión), eso significa que la salida del producto cruzado sería de 370 TB, aunque la salida final sería de solo 6.5GB.
Los animé a experimentar en el grupo durante las horas libres. El producto cruzado (la primera operación después de la carga de datos) se ejecutó durante aproximadamente 8 horas antes de que se superara la cuota de espacio temporal y se cancelara el trabajo. Ni siquiera pasó por el paso 1.
Tenemos que reducir esto a un O (n log m) para que sea práctico.
Nuestra solución actual se ejecuta en tiempo O (n log m) y utiliza espacio intermedio O (n) (también requiere aproximadamente m * 40 bytes almacenados en la memoria, pero esto es de 2 MB como máximo). Distribuido en unos pocos cientos de núcleos, se ejecuta en unos 7 minutos.
El uso de Big-O fue útil porque nos permitió cuantificar el rendimiento de nuestro algoritmo y también determinar dónde necesitábamos tener una probabilidad razonable de éxito. si no sabe a dónde va, O (n log m), ¿cómo sabrá cuando llegue allí?