Espero poder aportar algo nuevo a este problema. Noté que todas las respuestas descuidan el hecho de que hay dos puntos en los que puede realizar el preprocesamiento , sin ralentizar su rendimiento general de lavado.
Además, no necesitamos suponer una gran cantidad de calcetines, incluso para familias numerosas. Los calcetines se sacan del cajón y se usan, y luego se tiran en un lugar (tal vez un contenedor) donde permanecen antes de ser lavados. Si bien no llamaría a dicho bin una pila LIFO, diría que es seguro asumir que
- la gente tira sus dos calcetines aproximadamente en la misma área del contenedor,
- el contenedor no está aleatorizado en ningún punto, y por lo tanto
- cualquier subconjunto tomado de la parte superior de este contenedor generalmente contiene los dos calcetines de un par.
Dado que todas las lavadoras que conozco tienen un tamaño limitado (independientemente de la cantidad de calcetines que tenga que lavar), y la aleatorización real ocurre en la lavadora, no importa cuántas medias tengamos, siempre tenemos pequeños subconjuntos que casi no contienen Singletons.
Nuestras dos etapas de preprocesamiento son "poner los calcetines en el tendedero" y "quitar los calcetines del tendedero", lo que tenemos que hacer para obtener calcetines que no solo estén limpios sino también secos. Al igual que con las lavadoras, los tendederos son finitos, y supongo que tenemos toda la línea donde ponemos nuestros calcetines a la vista.
Aquí está el algoritmo para put_socks_on_line ():
while (socks left in basket) {
take_sock();
if (cluster of similar socks is present) {
Add sock to cluster (if possible, next to the matching pair)
} else {
Hang it somewhere on the line, this is now a new cluster of similar-looking socks.
Leave enough space around this sock to add other socks later on
}
}
No pierdas tu tiempo moviendo calcetines o buscando la mejor combinación, todo esto debe hacerse en O (n), que también necesitaríamos para ponerlos en la línea sin clasificar. Los calcetines aún no están emparejados, solo tenemos varios grupos de similitud en la línea. Es útil que tengamos un conjunto limitado de calcetines aquí, ya que esto nos ayuda a crear grupos "buenos" (por ejemplo, si solo hay calcetines negros en el conjunto de calcetines, la agrupación por colores no sería el camino a seguir)
Aquí está el algoritmo para take_socks_from_line ():
while(socks left on line) {
take_next_sock();
if (matching pair visible on line or in basket) {
Take it as well, pair 'em and put 'em away
} else {
put the sock in the basket
}
Debo señalar que para mejorar la velocidad de los pasos restantes, es aconsejable no elegir aleatoriamente el siguiente calcetín, sino tomar secuencialmente calcetín tras calce de cada grupo. Ambos pasos de preprocesamiento no toman más tiempo que simplemente poner los calcetines en la línea o en la canasta, lo que tenemos que hacer sin importar qué, por lo que esto debería mejorar en gran medida el rendimiento del lavado.
Después de esto, es fácil hacer el algoritmo de partición hash. Por lo general, aproximadamente el 75% de los calcetines ya están emparejados, dejándome con un subconjunto muy pequeño de calcetines, y este subconjunto ya está (algo) agrupado (no introduzco mucha entropía en mi cesta después de los pasos de preprocesamiento). Otra cosa es que los grupos restantes tienden a ser lo suficientemente pequeños como para ser manejados a la vez, por lo que es posible sacar un grupo completo de la cesta.
Aquí está el algoritmo para sort_remaining_clusters ():
while(clusters present in basket) {
Take out the cluster and spread it
Process it immediately
Leave remaining socks where they are
}
Después de eso, solo quedan unos pocos calcetines. Aquí es donde introduzco los calcetines no emparejados previamente en el sistema y proceso los calcetines restantes sin ningún algoritmo especial: los calcetines restantes son muy pocos y se pueden procesar visualmente muy rápido.
Para todos los calcetines restantes, supongo que sus contrapartes todavía están sin lavar y los guardo para la próxima iteración. Si registra un crecimiento de calcetines no apareados con el tiempo (una "fuga de calcetines"), debe revisar su papelera; puede ser aleatorio (¿tiene gatos que duermen allí?)
Sé que estos algoritmos toman muchas suposiciones: un contenedor que actúa como una especie de pila LIFO, una lavadora normal limitada y un tendedero normal limitado, pero esto todavía funciona con una gran cantidad de calcetines.
Acerca del paralelismo: siempre que arroje ambos calcetines en el mismo contenedor, puede paralelizar fácilmente todos esos pasos.