Я надеюсь, что смогу внести что-то новое в эту проблему. Я заметил, что во всех ответах игнорируется тот факт, что есть две точки, в которых вы можете выполнить предварительную обработку , не снижая общую производительность стирки.
Кроме того, нам не нужно брать большое количество носков, даже для больших семей. Носки вынимают из ящика и надевают, а затем бросают в место (возможно, в мусорное ведро), где они остаются перед стиркой. Хотя я бы не назвал указанный бин LIFO-стеком, я бы сказал, что можно с уверенностью предположить, что
- люди бросают оба своих носка примерно в одну и ту же область,
- мусорное ведро не рандомизировано в любой точке, и, следовательно,
- любое подмножество, взятое из верхней части этого бина, обычно содержит оба носка пары.
Поскольку все стиральные машины, о которых я знаю, имеют ограниченный размер (независимо от того, сколько носков вы должны стирать), и фактическая рандомизация происходит в стиральной машине, независимо от того, сколько у нас носков, у нас всегда есть небольшие поднаборы, которые почти не содержат одиночки.
Наши две стадии предварительной обработки - это «положить носки на веревку для белья» и «снять носки с веревки для белья», что мы должны сделать, чтобы получить носки, которые не только чистые, но и сухие. Как и в случае со стиральными машинами, бельевые веревки ограничены, и я предполагаю, что у нас есть целая часть линии, где мы видим наши носки.
Вот алгоритм для 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
}
}
Не тратьте свое время на перемещение носков или поиск лучшего соответствия, все это должно быть сделано в O (n), который нам также понадобится для того, чтобы просто поставить их на несортированную линию. Носки еще не спарены, у нас есть только несколько кластеров сходства на линии. Полезно, чтобы у нас был ограниченный набор носков, поскольку это помогает нам создавать «хорошие» кластеры (например, если в наборе носков есть только черные носки, кластеризация по цветам не будет подходящим способом)
Вот алгоритм для 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
}
Следует отметить, что для повышения скорости оставшихся шагов целесообразно не случайным образом выбирать следующий носок, а последовательно извлекать носок за носком из каждого кластера. Обе стадии предварительной обработки не занимают больше времени, чем просто положить носки на линию или в корзину, что мы должны делать, несмотря ни на что, что должно значительно повысить эффективность стирки.
После этого легко сделать алгоритм разбиения хеша. Обычно около 75% носков уже спарены, и у меня остается очень небольшое подмножество носков, и это подмножество уже (несколько) кластеризовано (я не привносю большой энтропии в свою корзину после этапов предварительной обработки). Другое дело, что оставшиеся кластеры имеют тенденцию быть достаточно маленькими, чтобы их можно было обрабатывать сразу, поэтому можно вынуть целый кластер из корзины.
Вот алгоритм для sort_remaining_clusters ():
while(clusters present in basket) {
Take out the cluster and spread it
Process it immediately
Leave remaining socks where they are
}
После этого осталось всего несколько носков. Здесь я ввожу ранее непарные носки в систему и обрабатываю оставшиеся носки без какого-либо специального алгоритма - оставшихся носков очень мало и их можно обрабатывать визуально очень быстро.
Для всех оставшихся носков, я предполагаю, что их аналоги все еще не вымыты, и отложу их для следующей итерации. Если вы регистрируете рост непарных носков с течением времени («утечка носков»), вы должны проверить свою корзину - она может быть рандомизирована (есть ли у вас кошки, которые там спят?)
Я знаю, что эти алгоритмы основаны на многих предположениях: корзина, которая действует как своего рода стек LIFO, ограниченная, обычная стиральная машина и ограниченная, обычная веревка для белья - но это все еще работает с очень большим количеством носков.
О параллелизме: пока вы добавляете оба носка в одну корзину, вы можете легко распараллелить все эти шаги.