algorithm - шортами - с чем носить высокие носки




Как эффективно сочетать носки с кучей? (20)

Были предложены решения для сортировки, но сортировка немного сложнее : нам не нужен заказ; нам просто нужны группы равенства .

Так что хэширования было бы достаточно (и быстрее).

  1. Для каждого цвета носков образует кучу . Итерируйте все носки в корзине и распределите их на цветные свая .
  2. Итерации по каждой куче и распространение ее по какой-либо другой метрике (например, узор) во второй набор свай
  3. Рекурсивно применяйте эту схему до тех пор, пока вы не распределите все носки на очень маленькие свай, которые вы можете визуально обработать немедленно

Такое рекурсивное хэш-разбиение фактически выполняется SQL Server, когда ему нужно хеш-соединение или хэш-агрегат над огромными наборами данных. Он распределяет входной поток сборки во множество разделов, которые являются независимыми. Эта схема масштабируется до произвольного количества данных и нескольких процессоров линейно.

Вам не нужно рекурсивное разбиение на разделы, если вы можете найти ключ распределения (хэш-ключ), который обеспечивает достаточное количество ведер, чтобы каждый ковш был достаточно мал, чтобы обрабатываться очень быстро. К сожалению, я не думаю, что у носков такая собственность.

Если у каждого носка было целое число, называемое «PairID», можно было бы легко распределить их на 10 ведер в соответствии с PairID % 10 (последняя цифра).

Лучшее реальное разбиение на разделы, о котором я могу думать, это создать прямоугольник свай : одно измерение - цветное, другое - шаблон. Почему прямоугольник? Потому что нам нужен O (1) случайный доступ к сваям. (3D- cuboid также будет работать, но это не очень практично).

Обновить:

Что относительно параллелизма ? Может ли несколько людей быстрее соответствовать носкам?

  1. Простейшая стратегия распараллеливания состоит в том, чтобы несколько работников взяли из корзины ввода и положили носки на свай. Это только масштабы - воображайте 100 человек, сражающихся более 10 свай. Затраты на синхронизацию (проявляющиеся как ручные столкновения и человеческое общение) разрушают эффективность и ускоряют работу (см. Закон об универсальной масштабируемости !). Это склонно к взаимоблокировкам ? Нет, потому что каждому работнику нужно только один раз получить доступ к одной куче. С одним «замком» не может быть тупика. Livelocks может быть возможным в зависимости от того, как люди координируют доступ к сваям. Они могут просто использовать случайную отсрочку, например сетевые карты, на физическом уровне, чтобы определить, какая карта может иметь исключительно доступ к сетевому проводу. Если он работает для NICs , он должен работать и для людей.
  2. Он масштабируется почти бесконечно, если у каждого работника есть своя свая . Затем рабочие могут брать большие куски носков из корзины ввода (очень редко, поскольку они редко делают это), и им не нужно синхронизировать при распространении носков вообще (потому что у них есть нитки-локальные сваи). В конце концов, всем работникам необходимо объединить свои сваи. Я считаю, что это можно сделать в O (log (количество работника * свая на одного работника)), если рабочие образуют дерево агрегации .

Как насчет проблемы отличия элемента ? Как указывается в статье, проблема отличимости элемента может быть решена в O(N) . Это то же самое для проблемы с носками (также O(N) , если вам нужен только один шаг распределения (я предложил несколько шагов только потому, что люди плохи при расчетах - достаточно одного шага, если вы распространяете на md5(color, length, pattern, ...) , т. е. совершенный хэш всех атрибутов)).

Ясно, что нельзя идти быстрее, чем O(N) , поэтому мы достигли оптимальной нижней границы .

Хотя выходы не совсем одинаковы (в одном случае, только булевы. В другом случае, пары носков), асимптотические сложности одинаковы.

Вчера я спаривал носки с чистого белья и выяснил, как я это делаю, это не очень эффективно. Я делал наивный поиск - собирал один носок и «итерировал» кучу, чтобы найти свою пару. Это требует итерации в среднем n / 2 * n / 4 = n 2/8 носков.

Как компьютерный ученый, я думал, что я могу сделать? Сортировка (в зависимости от размера / цвета / ...), конечно, приходила на ум для решения O (NlogN).

Хеширование или другие решения не на месте - это не вариант, потому что я не могу дублировать свои носки (хотя было бы неплохо, если бы я мог).

Итак, вопрос в основном:

Учитывая кучу n пар носков, содержащих 2n элементов (предположим, что каждый носок имеет ровно одну совпадающую пару), каков наилучший способ их эффективного соединения с помощью логарифмического дополнительного пространства? (По-моему, я могу запомнить этот объем информации в случае необходимости.)

Я буду признателен за ответ, который касается следующих аспектов:

  • Общее теоретическое решение для огромного количества носков.
  • Фактическое количество носков не так велико, я не верю моему супругу, и у меня более 30 пар. (И довольно легко различить мои носки и ее, можно ли это использовать и?)
  • Является ли это эквивалентом проблемы отличимости элемента ?

В качестве практического решения:

  1. Быстро сделайте груды легко различимых носков. (Скажем по цвету)
  2. Быстро сортируйте каждую кучу и используйте длину носка для сравнения. Как человек вы можете сделать довольно быстрое решение, которое носок использовать для разделения, что позволяет избежать худшего случая. (Вы можете видеть несколько носков параллельно, используйте это в своих интересах!)
  3. Остановите сортировку свай, когда они достигнут порога, при котором вам удобно находить спотовые пары и неустойчивые носки мгновенно

Если у вас 1000 носков, с 8 цветами и средним распределением, вы можете сделать 4 свая каждые 125 носков в c * n раз. С порогом 5 носков вы можете сортировать каждую кучу за 6 прогонов. (Подсчитайте 2 секунды, чтобы бросить носок в правильную кучу, вам понадобится немного меньше 4 часов).

Если у вас всего 60 носков, 3 цвета и 2 вида носков (ваша / ваша жена), вы можете сортировать каждую стопку 10 носков за 1 прогон (снова порог = 5). (Подсчитайте 2 секунды, вам понадобится 2 минуты).

Начальная сортировка ковша ускорит ваш процесс, потому что он делит ваши n носки на k ковшей в c*n раз, так что вам нужно будет только работать c*n*log(k) . (Не принимая во внимание порог). Так что все, что вы делаете о n*c*(1 + log(k)) работает, где c - время бросить носок на кучу.

Этот подход будет благоприятным по сравнению с любым методом c*x*n + O(1) примерно до тех пор, пока log(k) < x - 1 .

В информатике это может быть полезно: у нас есть коллекция n вещей , порядок на них (длина), а также отношение эквивалентности (дополнительная информация, например, цвет носков). Отношение эквивалентности позволяет нам сделать разбиение на исходную коллекцию, и в каждом классе эквивалентности наш порядок сохраняется. Отображение вещи в класс эквивалентности может быть выполнено в O (1), поэтому для назначения каждого элемента классу требуется только O (n). Теперь мы использовали нашу дополнительную информацию и можем всячески сортировать каждый класс. Преимущество в том, что наборы данных уже значительно меньше.

Метод также может быть вложен, если мы имеем множественные отношения эквивалентности -> делаем цветные свай, чем в каждом разделе кучи текстуры, чем сортируем по длине. Любое отношение эквивалентности, которое создает раздел с более чем двумя элементами, имеющими примерно четный размер, приведет к улучшению скорости сортировки (при условии, что мы можем напрямую назначить носок на его кучу), и сортировка может произойти очень быстро на небольших наборах данных.


Теоретический предел - O (n), потому что вам нужно прикоснуться к каждому носку (если только некоторые из них уже не связаны как-то).

Вы можете достичь O (n) с помощью сортировки radix . Вам просто нужно выбрать некоторые атрибуты для ведер.

  1. Сначала вы можете выбрать (ее, мою) - разделить на две сваи,
  2. затем используйте цвета (может иметь любой порядок цветов, например, в алфавитном порядке по имени цвета) - разделите их на кучи по цвету (не забудьте сохранить начальный порядок с шага 1 для всех носков в одной и той же куче),
  3. затем длина носка,
  4. затем текстура, ....

Если вы можете выбрать ограниченное количество атрибутов, но достаточно атрибутов, которые могут однозначно идентифицировать каждую пару, вы должны быть сделаны в O (k * n), который является O (n), если мы можем считать k ограниченным.


Что я делаю, так это то, что я забираю первый носок и кладу его (скажем, на край чаши для белья). Затем я забираю еще один носок и проверяю, не совпадает ли он с первым носком. Если это так, я удаляю их обоих. Если это не так, я положил его рядом с первым носком. Затем я подбираю третий носок и сравниваю это с первыми двумя (если они все еще там). И т.п.

Этот подход можно довольно легко реализовать в массиве, предполагая, что «удаление» носков является опцией. На самом деле вам даже не нужно «удалять» носки. Если вам не нужна сортировка носков (см. Ниже), вы можете просто переместить их и получить массив, в котором все носки расположены в парах в массиве.

Предполагая, что единственная операция для носков - это сравнение для равенства, этот алгоритм в основном по-прежнему является алгоритмом n 2 , хотя я не знаю о среднем случае (никогда не научился его вычислять).

Сортировка, конечно, повышает эффективность, особенно в реальной жизни, когда вы можете легко «вставить» носок между двумя другими носками. При вычислении же может быть достигнуто дерево, но это дополнительное пространство. И, конечно же, мы вернулись в NlogN (или немного больше, если есть несколько носков, которые совпадают по критериям сортировки, но не из одной пары).

Помимо этого, я ничего не могу придумать, но этот метод кажется довольно эффективным в реальной жизни. :)


Этот вопрос на самом деле глубоко философский. В глубине души речь идет о том, соответствует ли сила людей решению проблем («wetware» наших мозгов) эквивалентно тому, что может быть достигнуто с помощью алгоритмов.

Очевидным алгоритмом сортировки носка является:

Let N be the set of socks that are still unpaired, initially empty
for each sock s taken from the dryer
  if s matches a sock t in N
    remove t from N, bundle s and t together, and throw them in the basket
  else
    add s to N

Теперь информатика в этой проблеме касается шагов

  1. «если s пары с носком t в N». Как быстро мы можем «вспомнить» то, что мы видели до сих пор?
  2. «удалить t из N» и «добавить s к N». Насколько дорогим является отслеживание того, что мы видели до сих пор?

Люди будут использовать различные стратегии для их осуществления. Человеческая память ассоциативна , что-то вроде хеш-таблицы, где набор признаков хранимых значений сочетается с самими соответствующими значениями. Например, концепция «красной машины» отображает все красные автомобили, которые человек способен запомнить. У кого-то с совершенной памятью есть идеальное отображение. Большинство людей несовершенны в этом отношении (и большинство других). Ассоциативная карта имеет ограниченную емкость. Сопоставления могут выходить из строя при различных обстоятельствах (одно пиво слишком много), записываться по ошибке («Я, хотя ее имя было Бетти, а не Nettie»), или никогда не перезаписываться, хотя мы наблюдаем, что правда изменилась («папа автомобиль "вызывает" оранжевую Жар-птицу ", когда мы на самом деле знали, что он торгует этим для красного Camaro).

В случае с носками идеальное напоминание означает, что взгляд на носок всегда производит память его брата t , включая достаточную информацию (где он находится на гладильной доске) для нахождения t в постоянное время. Человек с фотографической памятью выполняет как 1, так и 2 в постоянное время.

Кто-то с менее совершенной памятью может использовать несколько классов эквивалентности здравого смысла, основанных на особенностях его способности отслеживать: размер (папа, мама, ребенок), цвет (зеленоватый, красноватый и т. Д.), Узор (аргил, равнина и т. Д.), , стиль (footie, knee-high и т. д.). Таким образом, гладильная доска будет разделена на разделы для категорий. Обычно это позволяет размещать категорию по постоянному времени по памяти, но тогда необходим линейный поиск по категории «ведро».

Кто-то, у кого нет памяти или воображения вообще (извините), просто будет держать носки в одной куче и делать линейный поиск всей сваи.

Утонченный урод может использовать числовые метки для пар, как кто-то предложил. Это открывает дверь для полного заказа, что позволяет человеку использовать точно такие же алгоритмы, которые мы могли бы использовать с процессором: бинарный поиск, деревья, хэши и т. Д.

Таким образом, «лучший» алгоритм зависит от качества используемого wetware / hardware / программного обеспечения и нашей готовности «обманывать», накладывая общий порядок на пары. Конечно , «лучший» мета -алгоритм, чтобы нанять лучший в мире носка Сортировщик: человек или машина , которая может aquire и быстро хранить огромное множество N наборов атрибутов носка в 1-1 ассоциативной памяти с постоянная временем поиска, вставками, и удалить. Можно приобрести как людей, так и машины. Если он у вас есть, вы можете соединить все носки в O (N) время для N пар, что является оптимальным. Общие теги ордеров позволяют использовать стандартное хеширование, чтобы получить тот же результат с помощью человеческого или аппаратного компьютера.


Вы пытаетесь решить неправильную проблему.

Решение 1. Каждый раз, когда вы кладете грязные носки в корзину для белья, привязывайте их в маленький узел. Таким образом вам не придется делать сортировку после стирки. Подумайте об этом, как о регистрации индекса в базе данных Mongo. Небольшая работа впереди для экономии некоторых процессоров в будущем.

Решение 2. Если зима, вам не нужно носить соответствующие носки. Мы программисты. Никто не должен знать, пока это работает.

Решение 3. Распространение работы. Вы хотите выполнить такой сложный процесс процессора асинхронно, не блокируя пользовательский интерфейс. Возьмите эту кучу носков и налейте их в сумку. Только ищите пару, когда вам это нужно. Таким образом, объем работы, которую он занимает, гораздо менее заметен.

Надеюсь это поможет!


Случай 1 : Все носки идентичны (кстати, это то, что я делаю в реальной жизни).

Выберите любые два из них, чтобы сделать пару. Постоянное время.

Случай 2 : существует постоянное количество комбинаций (собственность, цвет, размер, текстура и т. Д.).

Используйте сортировку radix . Это только линейное время, так как сравнение не требуется.

Случай 3 : Количество комбинаций заранее неизвестно (общий случай).

Мы должны сделать сравнение, чтобы проверить, входят ли два носка в пару. Выберите один из алгоритмов сортировки на основе сравнения O(n log n) .

Однако в реальной жизни, когда количество носков относительно невелико (постоянное), эти теоретически оптимальные алгоритмы не будут работать хорошо. Это может занять еще больше времени, чем последовательный поиск, что теоретически требует квадратичного времени.


Если операция «перемещение» довольно дорога, а операция «сравнения» дешева, и вам все равно нужно переместить весь набор в буфер, где поиск намного быстрее, чем в исходном хранилище ... просто интегрируйте сортировку в обязательную переехать.

Я обнаружил, что интеграция процесса сортировки в зависание для сушки делает его легким. Мне все равно нужно забрать каждый носок и повесить его (переместить), и мне ничего не стоит повесить его в определенном месте на струнах. Теперь просто не для принудительного поиска всего буфера (строк) я выбираю размещать носки по цвету / тени. Темнее слева, ярче справа, более яркий фронт и т. Д. Теперь, прежде чем я повесю каждый носок, я смотрю в его «правильную окрестность», если там уже есть соответствующая - это ограничивает «сканирование» до 2-3 других носков - и если это , Я повесил другой рядом с ним. Затем я переворачиваю их в пары, удаляя из струн, когда они сухие.

Теперь это может показаться не таким, что отличается от «формирования сваи по цвету», предложенного верхними ответами, но, во-первых, не выбирая дискретные свая, но диапазоны, я не имею проблемы, классифицируя, идет ли «фиолетовый» к «красной» или «голубой» куче; он просто идет между ними. А затем, объединив две операции (зависание, чтобы сушить и сортировать), накладные расходы на сортировку при подвешивании составляют 10% от того, какая будет отдельная сортировка.


Рассмотрим хеш-таблицу размера «N».

Если мы предполагаем нормальное распределение, то оценочное число «вставок», имеющих по крайней мере один носок, сопоставленный с одним ведром, равно NlogN (т. Е. Все ковши заполнены)

Я получил это как часть еще одной загадки, но я был бы счастлив, если бы оказался ошибочным. Вот моя статья в блоге о том же

Пусть «N» соответствует приблизительной верхней границе количества уникальных цветов / рисунков носков, которые у вас есть.

Как только вы столкнулись (aka: match), просто удалите эту пару носков. Повторите тот же эксперимент со следующей партией носков NlogN. Красота заключается в том, что вы можете делать параллельные сравнения NlogN (разрешение конфликтов) из-за того, как работает человеческий разум. :-)


Реальный мир:

Как можно быстрее удалите носки из несортированной кучи за один раз и место в сваях перед вами. Свай должен быть устроен несколько пространственно эффективно, со всеми носками, направленными в одном направлении; количество свай ограничено расстоянием, с которым вы легко можете добраться. Выбор кучи, на которую нужно положить носок, должен быть - как можно быстрее - положить носок на кучу, по-видимому, как носки; случайный тип I (поместив носок на кучу, к которому он не принадлежит) или тип II (помещая носок в свою кучу, когда есть существующая куча подобных носков), можно терпеть ошибку - самое важное соображение - скорость, Как только все носки находятся в сваях, быстро проходите через многокилоновые сваи, создавая пары и удаляя их (они идут в ящик). Если в стопке имеются несоответствующие носки, повторите сборку в порядке (в пределах как можно быстрее). Когда все сваи с несколькими носками будут обработаны, сравните оставшиеся пайкируемые носки, которые не были спарены из-за ошибок типа II. Кого, ты закончил - и у меня много носков, и не мыть их, пока большая часть не загрязнена. Еще одно практическое замечание: я переворачиваю верхнюю часть одной из двух носков поверх другой, используя их эластичные свойства, поэтому они остаются вместе при транспортировке в ящик и в ящике.


Чтобы сказать, насколько эффективно парные носки из кучи, мы должны сначала определить машину, потому что спаривание не выполняется, будь то turing или машиной произвольного доступа, которые обычно используются в качестве основы для алгоритмический анализ.

Машина

Машина представляет собой абстракцию элемента реального мира, называемого человеком. Он может читать из окружающей среды через пару глаз. И наша модель машины может управлять окружающей средой, используя 2 руки. Логические и арифметические операции вычисляются с использованием нашего мозга (надеюсь, ;-)).

Мы также должны рассмотреть внутреннее время выполнения атомных операций, которое может быть выполнено с помощью этих инструментов. Из-за физических ограничений операции, выполняемые рукой или глазом, имеют постоянную временную сложность. Это связано с тем, что мы не можем перемещать бесконечно большую кучу носков с помощью руки и не можем видеть верхний носок на бесконечно большой куче носков.

Однако механическая физика дает нам некоторые положительные стороны. Мы не ограничены движением не более одного носка рукой. Мы можем перемещать целую пару одновременно.

Поэтому в зависимости от предыдущего анализа следующие операции должны использоваться в порядке убывания:

  • логические и арифметические операции
  • экологические чтения
  • экологические изменения

Мы также можем использовать тот факт, что у людей только очень небольшое количество носков. Таким образом, экологическая модификация может включать все носки в кучу.

Алгоритм

Итак, вот мое предложение:

  1. Расправьте все носки в кучу над полом.
  2. Найдите пару, глядя на носки на полу.
  3. Повторяйте с 2 до тех пор, пока не будет создана пара.
  4. Повторяйте с 1 до тех пор, пока на полу не будет носков.

Операция 4 необходима, потому что при распространении носков над полом некоторые носки могут скрыть других. Вот анализ алгоритма:

Анализ

Алгоритм завершается с большой вероятностью. Это связано с тем, что в шаге номер 2 не удается найти пары носков.

Для последующего анализа пар nпарных носков мы рассмотрим, что по крайней мере половина 2nносков не скрыта после шага 1. Таким образом, в среднем случае мы можем найти n/2пары. Это означает, что цикл - это шаг 4, выполняется O(log n)раз. Шаг 2 выполняется O(n^2)раз. Таким образом, мы можем заключить:

  • Алгоритм включает O(ln n + n)изменения окружающей среды (шаг 1 O(ln n)плюс выбор каждой пары носка с пола)
  • Алгоритм включает в себя O(n^2)экологические показания с шага 2
  • Алгоритм включает O(n^2)логические и арифметические операции для сравнения носка с другим на шаге 2

Таким образом, у нас есть общая сложность времени выполнения, O(r*n^2 + w*(ln n + n))где rи wявляются факторами для операций по защите окружающей среды и окружающей среды, соответственно, для разумного количества носков. Стоимость логических и арифметических операций опущена, поскольку мы предполагаем, что для принятия решения о том, принадлежит ли 2 носка к одной и той же паре, требуется определенное количество логических и арифметических операций. Это может быть невозможно в каждом сценарии.


Я вышла с другим решением, которое не обещает меньше операций, и не меньше времени на потребление, но его следует попытаться выяснить, может ли это быть достаточно эвристическим, чтобы обеспечить меньшее потребление времени в огромной серии парных носков.

Предпосылки: нет гарантии, что есть те же носки. Если они имеют один и тот же цвет, это не означает, что они имеют одинаковый размер или рисунок. Носки случайным образом перетасовываются. Может быть нечетное количество носков (некоторые отсутствуют, мы не знаем, сколько). Подготовьтесь запомнить переменную «index» и установите ее в 0.

Результат будет иметь одну или две сваи: 1. «соответствует» и 2. «отсутствует»,

Эвристический:

  1. Найдите самый отличительный носок.
  2. Найдите его матч.
  3. Если нет совпадения, поставьте его на «недостающую» кучу.
  4. Повторяйте с 1. до тех пор, пока нет более отличительных носков.
  5. Если есть меньше шести носков, перейдите к 11.
  6. Пара вслепую все носки к своему соседу (не упаковывайте его)
  7. Найдите все согласованные пары, упакуйте их и переместите упакованные пары в «сопоставленную» кучу; Если новых совпадений не было - увеличивать «индекс» на 1
  8. Если «индекс» больше 2 (это может быть значение зависит от номера носка, потому что с большим количеством носков меньше шансов соединить их вслепую) перейти к 11
  9. Перемешать остальные
  10. Перейти к 1
  11. Забудьте «индекс»
  12. Выберите носок
  13. Найти свою пару
  14. Если для носка нет пары, переместите ее в «пропавшую» кучу
  15. Если совпадение получило пару, пакет, переместите его в «согласованную» кучу
  16. Если есть еще несколько носков, перейдите к 12
  17. Если есть только один левый, перейдите к 14
  18. Улыбка удовлетворена :)

Кроме того, может быть добавлена ​​проверка на поврежденные носки также, как если бы они были удалены. Он может быть вставлен между 2 и 3 и между 13 и 14.

Я с нетерпением жду услышать о любых переживаниях или исправлениях.


Я предпринял простые шаги, чтобы уменьшить свои усилия в процессе, принимающем O (1) раз.

Уменьшая мои данные до одного из двух видов носков (белые носки для отдыха, черные носки для работы), мне нужно только определить, какой из двух носков у меня есть. (Технически, поскольку они никогда не смываются вместе, я сократил процесс до O (0) времени)

Требуются некоторые предварительные усилия, чтобы найти нужные носки и приобрести в достаточном количестве, чтобы устранить необходимость в ваших существующих носках. Поскольку я сделал это до моей потребности в черных носках, мои усилия были минимальными, но пробег может отличаться.

Такие предварительные усилия были замечены много раз в очень популярном и эффективном коде. Примеры включают # ОПРЕДЕЛЕНИЕ pi к нескольким десятичным знакам (существуют другие примеры, но это тот, который приходит на ум прямо сейчас).


Возьмите первый носок и поместите его на стол. Теперь выберите другой носок; если он совпадает с первым выбранным, поместите его поверх первого. Если нет, поместите его на стол на небольшое расстояние от первого. Выберите третий носок; если он соответствует любому из двух предыдущих, поместите его поверх них или разместите на небольшом расстоянии от третьего. Повторяйте, пока не возьмете все носки.


Всякий раз, когда вы берете носок, положите его в одно место. Затем следующий носок, который вы поднимаете, если он не соответствует первому носу, установите его рядом с первым. Если да, то есть пара. Таким образом, на самом деле не имеет значения, сколько комбинаций есть, и есть только две возможности для каждого носка, который вы забираете - либо у него есть совпадение, которое уже находится в вашем массиве носков, либо это не так, а это означает, что вы добавьте его в место в массиве.

Это также означает, что вы почти наверняка никогда не будете иметь все свои носки в массиве, потому что носки будут удалены по мере их соответствия.


Из вашего вопроса ясно, что у вас нет большого опыта в стирке :). Вам нужен алгоритм, который хорошо работает с небольшим количеством незащищенных носков.

Ответы до сих пор не используют наши возможности распознавания человеческого рисунка. Игра в Set дает ключ к тому, как это сделать: поставьте все носки в двумерном пространстве, чтобы вы могли их легко распознать и легко достать руками. Это ограничивает область около 120 * 80 см или около того. Оттуда выберите пары, которые вы распознаете, и удалите их. Положите лишние носки в свободное пространство и повторите. Если вы моете для людей с легко узнаваемыми носками (маленькие дети приходят на ум), вы можете сделать сортировку радикса, сначала выбрав эти носки. Этот алгоритм хорошо работает только тогда, когда количество одиночных носков низкое


Мое решение точно не соответствует вашим требованиям, поскольку оно формально требует O(n)«лишнего» пространства. Однако, учитывая мои условия, он очень эффективен в моем практическом применении. Поэтому я думаю, что это должно быть интересно.

Объединить с другой задачей

Особым условием в моем случае является то, что я не использую сушильную машину, просто повесьте свои ткани на обычную сухую сушилку. Висячие ткани требуют O(n)операций (кстати, я всегда рассматриваю проблему упаковки бутылок здесь), и проблема по своей природе требует линейного «лишнего» пространства. Когда я беру новый носок из ведра, я пытаюсь повесить его рядом с его парой, если пара уже висит. Если его носок из новой пары, я оставляю некоторое пространство рядом с ним.

Oracle Machine лучше ;-)

Очевидно, для этого требуется дополнительная работа, чтобы проверить, существует ли уже подходящий носок, и он будет отображать решение O(n^2)с коэффициентом 1/2для компьютера. Но в этом случае «человеческий фактор» на самом деле является преимуществом - я обычно могу очень быстро (почти O(1)) идентифицировать подходящий носок, если он уже висел (возможно, задействовано некоторое незаметное кэширование в мозге) - считайте это своего рода ограниченный «оракул», как в Oracle Machine ;-) В некоторых случаях у людей есть эти преимущества по сравнению с цифровыми машинами ;-)

Имейте это Почти O(n)!

Таким образом, связывая проблему спаривания носков с проблемой подвешивания полотенец, я бесплатно получаю O(n)«лишнее пространство» и имею решение, которое происходит O(n)вовремя, требует лишь немного больше работы, чем простые вешалки, и позволяет сразу же получить доступ к полной паре носки даже в очень плохое утро в понедельник ... ;-)


Надеюсь, я смогу внести что-то новое в эту проблему. Я заметил, что все ответы игнорируют тот факт, что есть две точки, где вы можете выполнить предварительную обработку , не замедляя общую производительность белья.

Кроме того, нам не нужно брать большое количество носков, даже для больших семей. Носки вынимают из ящика и носят, и их бросают в место (возможно, в мусорное ведро), где они остаются перед отмыванием. Хотя я бы не назвал указанный бит LIFO-Stack, я бы сказал, что можно с уверенностью предположить, что

  1. люди бросают оба своих носка примерно в одну и ту же область бункера,
  2. бункер не рандомизирован в любой точке, и поэтому
  3. любое подмножество, взятое с вершины этого бункера, обычно содержит оба носка пары.

Поскольку все стиральные машины, о которых я знаю, имеют ограниченный размер (независимо от количества носков, которые вы должны стирать), и фактическая рандомизация происходит в стиральной машине, независимо от того, сколько у нас носков у нас всегда есть маленькие подмножества, которые почти не содержат одиночки.

Наши две стадии предварительной обработки - «положить носки на веревку для белья» и «брать носки из веревки», что мы должны сделать, чтобы получить носки, которые не только чисты, но и сухие. Как и в стиральных машинах, веревки для одежды являются конечными, и я предполагаю, что у нас есть целая часть линии, где мы ставим наши носки в поле зрения.

Вот алгоритм 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, ограниченная, обычная стиральная машина и ограниченная нормальная веревка для белья - но это все еще работает с очень большим количеством носков.

О параллелизме: пока вы бросаете оба носка в один и тот же ящик, вы можете легко распараллелить все эти шаги.


Проблема сортировки ваших n пар носков - O (n) . Прежде чем вы выбросите их в корзину для белья , вы пропустите левую сторону вправо. Вынимая их, вы разрезаете нить и помещаете каждую пару в ваш ящик - 2 операции по n парам, поэтому O (n).

Теперь следующий вопрос: просто ли вы делаете свою собственную прачечную, а ваша жена делает ее. Это проблема, вероятно, в совершенно другой области проблем . :)


Создайте хеш-таблицу, которая будет использоваться для непревзойденных носков, используя шаблон как хэш. Идите по носкам один за другим. Если носок имеет совпадение с шаблоном в хэш-таблице, выньте носок из таблицы и сделайте пару. Если носок не имеет соответствия, поместите его в таблицу.







matching