Как эффективно соединить носки в стопку?

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

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

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

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

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

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

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

person amit    schedule 19.01.2013    source источник
comment
Я использую принцип «голубятни», чтобы соединить ровно одну из стопки белья. У меня есть носки 3 разных цветов (красный, синий и зеленый) и по 2 пары каждого цвета. Я каждый раз беру 4 носков, всегда составляю пару и приступаю к работе.   -  person Srinivas    schedule 19.01.2013
comment
Я думаю, вы могли бы несколько упростить это, предположив, что некоторые подмножества пар носков взаимозаменяемы; У меня около шести пар одинаковых носков. Также: интересный вопрос!   -  person Dave    schedule 19.01.2013
comment
Выберите свой любимый принцип сортировки (цвет, текстура, толщина), отсортируйте по нему, выберите соседние пары   -  person sehe    schedule 19.01.2013
comment
Еще один принцип «голубиной дыры»: если вы возьмете подмножество из n / 2 +1 носков, в этом подмножестве должна быть хотя бы одна пара.   -  person wildplasser    schedule 19.01.2013
comment
Кроме того, вы отбрасываете хэши, потому что вы не можете делать копии, но обратите внимание, что легко можно создать хеш-набор, который не нуждается в копиях, как в вычислениях, так и в прачечной.   -  person Mooing Duck    schedule 19.01.2013
comment
@MooingDuck: Если у вас есть что-то конкретное, пожалуйста, опубликуйте это, обратите внимание, что я не отбрасываю это - это только мои начальные трюки - это может быть неправильно, сам вопрос не запрещает хеширование, он только требует, чтобы алгоритм был на месте (и эффективно). Как уже было сказано, я также буду признателен за ответ, который касается других аспектов (малый / крупный масштаб и эквивалентность проблеме отличимости - который покажет, что O (nlogn) в основном лучшее, что я могу получить без дополнительного места)   -  person amit    schedule 19.01.2013
comment
заметьте, что если у вас есть бесконечное количество различных симметричных пар носков (т.е. left = right), то, фактически, просто выбрать по одной из них невозможно, если вы не принимаете аксиому выбора (en.wikipedia.org/wiki/Axiom_of_choice). Какое влияние это имеет на спаривание? как это связано с вычислимостью? math.stackexchange.com/questions/269902/   -  person thang    schedule 20.01.2013
comment
Кстати, это больше известно (как бы) как игра в Концентрация - составлять пары из большой случайной группы.   -  person Izkata    schedule 20.01.2013
comment
Хорошим алгоритмом, выполняемым вручную, может быть алгоритм уменьшения сдвига. Добавьте новый носок в стопку случайным образом, и как только пара окажется наверху, уменьшите и уберите пару. В конце концов вы получите их большинство. Остаток можно обработать вручную или перезапустить алгоритм. Ни в малейшей степени не компьютерная наука, но достаточно хороша, так как вы можете немного схитрить и иногда подобрать подходящий носок.   -  person doug65536    schedule 20.01.2013
comment
Отличный вопрос! Возможно, вас заинтересует моя статья о связанной проблеме, в которой обсуждается вероятность вытащить из кучи два одинаковых носка: blogs.msdn.com/b/ericlippert/archive/2010/03/22/   -  person Eric Lippert    schedule 20.01.2013
comment
Принцип голубятни: en.wikipedia.org/wiki/Pigeonhole_principle   -  person Nabil Kadimi    schedule 22.01.2013
comment
Добавьте дополнительный указатель на класс носка, который будет указывать на пару носков.   -  person AJMansfield    schedule 12.07.2013
comment
Почему бы не создать дочерний элемент и waitpid, чтобы вы, как родитель, сами даже не сортировали носки?   -  person Mxyk    schedule 06.09.2013
comment
Я решил эту проблему, купив только белые носки по колено. Все они совпадают. Я мог просто взять любые два носка наугад из кучи, и они совпали. Я еще больше упрощаю задачу, НЕ соединяя носки в пару. У меня есть ящик для носков, в который я просто бросаю все свои носки, непарные. Каждое утро я беру два наугад из ящика. Я упростил его до O (0). Нет ничего проще. :)   -  person Lee    schedule 07.09.2013
comment
В любом случае это O (1) - существует постоянное ограничение на количество носков, которые поместятся в любой конкретной стиральной машине или ящике для носков.   -  person Steve314    schedule 07.09.2013
comment
@ Steve314 Итак, распараллеливайте и используйте несколько ящиков для носков.   -  person Thomas    schedule 14.09.2013
comment
Если бы вы могли дублировать носки, хеширование было бы не самым эффективным ответом;)   -  person sfussenegger    schedule 19.09.2013
comment
В этом документе обсуждается связанная проблема: citeseerx.ist .psu.edu / viewdoc /   -  person Erel Segal-Halevi    schedule 16.10.2013
comment
Вот еще одна ссылка по теме: mail-archive.com/kragen- [email protected]/msg00084.html   -  person Erel Segal-Halevi    schedule 16.10.2013
comment
Я знаю, что это не отвечает на ваш вопрос с теоретической точки зрения, но с практической точки зрения никто не смотрит на ваши носки. Не объединять их в пары - это O (k).   -  person sqykly    schedule 10.11.2013
comment
День стирки и так скучен. Чтобы избавиться от затруднений при сортировке носков, вы должны делать это лениво: высыпать все (не имеющие себе равных) носки в ящик, каждое утро выбирая два, которые выглядят (как бы) одинаково.   -  person Marcus    schedule 06.12.2013
comment
Я думаю, что в этом случае избегание - лучшее решение: у меня только один тип носков, поэтому он O (n) и требует минимум памяти ... :-)   -  person Francois Bourgeois    schedule 24.12.2013
comment
Этот вопрос полон инженерного туннельного видения. Не все гвоздь. Сортировка носков в реальной жизни очень зависит от ограничений производительности зрительной когнитивной системы человека и ее манипуляторов. Мы можем до некоторой степени сопоставить носки с образцом, используя нашу параллельную обработку зрения (зрительная кора FTW). Мы также можем до некоторой степени планировать движения параллельно с приобретением следующей пары носков, которую нужно выбрать из кучи. Теоретическое описание алгоритмической сложности поиска носков в реальной жизни не похоже на то, что вы описываете.   -  person Kuba hasn't forgotten Monica    schedule 26.03.2014
comment
IOW: Реальные сортировки носков совершенно нечувствительны к тому, какой базовый алгоритм вы используете, и вы не можете выбрать алгоритм, потому что ваша зрительная и моторная кора уже выбрала один для вас. Насколько я могу судить, оптимальный. Время манипуляции превосходит все остальное. Я пришел к выводу (и, черт возьми, я провел пару часов, записывая себя и анализируя записи): вы можете легко насытить своих манипуляторов, и на этом все. Все, что вам нужно, это достаточно большой стол. Материал CS приходит только в том случае, если ваша нагрузка не помещается на одном столе.   -  person Kuba hasn't forgotten Monica    schedule 26.03.2014
comment
@thang, вам не нужно принимать Аксиому Выбора, если количество носков счетно.   -  person Apprentice Queue    schedule 03.04.2014
comment
@ApprenticeQueue говорит, что вы правы, как будет выглядеть функция выбора? Я думаю, что вы (доказуемо) неправы, но чтобы дать подсказку, взгляните на это: en. wikipedia.org/wiki/Axiom_of_countable_choice (более слабая версия AC). Доказать, что даже аксиома счетного выбора не зависит от ZF, сложно и требует принуждения.   -  person thang    schedule 03.04.2014
comment
Вы можете сэкономить память, сразу набив стопку из корзины в ящик, а не раскладывая их по поверхности (чтобы найти подходящие пары). Просто поищите подходящую пару из ящика, когда она вам понадобится.   -  person user1164937    schedule 30.04.2014
comment
Я уверен, что кто-то уже опубликовал это, но вы делаете вывод из неверного предположения, что для каждого носка есть пара. Я имею в виду - давай, ты правда думаешь, что каждому носку, который ты стираешь, есть подходящий ...   -  person Vasil Dininski    schedule 01.05.2014
comment
Оптимальное решение проблемы пары носков - положить их в стирку парами. Это сокращает время сортировки до нуля и решает проблему с одним носком.   -  person Keith    schedule 02.05.2014
comment
@amit, который вы написали, используя свою наивную технику Это требует повторения в среднем n / 2 * n / 4 = n2 / 8 носков.. В чем причина этого? Как появляются термины n / 2 и n / 4?   -  person Geek    schedule 07.05.2014
comment
@Geek Вам нужно соединить n / 2 носков (отсюда n / 2). взяв один носок и найдя ему совпадение. В среднем нужно пройти половину левых носков. На первой итерации это число равно n / 2, на второй - (n / 2) / 2, ... среднее значение n / 2, (n-2) / 2, (n-4) / 2, .. ., 2/2 - это n / 4.   -  person amit    schedule 07.05.2014
comment
Другая проблема, которую, казалось, упускали из виду, - это проблема поиска точного соответствия носка (а не только того же цвета и размера). Я всегда ношу носки с их соответствующими партнерами, чтобы они носили одинаковые, поэтому, если я не найду точный носок, который я всегда носил с другим носком, они будут чувствовать себя иначе (неприемлемо для моего ума программиста ОКР), даже если они возникли. из точно такого же пакета.   -  person cnsumner    schedule 08.07.2014
comment
Я также решил практическую проблему за O (1) раз, купив только черные носки упаковками по 50 пар. Интересно, сколько плакатов с переполнением стека нашли такое же решение!   -  person Persixty    schedule 19.11.2014
comment
Как вы считаете носок без пары, который съел сушильный монстр?   -  person woot    schedule 24.02.2015
comment
Я думаю, что для носков наиболее эффективным методом будет сортировка по ведру. держите кучу в одном месте, а ведра в другом. вытащите носок, положите его в новую стопку носков, подходящих к этому носку. пока у вас достаточно табличного пространства, вы можете сортировать носки за O (n) времени, что является нижним пределом, если вы делаете это самостоятельно. добавление дополнительных рабочих позволяет продвигаться к O (log n)   -  person Chris Phillips    schedule 29.09.2017
comment
ваше предположение о совпадающих парах ооочень удалено от реальности. даже с двумя parallel.task(child).waitpid.all выигрыш в производительности, который обещает принятый ответ, перевешивается экспоненциальным уменьшением количества подходящих образцов в стопке с течением времени.   -  person Cee McSharpface    schedule 23.01.2018
comment
Шаг 1) Выбросьте все свои носки. Шаг 2: купите себе 15 пар одинаковых черных носков и 15 пар одинаковых белых носков для своей жены. Шаг 3) Алгоритм гласит: черные носки - твои, а белые - твоей жены!   -  person Chris Melville    schedule 09.01.2020
comment
отличный вопрос!   -  person David Peer    schedule 28.04.2021
comment
@Mxyk Я немного боюсь спросить, почему твои дети умирают, когда перестают одевать носки? Это кажется неоптимальным (и жестоким).   -  person val is still with Monica    schedule 06.05.2021


Ответы (36)


Поскольку архитектура человеческого мозга полностью отличается от архитектуры современного процессора, этот вопрос не имеет практического смысла.

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

Мой алгоритм:

spread_all_socks_on_flat_surface();
while (socks_left_on_a_surface()) {
     // Thanks to human visual SIMD, this is one, quick operation.
     pair = notice_any_matching_pair();
     remove_socks_pair_from_surface(pair);
}

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

person Community    schedule 20.01.2013
comment
по мере увеличения количества socks человеческий SIMD становится не лучше процессора. - person Lie Ryan; 20.01.2013
comment
Лучший ответ, ИМО. Хотя свести повседневную проблему к компьютерному алгоритму весело и умно (и подходит для SO), гораздо более разумно использовать разрешающую способность человеческого глаза / мозга для набора размером всего ~ 60 носков. - person drug_user841417; 20.01.2013
comment
@LieRyan Если носки распределены равномерно, вы в конечном итоге заметите пару в любом достаточно маленьком наборе носков из-за парадокса дня рождения (если вы не можете различать цвета с произвольной точностью, в чем я сомневаюсь), поэтому узким местом здесь не будет алгоритм сопоставления цвета человека, но шаг распространения. - person Thomas; 21.01.2013
comment
@Christian: То же самое для меня. Поэтому я всегда использую алгоритм сделки с ним: он единственный, который можно использовать в этой ситуации ... - person Askaga; 21.01.2013
comment
@Christian: Если бы у вас были только черные носки, разве какой-нибудь носок не соответствовал бы другим носкам? ;) - person dpc.pw; 21.01.2013
comment
Ага. По крайней мере, после того, как вы сопоставили все легко идентифицируемые пары, у вас останется гораздо меньшее число. Я не думаю, что у меня остались какие-то реальные пары, поэтому я стараюсь просто перебирать два носка, которые выглядят менее непохожими, чем средняя случайная пара. - person Steve Bennett; 22.01.2013
comment
Я не согласен с утверждением, что мозг - это совершенно другая архитектура. "finding a matching pair" can be one operation for a set that isn't too big. эквивалентен поиску в машинном кэше, который НАМНОГО быстрее, чем поиск в ОЗУ, но вы собираетесь сначала загрузить эти носки в кеш, и поэтому предлагаемый подход будет O(n^2) как для человека, так и для машины. - person amit; 22.01.2013
comment
@ dpc.ucore.info Нет, потому что у них разные плетеные манжеты, длина манжет, общая длина и оттенки черного (моя жена, вероятно, физически причинила мне вред из-за этого последнего). - person Christian; 22.01.2013
comment
@Christian Даже среди моих черных носков я легко могу определить различия в длине, узоре и оттенке, чтобы найти подходящие пары. Это не так просто, как заметить мою единственную пару ярко-оранжевых носков, но все же довольно легко. Я всегда расстилаю носки так, чтобы они смотрели в одном направлении бок о бок, это, кажется, помогает находить пары и соединять их в пары. - person AnnanFay; 23.01.2013
comment
@Annan Ну, тогда тебе повезло, потому что я не могу :) - person Christian; 23.01.2013
comment
Лучше надеяться, что у вас четное количество носков, иначе вы долго будете складывать носки ... - person Patrick James McDougle; 23.01.2013
comment
Точно так же сортировка выбора выполняется быстрее, чем сортировка слиянием для достаточно небольших выборок. - person Brian Webster; 25.01.2013
comment
Забавно, я прочитал этот вопрос, когда он появился в новостном хакере, но ответа еще не было. Я сочетал свои носки и - уделив немного внимания тому, как мне удавалось быть «эффективным» - пришел к такому же выводу! Cooooooooooool! ;-) - person Vinzzz; 31.01.2013
comment
Я не думаю, что вам нужно делать свою горизонтальную поверхность однослойной и, следовательно, чрезмерно большой, учитывая большую кучу случайно отсортированных носков. Также не требуется упреждающая сортировка, поскольку вы будете выполнять сортировку посредством рекурсивного процесса сопоставления SIMD. Если у вас есть куча, вы, вероятно, увидите хотя бы одну спичку. Когда у вас больше нет видимого совпадения, переместите предметы из кучи в другой его «тип». В конечном итоге вы обнаружите, что еще одна спичка будет видна на стопке, или она появится при переходе в стопку индивидуального «типа». Насколько это быстро? это для математика - person JoeBrockhaus; 14.02.2013
comment
Это сработало бы на сотню носков. Теперь попробуйте увеличить это число до нескольких миллионов. - person hookenz; 25.11.2013
comment
@Christian Если у вас только черные носки, подобрать носки не проблема. - person OJFord; 19.03.2014
comment
@OllieFord Ты, честно говоря, понятия не имеешь :) - person Christian; 20.03.2014
comment
@Christian Вам нужно хорошее освещение для конкретной задачи, возможно, под косым углом, чтобы узоры выделялись больше. Люди, занимающиеся машинным зрением, должны поделиться с вами реальными рекомендациями. - person Kuba hasn't forgotten Monica; 26.03.2014
comment
@KubaOber В целом более простым решением может быть простая замена пар объектов Sock экземплярами класса WashablePair. Существуют носки, которые оснащены встроенными кнопками, чтобы сделать это возможным, но есть также решения по модернизации обычных носков, чтобы они оставались парными на протяжении всего процесса стирки. Просто у меня лично никогда не было времени на рефакторинг моей коллекции носков. - person Christian; 26.03.2014
comment
Я предлагаю изменить это значение на while(pair = notice_any_matching_pair()) { для обеспечения отказоустойчивости в случае, если совпадение не может быть найдено (т.е.если нет совпадения или если количество носков, которые могут поместиться в памяти, недостаточно для поиска совпадения). - person Brilliand; 16.04.2014
comment
Есть некоторые серьезные ограничения на производительность визуального сканирования плоских поверхностей. Если имеется много относительно уникальных пар (здесь нет простых белых носков), вы быстро превзойдете возможности визуального сканирования человеческого мозга. Требование большего внимания мозга к соответствию означает, что вы не можете смотреть телевизор, пока соединяете носки. Кто-то еще упомянул практическую проблему поиска достаточно большой плоской поверхности. Наконец, по мере увеличения площади поверхности у вас возникают проблемы с расстоянием и углом обзора при просмотре носков ближе к горизонту и при физическом пересечении зоны сортировки. - person Mnebuerquo; 29.04.2014
comment
распространение носков занимает много места, и вопрос говорит только о логарифмическом пространстве - person DollarAkshay; 01.08.2014
comment
Неужели только я считаю, что это получил все юмористические голоса .. или, в лучшем случае, псевдокодовые ...? - person Nirav Bhatt; 07.10.2015
comment
да, на самом деле сопоставление с образцом занимает O (1) с человеческими глазами, если N мало. - person ramgorur; 03.06.2016
comment
Разложить @AkshayLAradhya - это операция O (1), называемая выгрузкой бака для стирки. Возможно, потребуется некоторая перетасовка, еще одна операция O (1) - person Frank Hopkins; 07.05.2019
comment
Я придерживаюсь такого подхода: 1. Достаньте носок из корзины; 2. Проверьте уже взятые носки, есть ли подходящие; 3. Если нет, положите их в область несовпадающих носков; 4. Возьмите еще одну и повторите; Это очень похоже, но вместо того, чтобы сначала распределять все, я делаю это линейно, поэтому в какой-то момент я достигаю максимального количества несовпадающих носков, не длиннее N / 2 в худшем случае. - person Netrix; 09.09.2019

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

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

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

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

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

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

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

person Community    schedule 19.01.2013
comment
Я думаю, строго говоря, поразрядная сортировка не годится, потому что предположим, что у каждого носка есть ровно одна подходящая пара. Хотя в большинстве практических приложений это сработает. - person emory; 20.01.2013
comment
›Это может занять даже больше времени, чем последовательный поиск, который теоретически требует квадратичного времени. Да, поэтому я ненавижу это делать, может, мне стоит выбросить все носки и начать с дела 1. - person Nils; 21.01.2013
comment
Мне также легче иметь одинаковые носки. Каждые пару лет я покупаю 10 из этих 6 пачек носков, когда они есть в продаже, и выбрасываю все свои старые носки. Просто подобрать одинаковые носки проще, и они будут выглядеть лучше, чем старые святые носки. При этом для меня самый быстрый результат - простой первый удар с вершины кучи. - person Michael D. Kirkpatrick; 21.01.2013
comment
Обратной стороной одинаковых носков является то, что они стареют с разной скоростью. Так что вы все равно пытаетесь подобрать их в зависимости от того, насколько они изношены. (что сложнее, чем просто сопоставление по шаблону) - person SDC; 22.01.2013
comment
Проблема с 60 парами одинаковых носков, поскольку это упрощает создание пары, заключается в том, что у людей создается впечатление, будто вы работаете с компьютерами. - person Steve Ives; 24.04.2013
comment
Случай 1 не является постоянным временем, когда задействована операция, такая как складывание пар вместе. В данном случае это линейное время с наименьшим постоянным множителем (доказательство которого оставляем читателю в качестве упражнения). Невозможно одновременно складывать одну пару и ведро носков. Однако масштабируется линейно. По закону Амдала он имеет неограниченное ускорение без учета накладных расходов. По закону Густафсона вы можете сбросить столько пар, сколько требуется, чтобы сложить одну пару при достаточном количестве рабочих (количество которых остается в качестве упражнения для читателя), игнорируя накладные расходы. - person acelent; 04.09.2013
comment
@PauloMadeira Сортировка - это постоянное время - вы просто берете стопку и кладете ее в свой ящик. Единственная операция в этом случае - это надевать носки на ноги, что тоже постоянно. Производительность достигается за счет отложенного выполнения носки носка, возможно, с некоторой жертвой в пространстве (потребляемое пространство несложенных носков больше, чем сложенных). Я утверждаю, что это того стоит; Обычно я проигрываю этот спор со своей женой. - person Travis; 12.09.2013
comment
@ Трэвис, ты прав. Но проблема заключается в том, чтобы объединить носки в пару (возможно, в результате получится куча сложенных / набитых носков), а не сортировать стопку носков (в результате получится просто еще одна стопка). Это то, что я хотел отметить. - person acelent; 14.09.2013
comment
@TerryLi Случай 4: у вас все одинаковые носки, у вашей жены много разных. Решение: сделайте 2 стопки, используйте «футляр 1» для стопки ваших носков, а ваша жена сама решит свои проблемы. В основном, как я это делаю :-) - person atlaste; 11.02.2014
comment
Я сделал Case 1 год назад. Для некоторых время - деньги, а для меня время ›деньги. Я постирала и рассортировала носки в последний раз и все пожертвовала на добрую волю. Затем я купил 60 пар носков и открыл только 30 из них. Остальные пары запечатаны в моем шкафу на случай необходимости замены. Я никогда не окунаюсь в них, если хотя бы 10 носков не повреждены или непригодны для использования. Сортировка носков теперь заключается только в моих носках (легко узнаваемых), а не в моих носках (которые складываются в кучу для сортировки не мне) - person TxRegex; 28.05.2019
comment
@SDC и все - если они стареют с разной скоростью, вы упускаете важную важную деталь. поверните их, как обычные, то есть положите только что постиранные носки в заднюю (или левую) часть ящика, потяните спереди / справа. Задача решена. Это пример того, как избежать улучшения из-за очевидного недостатка, когда недостаток можно смягчить (по общему признанию - смягчение недостатков новых технологий редко бывает таким простым!) Но, возможно, это не так просто, поскольку на момент написания этой статьи 52 человека проголосовали за комментарий! Это означает, что 52 человека пропустили это очевидное решение. Хвастайтесь: вот как я делал это годами :-) - person FastAl; 06.06.2019

Неалгоритмический ответ, но "эффективный", когда я это делаю:

  • Шаг 1) откажитесь от всех существующих носков

  • шаг 2) перейдите на Walmart и купите их пакетами по 10 штук белого и m пакетов черного цвета. В повседневной жизни нет необходимости в других цветах.

Тем не менее, время от времени мне приходится делать это снова (потерянные носки, поврежденные носки и т. Д.), И я ненавижу слишком часто выбрасывать идеально хорошие носки (и мне хотелось, чтобы они продолжали продавать те же самые ссылки на носки!), Поэтому я недавно взял другой подход.

Алгоритмический ответ:

Учтите, что если вы нарисуете только один носок для второй стопки носков, как вы это делаете, ваши шансы найти подходящий носок при наивном поиске довольно низки.

  • Так что возьмите пять из них наугад и запомните их форму или длину.

Почему пять? Обычно люди хорошо запоминают от пяти до семи различных элементов в рабочей памяти - это немного похоже на человеческий эквивалент RPN стек - пять - безопасное значение по умолчанию.

  • Возьмите одну из стопки 2н-5.

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

  • Продолжайте случайным образом выбирать носки из стопки и сравнивать их со своими носками 5 + 1 на матч. По мере того, как ваш стек растет, это снижает вашу производительность, но повышает ваши шансы. Намного быстрее.

Не стесняйтесь записывать формулу для расчета, сколько образцов вам нужно нарисовать для 50% вероятности совпадения. IIRC - это гипергеометрический закон.

Я делаю это каждое утро, и мне редко нужно больше трех розыгрышей, но у меня есть n похожие пары (около 10, плюс минус потерянные) белых носков m формы. Теперь вы можете оценить размер моей стопки акций :-)

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

person Community    schedule 20.01.2013
comment
Проголосуйте за "неалгоритмический" ответ. Именно этим я и занимаюсь, и это прекрасно работает. Замена носков не проблема, если вы «поворачиваете» запас носков, кладя выстиранные носки на заднюю часть и потянув утром за переднюю часть ящика. Все носки изнашиваются равномерно. Когда я начинаю замечать износ одного из них, я включаю в список покупок, чтобы полностью заменить весь этот класс носков. Что касается старых носков, я отдаю лучшие 20% Goodwill (привязанные в продуктовом мешочке, чтобы они не попадали обратно), а остальное предлагаю. Вы не тратите носки, на данный момент у 80% осталось всего 6 месяцев. - person FastAl; 22.01.2013
comment
Кстати (1) Связывание ваших носков приводит к тому, что эластичные носки сохраняются в растянутом состоянии, и они выходят из строя намного быстрее. Ограничение количества уникальных носков делает их ненужными. (2) Недостатком ограничения уникальных носков является то, что для людей с определенными проблемами моды этот метод может быть неподходящим. - person FastAl; 22.01.2013
comment
Я пришел сюда специально, чтобы опубликовать ваш неалгоритмический ответ. Как и в настоящей информатике, большинство людей никогда не уделяют достаточно внимания данным и их структуре. - person bkconrad; 07.09.2013
comment
Я использую этот алгоритмический подход каждое утро, и он отлично работает! Кроме того, я кладу изношенные носки в другую кучу, чтобы потом выбросить (к сожалению, им удается снова добраться до исходной кучи, прежде чем я найду время, чтобы выбросить ее). - person Donatas Olsevičius; 11.09.2013
comment
в моем случае шаг (1) мне не нужен, так как они автоматически сбрасываются, к сожалению, не попарно. Носки, как правило, исчезают с постоянной скоростью, обычно около 2 месяцев достаточно, чтобы потерять 10 пар из виду. - person rupps; 07.12.2014
comment
Многие люди склонны считать неалгоритмический ответ шуткой. Конечно, это работает для socks, но на самом деле это обсуждение программирования, и вы уклоняетесь от вопроса. Но я думаю, что это все еще актуально. По моему опыту создания реальных программных продуктов для клиентов, если кто-то целыми днями работает над проблемой, которая выглядит так, как будто она возникла из учебника колледжа, почти всегда есть более простое (неалгоритмическое) решение, которое они упускают из виду. - person DrShaffopolis; 23.04.2015
comment
«N пакетов белого и m пакетов черного. В повседневной жизни нет необходимости в других цветах »Хорошим стандартным правилом для легкого выбора носков является то, что они должны соответствовать либо цвету ваших брюк, либо цвету вашего пояса. По этой причине наиболее часто используемые цвета, вероятно, будут черным, синим, серым и немного коричневым. Трудно поверить, что нужно много белых носков. - person Andrea Lazzarotto; 13.12.2015

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

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

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

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

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

person Community    schedule 19.01.2013
comment
Это то же самое, что я делаю (обратите внимание, что если вы просто оставите пробелы, тогда вставки также будут O (1)), но он плохо масштабируется с теоретически большим количеством носков. - person Mooing Duck; 19.01.2013
comment
плохо масштабируется с теоретически большим количеством типов носков - person Steven Lu; 20.01.2013
comment
@StevenLu - как я уже сказал - это n * n или nLogn, в зависимости от того, сортируете вы это или нет. Таким образом, он масштабируется так же плохо, как любой алгоритм сортировки. Если вы хотите быстрее, пронумеруйте их и используйте сортировку по основанию. - person Vilx-; 20.01.2013
comment
По сути, это хранение найденных, но не совпадающих носков в поиске на основе хэша. Для идеального хеша это O (n), но если у вас хранится достаточно носков, чтобы хеш начал вырождаться, он соответственно становится более сложным. - person Jon Hanna; 20.01.2013
comment
Я не могу представить себе сортировку, какой носок больше или меньше другого? : D - person graywolf; 20.01.2013
comment
Я использую этот метод, потому что в нем используется хорошая эвристика: поскольку структура ворсового носка имеет несколько верхних элементов, можно выбрать один носк вверху, который, скорее всего, будет соответствовать любому из ваших ранее выбранных носков. . - person evilcandybag; 21.01.2013
comment
Я сначала расстилаю носки и стараюсь не висеть на краю емкости для стирки. Но тогда я хорошо вижу лес за деревьями. - person ; 22.01.2013
comment
@lttlrck - это работает, если ваши носки настолько разные, что вы можете сразу найти несколько пар. Мои в основном требуют более глубокого осмотра, поэтому их разброс не очень помогает. - person Vilx-; 22.01.2013
comment
Какое значение имеет вставка носка между двумя другими носками для создания пары носков? нет мощности носков. :-Икс - person JoeBrockhaus; 14.02.2013
comment
@JoeBrockhaus - Sorting, of course improves efficiency, especially in real life where you can easily "insert" a sock between two other socks. Я имею в виду - если вы можете сравнивать носки, тогда вы можете их сортировать, а вставка помогает ускорить сортировку (самый простой способ сортировки для людей - это сортировка вставкой, которая значительно выигрывает от этой операции ). - person Vilx-; 14.02.2013
comment
Я тоже этим занимаюсь, и, поскольку у меня когда-либо было от 4 до 5 разных типов носков, я всегда могу быстро оценить непревзойденные носки, и поэтому для всех практических целей он функционирует как идеальный хэш, описанный @JonHanna, и масштабируется как На). - person Jacob Eggers; 07.09.2013
comment
Сортировка, конечно, повышает эффективность - нет, конечно делает наоборот. - person Jim Balter; 27.05.2015
comment
@JimBalter - Хм? Я сравнивал это с наивным алгоритмом, когда вы сравниваете каждый носок друг с другом. Разве сортировка не должна улучшить это? - person Vilx-; 27.05.2015
comment
@JimBalter - Окей, подожди, что? Давайте проанализируем это. Предположим, у вас есть N пар носков (это 2N носков). Наихудший сценарий - первые N носков, которые вы натягиваете, принадлежат разным парам. Итак, у вас есть N носков, и только N + 1 носок что-то удаляет. В наивном сценарии первый носок потребует 0 сравнений, второй - 1 сравнение и т. Д., Пока N-й носок не потребует N-1 сравнений. Всего это N * (N-1) / 2 сравнений. Что касается удаления, худший случай почти такой же. Итак, этот алгоритм - O (N * N). - person Vilx-; 27.05.2015
comment
@JimBalter - Хорошо, теперь займемся сортировкой. Предположим, на каждой паре носков напечатан номер. Цифры, конечно, от 1 до N. Теперь, когда я вынимаю новый носок, я отсортировываю очередь перед собой. Я могу найти место для вставки нового носка в O (logN), а могу вставить в O (1). Так как это Real Life, и я могу просто засунуть его на место, одновременно перекладывая все остальные носки. На компьютере вы можете использовать сбалансированное дерево с тем же эффектом (с деревьями труднее работать в реальной жизни). - person Vilx-; 27.05.2015
comment
@JimBalter - В общем, взятие первых N носков будет O (NlogN) операцией, а затем взять и оставшиеся носки. Итак, насколько я понимаю, сортировка ДЕЙСТВИТЕЛЬНО помогает - по крайней мере, с теоретической точки зрения. Я где-то ошибся? - person Vilx-; 27.05.2015

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

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

Часто бывает хорошо сделать шаг назад и подумать, как решить проблему.

И выход есть!

Найдите носки, которые вам нравятся. Учитывайте все важные особенности: цвет в различных условиях освещения, общее качество и долговечность, комфорт в различных климатических условиях и поглощение запахов. Также важно, чтобы они не теряли эластичности при хранении, поэтому подойдут натуральные ткани, и они должны быть доступны в полиэтиленовой упаковке.

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

Если вы выбрали причудливую пару с разными левыми и правыми носками, для выполнения полной сортировки ведер по ведрам для левой и правой ноги потребуется O (N + M), где N - количество носков, а M такое же, как указано выше. Кто-то другой может дать формулу для средних итераций поиска первой пары, но наихудший случай для поиска пары слепым поиском - это N / 2 + 1, что становится астрономически маловероятным случаем для разумного N. Это можно ускорить, используя расширенное изображение. алгоритмы распознавания и эвристика при сканировании стопки несортированных носков с помощью Mk1 Eyeball .

Итак, алгоритм для достижения эффективности пары носков O (1) (при условии симметричного носка):

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

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

  3. Заказывайте носки!

  4. Избавьтесь от старых носков.

Альтернативный шаг 3 будет включать сравнение затрат на покупку того же количества, возможно, более дешевых носков, несколько пар за раз в течение многих лет, и добавление стоимости сортировки носков, но поверьте мне на слово: покупка оптом дешевле! Кроме того, носки на складе увеличиваются в цене со скоростью роста цен на акции, а это больше, чем вы получили бы при многих инвестициях. Опять же, есть также расходы на хранение, но носки действительно не занимают много места на верхней полке шкафа.

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

person Community    schedule 08.02.2013
comment
Пожизненный (при условии, что 75 лет) запас носков (при условии, что вы израсходуете 4 пары в месяц, что составляет 3600 пар) займет (при условии, что новая пара носков занимает 20 кубических дюймов) в общей сложности 1,5 кубических ярда. Это огромное пространство. Если предположить, что они доставят его вам в коробке, которая представляет собой примерно куб, у этого ящика будет примерно 3 фута 4 дюйма со стороной. - person AJMansfield; 12.07.2013
comment
@AJMansfield - серьезное беспокойство. Однако я не согласен с некоторыми из ваших цифр. Я бы взял временной промежуток всего в 40 лет (25 ... 65) (время между отсутствием проживания у родителей / в общежитии и т. Д. И выходом на пенсию, см. Выше). Кроме того, я думаю, что одна пара занимает больше 0,5x4x6 дюймов в оригинальной упаковке. Эти цифры немного снизят ваше космическое время! - person hyde; 14.07.2013
comment
Шаг 4 излишне расточителен, -1. - person Dan Bechard; 04.11.2013
comment
Руководство для тех, кто может быть сбит с толку измерениями А. Дж. Мансфилда, перевод в метрическую систему: »займет (при условии, что новая пара носков занимает 327 см³) в общей сложности 1,14 м³. Это огромное пространство. Если предположить, что они доставят его вам в коробке, которая представляет собой примерно куб, у этого ящика будет примерно 1,04 м со стороны «. - person Joey; 28.11.2013
comment
Как вопрос, основанный на любопытстве, может быть неправильным? Классический StackOverflow ... - person Timmmm; 29.05.2019

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

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

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

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

person Community    schedule 19.01.2013
comment
Носки часто бывают упаковками по 4 штуки и больше, так как это дешевле, но также делает их неотличимыми. Чтобы противостоять этому, моя жена пришивает крошечную отметку на каждой новой паре носков, которую я покупаю. Знак имеет разный цвет для каждой пары или другую форму, если у нее заканчиваются цвета. При таком подходе вам даже не понадобится ограниченный набор атрибутов. Просто пришейте к каждой паре уникальный номер. :) Для дополнительных баллов используйте двоичный код. - person Vilx-; 20.01.2013
comment
@ Vilx- ПОЧЕМУ?!? Разве не все дело в том, что они неразличимы? - person flup; 20.01.2013
comment
@flup - Думаю, весь смысл в том, чтобы продавать большие пакеты. :) Как по мне, это помогает изнашивать их попарно. В противном случае я могу получить три очень изношенных носка и один совершенно новый. Довольно глупо. - person Vilx-; 20.01.2013
comment
Я не согласен с расчетом O (n). Что такое $ k $? $ k $ - количество атрибутов. Я бы сказал, что $ k $ - это $ O (log n) $, потому что этого должно быть достаточно, чтобы однозначно идентифицировать каждую пару. Если у вас 2 пары (черная и белая), то достаточно цвета ($ k = 1, n = 2 $). Если у вас есть одна пара черных, короткие; одна пара черного, длинного; одна пара белых, коротких; и одна пара белых длинных - тогда $ k = 2, n = 4 $. Тогда, если мы ограничиваем $ k $, мы одновременно ограничиваем $ n $. Если мы собираемся ограничить $ n $, то расчет заказа больше не имеет смысла. - person emory; 20.01.2013
comment
@emory, я думаю, что вы ищете обратную кавычку, а не символ $, чтобы ваши вещи выглядели как кодовые. - person Xymostech; 21.01.2013
comment
Вы злоупотребляете обозначением Ландау ... Big Oh используется для верхней границы: см. Семейство нотаций Бахмана-Ландау. Также: вы можете достичь O (n) с помощью радиальной сортировки .. O (n) для чего? Строительство? Прошивка? - person Janus Troelsen; 21.01.2013
comment
@Xymostech, вы правы. Кажется, я не могу отредактировать свой комментарий, чтобы исправить эту ошибку. - person emory; 22.01.2013
comment
@Xymostech LaTeX помечает кого-нибудь? Они действительно должны быть в StackOverflow, иногда они действительно действительно пригодятся. - person Thomas; 26.01.2013
comment
Для emory: я не согласен с расчетом O (n). Что такое k? k - количество атрибутов. Я бы сказал, что k равно O(log n), потому что этого должно быть достаточно, чтобы однозначно идентифицировать каждую пару. Если у вас 2 пары (черная и белая), то достаточно цвета (k=1, n=2). Если у вас есть одна пара черных, короткие; одна пара черного, длинного; одна пара белых, коротких; и одна пара белых длинных - тогда k=2, n=4. Тогда, если мы ограничиваем k, мы одновременно ограничиваем n. Если мы собираемся ограничить n, то расчет ордера больше не имеет смысла. - person Jim Balter; 01.04.2013
comment
@ Vilx- Но как быть с потерянными носками? Когда у меня изнашивается один носок, я просто выбрасываю его, а второй бросаю в стирку, надеясь, что он будет соответствовать другим носкам, оставшимся без присмотра. - person Jacob Eggers; 07.09.2013
comment
@JacobEggers - Я всегда выбрасываю всю пару. Возможно, неоптимально, да. - person Vilx-; 07.09.2013
comment
@Xymostech: Некоторые сайты SE (например, Mathematics) позволяют использовать $ для разметки LaTeX. - person rvighne; 13.04.2014
comment
Как по мне, это помогает изнашивать их попарно. В противном случае я могу получить три очень изношенных носка и один совершенно новый. Довольно глупо. - Что немного глупо, так это то, что вы получаете одинаковое общее время носки в любом случае, поэтому глупо вшивать бирки в одинаковые носки, чтобы различать их ... и если цель состоит в том, чтобы соединять носки одинаковой степени износа, вы можете сделайте это визуально (с необходимой точностью). Я всегда выбрасываю всю пару. - Еще больше глупости из-за глупых тегов. - person Jim Balter; 27.05.2015

Как практическое решение:

  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). Теперь мы использовали нашу дополнительную информацию и можем продолжить сортировку каждого класса любым способом. Преимущество в том, что наборы данных уже значительно меньше.

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

person Community    schedule 20.01.2013
comment
Оптимизация для человека: я бы сказал, что как человек для шага 2 вы должны опустить носки примерно в возрастающем порядке, а затем повторять с все более мелкой детализацией до сортировки, что немного похоже на сортировку оболочки. Это будет намного быстрее для человека (визуальная оценка), чем подход, основанный на сравнении и замене. - person AndrewC; 21.01.2013

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

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

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

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

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

person Nikolay Dyankov    schedule 19.10.2015
comment
Связывание носков (или любой одежды) узлом снижает способность стиральной машины стирать одежду и затрудняет их развязывание для ношения. Решение 2 усложняет обслуживание, чем дольше сохраняется состояние дел; через 6 месяцев, когда вам понадобятся два черных носка до щиколотки, чтобы носить с парой шорт и кроссовок, 6 месяцев выполнения любых работ значительно снизят вероятность нахождения этой пары в том же состоянии (грязный / чистый, похожий износ). Решение 3 менее асинхронно и более лениво; выполняйте необходимый минимум работы именно тогда, когда это необходимо. - person KeithS; 20.04.2017
comment
Re: решение 2: люди будут знать, что я ношу не подходящие носки, потому что они увидят их в моих Birks :) - person Bob Probst; 28.05.2019
comment
@BobProbst Да, но ваши товарищи-программисты также будут носить непревзойденные носки с Бирксом и поэтому будут счастливы заметить, что они не единственные. - person Francesco Pasa; 29.05.2019

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

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

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». Насколько дорого стоит отслеживать то, что мы уже видели?

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

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

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

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

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

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

person Community    schedule 23.01.2013
comment
Ладно, так лучше, хотя все равно совсем не так ... вопрос не об этом. Независимо от того, верен тезис Черча-Тьюринга или нет, и люди, и наши компьютеры могут сортировать носки. (Реальность такова, что люди, будучи в высшей степени конечными сущностями, обладают гораздо меньшей вычислительной мощностью, чем машины Тьюринга ... и то же самое верно и для наших компьютеров, но ограничения другие.) - person Jim Balter; 02.04.2013
comment
Я не согласен. Конечно, любой из наших нынешних компьютеров по сути является огромным DFA (по модулю различий ввода-вывода), а не TM. Однако любое аналоговое устройство, например наше тело, способно имитировать бесконечную ленту. У нас еще нет полезной характеристики вычислений в нашем уме. - person Gene; 02.04.2013
comment
Нет бесконечной ленты для людей или других физических устройств, потому что ничто в человеческом мозге не имеет бесконечного разрешения и не может. Также было бы полезно узнать немного о нейробиологии. В любом случае здесь не было глубокого философского вопроса, независимо от вашего желания его уколоть. Но поверьте, что хотите ... это не место для такого рода дебатов, и раньше у меня это было слишком много раз. Но меня всегда забавляют люди, которые с трудом решают простейшие проблемы (это все мы), воображая, что они эквивалентны ТМ. - person Jim Balter; 02.04.2013

Стоимость: перемещение носков -> высокие, поиск / поиск носков в очереди -> маленькие

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

X = ваш, Y = ваши супруги

Из стопки А всех носков:

Выберите два носка, поместите соответствующий носок X в линию X и носок Y в линию Y в следующей доступной позиции.

Делайте, пока A не станет пустым.

Для каждой строки X и Y

  1. Выберите первый носок в строке, ищите по строке, пока не найдете соответствующий носок.

  2. Вставьте в соответствующую готовую линию носков.

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

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

Делайте это до тех пор, пока X и Y не станут пустыми.

Выполнено

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

person Community    schedule 19.01.2013

Вот нижняя граница Омега (n log n) в модели, основанной на сравнении. (Единственная допустимая операция - это сравнение двух носков.)

Предположим, вы знаете, что ваши 2n носки устроены следующим образом:

p 1 p 2 p 3 ... p n p f (1) p f (2) ... p f (n)

где f - неизвестная перестановка множества {1,2, ..., n}. Понимание этого не может усложнить проблему. Нет! возможные выходы (совпадения между первой и второй половиной), что означает, что вам нужны сравнения log (n!) = Omega (n log n). Это можно получить путем сортировки.

Поскольку вас интересуют связи с проблемой отличимости элементов: доказать границу Omega (n log n) для отличимости элементов сложнее, потому что вывод будет двоичным да / нет. Здесь выходные данные должны совпадать, и количество возможных выходов должно быть достаточным, чтобы получить приличную границу. Однако есть вариант, связанный с различимостью элементов. Предположим, вам дано 2n носков и вы задаетесь вопросом, можно ли их соединить однозначно. Вы можете уменьшить ED, отправив (a 1, a 2, ..., a n) в (a 1, a 1, a 2, a 2, ..., a n, a n). (В скобках доказательство твердости ED очень интересно, через топология.)

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

person Community    schedule 20.01.2013

Вот как я это делаю для p пар носков (n = 2p индивидуальных носков):

  • Возьмите из кучи носок наугад.
  • Для первого носка или если все ранее выбранные носки были парными, просто поместите носок в первый «слот» «массива» непарных носков перед собой.
  • If you have one or more selected unpaired socks, check your current sock against all the unpaired socks in the array.
    • It is possible to separate socks into general classes or types (white/black, ankle/crew, athletic/dress) when building your array, and "drill-down" to only compare like-for-like.
    • Если вы найдете приемлемое совпадение, соедините оба носка и удалите их из массива.
    • Если вы этого не сделаете, поместите текущий носок в первый открытый слот в массиве.
  • Повторите с каждым носком.

Наихудший сценарий этой схемы состоит в том, что каждая пара носков достаточно различается, чтобы они должны были точно совпадать, и что первые n / 2 носки, которые вы выберете, все разные. Это ваш сценарий O (n 2), и он крайне маловероятен. Если количество уникальных типов носков t меньше количества пар p = n / 2, а носки каждого типа достаточно похожи (обычно по износу) связанные термины), что любой носок этого типа может быть соединен с любым другим, то, как я сделал вывод выше, максимальное количество носков, с которыми вам когда-либо придется сравнивать, составляет t, после чего следующий pull будет соответствовать одному из непарных носков. Этот сценарий гораздо более вероятен для среднего ящика для носков, чем для худшего случая, и снижает сложность наихудшего случая до O (n * t), где обычно t ‹< n ​​.

person Community    schedule 21.01.2013
comment
Вероятно, это очень похоже на мой умственный процесс. У меня есть дополнительный уровень оптимизации перед сортировкой. Мои спортивные носки стираются с белым, а мои носки стираются с цветами. Это означает, что до тех пор, пока я не складываю две партии белья вместе, мои носки уже сгруппированы по типам. Белая нагрузка идет очень быстро (много одинаковых носков), а вот носки для платьев занимают больше времени. Другой ключевой совет - сделайте больше доступной памяти для сортировки (сначала сложите и удалите все не-носки, а ЗАТЕМ запустите алгоритм сопряжения) - person orh; 24.01.2013

Реальный подход:

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

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

person Community    schedule 01.04.2013

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

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

person Community    schedule 22.01.2013
comment
Обычно я так и делаю. Работает намного лучше, чем повторять каждый раз все оставшиеся носки. - person yu_ominae; 23.01.2013
comment
Хороший подход, и я думаю, что его можно применить и к некоторым реальным задачам CS. Не могли бы вы добавить такой пример (проблема CS, где мы могли бы использовать аналогичный подход для решения проблем)? Кроме того, как это решение масштабируется для миллионов носков? - person amit; 23.01.2013
comment
Я думаю, что это в основном то же самое, что и другой ответ здесь, stackoverflow.com/a/14423956, от 20 января. Оба +1 . Система человеческого зрения во многом параллельна. - person Will Ness; 07.02.2013

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

person Community    schedule 28.11.2013
comment
Это единственный верный ответ. Все остальные игнорируют тот факт, что больше всего времени уходит на то, чтобы различать похожие носки (так что объединение их всех вместе по внешнему виду только усугубляет ситуацию). - person entonio; 05.05.2014
comment
Ради интереса я написал этот метод складывания носков в небольшую программу на Python gist.github.com/justinfay/53b574cf0a492f6795ef - person Justin Fay; 04.07.2014

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

Машина

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

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

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

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

  • логические и арифметические операции
  • экологические чтения
  • модификации окружающей среды

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

Алгоритм

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

  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 - факторы для операций чтения и записи в среде, соответственно, для разумного количества socks. Стоимость логических и арифметических операций опускается, потому что мы предполагаем, что требуется постоянное количество логических и арифметических операций, чтобы решить, принадлежат ли 2 носка к одной паре. Это не может быть осуществимо в каждом сценарии.

person Community    schedule 29.01.2013
comment
это то же самое, что и stackoverflow.com/a/14423956 и stackoverflow.com/a/14468913 Думаю. - person Will Ness; 07.02.2013
comment
@WillNess Ага, с дополнительными пояснениями - person SpaceTrucker; 07.02.2013

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

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

В результате будет одна или две стопки: 1. "совпадают" и 2. "отсутствуют".

Эвристика:

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

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

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

person Community    schedule 23.01.2013
comment
После того, как я это написал, я использую его каждый раз. Это помогло мне стать немного более эффективным, и теперь работа стала менее скучной. - person Saša; 12.02.2015

Когда я сортирую носки, я выполняю приблизительную сортировку по основанию, сбрасывая носки рядом с другими носками того же размера. цвет / тип рисунка. За исключением случая, когда я вижу точное совпадение в / рядом с тем местом, где я собираюсь уронить носок, я извлекаю пару в этот момент.

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

Я делаю это:

  1. Выбираю оригинальный носок (то, что первым бросается в глаза в стопке).
  2. Начало сортировки по основанию системы счисления из этого концептуального местоположения путем извлечения носков из кучи на основе сходства с этим.
  3. Поместите новый носок рядом с текущей стопкой на расстоянии, зависящем от того, насколько он отличается. Если вы обнаружите, что надеваете один носок на другой, потому что он идентичен, сформируйте там пару и снимите их. Это означает, что в будущих сравнениях потребуется меньше усилий, чтобы найти правильное место.

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

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

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

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

person Community    schedule 23.10.2013

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

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

person Community    schedule 19.01.2013
comment
Это то, что я делаю ... O (n) - person Pykler; 20.01.2013
comment
@Pykler - это O (n) в лучшем случае и O (n * n) в худшем случае. - person Vilx-; 20.01.2013
comment
Это предполагает, что вы не можете создать в уме полностью уникальный хеш для всех носков, которые вы уже видели, что для меня является O (1), чтобы соответствовать носку, который я видел и ранее и поместил в ожидание соответствия хэш - person Pykler; 21.01.2013
comment
Собственно, это алгоритм, который я имел в виду: если у вас есть ограниченное пространство для n носков, действуйте, как описано. Если новый извлеченный носок не совпадает ни с одним из уже извлеченных, а вынутых носков уже n, положите его обратно и возьмите другой (случайным образом) или ищите в остальных, пока не найдете один подходящий , позволяя освободить слот. - person U. Windl; 30.04.2021


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

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

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

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

Есть две физические возможности:

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

Но для каждого носка, чтобы сохранить ссылку на другой, есть изящное решение: поппер (или `` кнопка с защелкой '', если вы американец), например:

http://www.aliexpress.com/compare/compare-invisible-snap-buttons.html

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

person Community    schedule 23.01.2013
comment
Это не дает ответа на вопрос, поскольку обработка уже сопряженных данных проста, вопрос в том, что делать, если данные НЕ СОПРЯЖЕНЫ, и вы хотите их связать. - person amit; 01.05.2015

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

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

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

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

person Community    schedule 30.04.2014
comment
Носки - это всего лишь метафора для объединения произвольных объектов в некую базу данных. - person amit; 01.05.2015
comment
Нет, из вопросов и ответов ясно видно, что этот вопрос на самом деле касается носков. - person Philipp; 01.05.2015
comment
Понял, не видел, что вы автор. Если вам нужно универсальное решение, вы действительно должны были сказать об этом. В любом случае, нет ничего плохого в том, чтобы принять во внимание любую имеющуюся у вас информацию, если только вам не нужно придумывать общее решение - отказ от возможности повторного использования решения может привести к значительному повышению производительности. В этом случае полезно рассмотреть вариант использования и доступную базу данных в целом. Однако у этого специального ответа на ваш специальный вопрос есть проблемы с похожими носками, например черные носки разных размеров, поэтому в некоторых случаях это не применимо. - person Philipp; 01.05.2015
comment
Кроме того, вы не получили ›2 тыс. Голосов за, потому что задали вопрос о соединении произвольных объектов в базе данных. Вы специально ограничили вопрос из-за самой природы носков (которые вы не можете дублировать, в отличие от данных), вы даже призвали использовать тот факт, что вы можете легко отличить свои носки от носков вашего супруга. Если вы зададите вопрос о носках, не ждите, что ответ будет о базах данных ;-) - person Philipp; 01.05.2015
comment
Я специально спросил в первом руководстве для ответов. Я ищу теоретический ответ. A general theoretical solution for a huge number of socks. Это первое указание, которое я написал, и я ожидаю ответа на него. Поэтому, если вы думаете, что этот ответ можно масштабировать для огромного количества носков, предоставьте информацию, как это сделать. - person amit; 01.05.2015
comment
Есть несколько предположений: обычная стиральная машина, обычная веревка для белья и тот факт, что вы одновременно выбрасываете оба носка в мусорное ведро, что означает, что в большинстве случаев оба носка находятся в одной машине, и количество носков. поэтому остатки носков, которые нужно отсортировать, невелики. Но поскольку вы действительно хотели получить ответ о хранении произвольных объектов в базе данных, действительно ли полезно обсуждать мое решение в дальнейшем? - person Philipp; 01.05.2015
comment
Я пытаюсь немного очистить поток, и буду признателен, если вы (1) решите вопросы, указанные в вопросе, или (2) удалите ответ. Конечно, решать вам, но это просьба убедиться, что поток не запутался. - person amit; 01.05.2015
comment
Как я уже сказал, я думаю, что рассмотрел все, о чем вы просили, за исключением проблемы отличимости элементов, на которую ответили другие люди. Я не пытаюсь быть здесь дураком, но некоторое время назад я приложил много усилий, чтобы ответить, и я слегка разочарован тем, что теперь вы просматриваете некоторые ответы и утверждаете, что они не ответили на исходный вопрос. . Почему бы вам просто не оставить всю ветку в покое - это все еще интересное чтение, спустя более 2 лет после того, как вы спросили о нем? - person Philipp; 01.05.2015

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

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

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

Такие предварительные усилия многократно наблюдались в очень популярном и эффективном коде. Примеры включают в себя # DEFINE преобразование числа Пи в несколько десятичных знаков (существуют и другие примеры, но это тот, который приходит в голову прямо сейчас).

person Community    schedule 07.09.2013

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

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

person Community    schedule 08.10.2013
comment
Это не отвечает на вопрос, где носки - всего лишь метафора. - person amit; 01.05.2015
comment
Вопрос заключался в том, как соединить носки из непарного ворса, а не в том, как избежать необходимости в соединении. - person amit; 02.05.2015

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

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

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

person Community    schedule 21.09.2014
comment
У этого подхода есть два других преимущества: при сушке на линии теряется намного меньше IME носков, чем при сушильной машине, и процесс сортировки можно распространить на остальное белье, так (например) все полотенца находятся рядом друг с другом, чтобы их можно было сложить. линия и мусорное ведро и доставлено прямо на их хранение. Он также работает в двух проходах с низким усилием, поднимая одежду и снова опуская ее. - person cphlewis; 11.04.2015

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

  • Выберите один из носков и уберите его (сделайте «ведро» для этой пары).
  • Если следующий является парой предыдущего, то поместите его в существующее ведро, в противном случае создайте новое.

В худшем случае это означает, что у вас будет n / 2 разных ведра, и у вас будет n-2 определения того, какое ведро содержит пару текущего носка. Очевидно, что этот алгоритм хорошо работает, если у вас всего несколько пар; Я сделал это с 12 парами.

Это не так уж и научно, но работает хорошо :)

person Community    schedule 27.10.2013
comment
Это по-прежнему алгоритм O (n ^ 2), поскольку вам нужно перебирать каждое ведро всякий раз, когда вы вытаскиваете новый носок. Но, учитывая тот факт, что даже носки, купленные в одной партии, имеют незначительные различия, которые делают их фактически уникальными в паре (или даже в единственном экземпляре), лучшего способа в любом случае нет. - person Semisonic; 24.01.2018
comment
Согласитесь, но мой алгоритм предполагает, что спаривание выполняет человек. Следовательно, когда вы ищете подходящую корзину, в вашей голове будет что-то вроде кеша, поэтому вам все равно не нужно перебирать сегменты. Не уверен, какая структура данных построена для этого механизма кеширования в моей голове во время сопряжения. - person maestro; 24.01.2018

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

Совместите с другим заданием

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

Oracle Machine лучше ;-)

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

Получите почти O(n)!

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

person wrzasa    schedule 27.05.2015

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

person Community    schedule 08.09.2013
comment
Как сделать это не на месте, как конкретно указано в вопросе? - person amit; 01.05.2015

Что насчет предварительной обработки? Я бы пришил отметку или идентификационный номер к каждому носку таким образом, чтобы каждая пара имела одинаковый маркировочный / идентификационный номер. Этот процесс может повторяться каждый раз, когда вы покупаете новую пару носков. Затем вы можете выполнить радикальную сортировку, чтобы получить общую стоимость O (n). Найдите место для каждой отметки / идентификационного номера и просто выберите все носки один за другим и поместите их в нужное место.

person Community    schedule 24.01.2013

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

Предположим, что затраты на просмотр носков и запоминание их отличительных рисунков незначительны (ε). Тогда лучшее решение - просто бросить все носки на стол. Это включает в себя следующие шаги:

  1. Выложите все носки на стол (1) и создайте хэш-карту {шаблон: позиция} (ε)
  2. While there are remaining socks (n/2):
    1. Pick up one random sock (1)
    2. Найдите положение соответствующего носка (ε)
    3. Извлеките носок (1) и сохраните пару.

Это действительно самая быстрая возможность и выполняется за n + 1 = O (n) сложность. Но это предполагает, что вы прекрасно помните все шаблоны ... На практике это не так, и мой личный опыт показывает, что вы иногда не можете найти подходящую пару с первой попытки:

  1. Все носки бросить на стол (1)
  2. While there are remaining socks (n/2):
    1. Pick up one random sock (1)
    2. while it is not paired (1/P):
      1. Find sock with similar pattern
      2. Возьмите носок и сравните оба (1)
      3. Если все в порядке, сохраните пару

Теперь это зависит от нашей способности находить подходящие пары. Это особенно актуально, если у вас темно-серые пары или белые спортивные носки, которые часто имеют очень похожий узор! Допустим, у вас есть вероятность P найти соответствующий носок. В среднем вам понадобится 1 / P попыток, прежде чем найти соответствующий носок, чтобы сформировать пару. Общая сложность составляет 1 + (n / 2) * (1 + 1 / P) = O (n).

Оба варианта линейны по количеству носков и являются очень похожими решениями. Давайте немного изменим задачу и допустим, что у вас есть несколько пар одинаковых носков в наборе, и что легко сохранить несколько пар носков за один ход (1 + ε ). Для K различных шаблонов вы можете реализовать:

  1. For each sock (n):
    1. Pick up one random sock (1)
    2. Поместите его в кластер своего шаблона
  2. For each cluster (K):
    1. Take cluster and store pairs of socks (1+ε)

Общая сложность становится n + K = O (n). Он по-прежнему линейный, но выбор правильного алгоритма теперь может сильно зависеть от значений P и K! Но можно еще раз возразить, что у вас могут возникнуть трудности с поиском (или созданием) кластера для каждого носка.

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

person Community    schedule 09.09.2013

На пути к эффективному алгоритму соединения носков из стопки

Предварительные условия

  1. В стопке должен быть хотя бы один носок
  2. Стол должен быть достаточно большим, чтобы вместить N / 2 носков (худший случай), где N - общее количество носков.

Алгоритм

Пытаться:

  1. Выбери первый носок
  2. Положи это на стол
  3. Выберите следующий носок и посмотрите на него (может возникнуть исключение «нет больше носков в стопке»)
  4. Теперь просканируйте носки на столе (выдает исключение, если на столе не осталось носков)
  5. Есть ли совпадение? a) yes = ›удалите соответствующий носок из таблицы b) no =› положите носок на стол (может возникнуть исключение «таблица недостаточно велика»)

Кроме:

  • Таблица недостаточно велика:
    тщательно перемешайте все непарные носки вместе, затем возобновите операцию
    // эта операция приведет к новой стопке и пустой таблице

  • На столе не осталось носков:
    бросок (последний неспаренный носок)

  • В куче не осталось носков:
    выйдите из прачечной.

Наконец-то:

  • Если в стопке еще остались носки:
    goto 3

Известные проблемы

Алгоритм войдет в бесконечный цикл, если вокруг нет стола или на нем недостаточно места для размещения хотя бы одного носка.

Возможное улучшение

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

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

Отсортируйте носки на столе по указанному признаку. Назовем этот атрибут «цвет». Расположите носки в ряд и поместите носки более темного цвета справа (например, .push_back ()) и носки более светлого цвета слева (например, .push_front ()).

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

Для оценки эффективности этого возможного улучшения необходимы некоторые исследования. Возникают следующие вопросы:

  • Какое оптимальное количество носков для пары с использованием вышеуказанного улучшения?
  • Сколько итераций необходимо для заданного количества носков, прежде чем пропускная способность увеличится?
    а) для последней итерации
    б) для всех итераций в целом

PoC в соответствии с рекомендациями MCVE:

#include <iostream>
#include <vector>
#include <string>
#include <time.h>

using namespace std;

struct pileOfsocks {
    pileOfsocks(int pairCount = 42) :
        elemCount(pairCount<<1) {
        srand(time(NULL));
        socks.resize(elemCount);

        vector<int> used_colors;
        vector<int> used_indices;

        auto getOne = [](vector<int>& v, int c) {
            int r;
            do {
                r = rand() % c;
            } while (find(v.begin(), v.end(), r) != v.end());
            v.push_back(r);
            return r;
        };

        for (auto i = 0; i < pairCount; i++) {
            auto sock_color = getOne(used_colors, INT_MAX);
            socks[getOne(used_indices, elemCount)] = sock_color;
            socks[getOne(used_indices, elemCount)] = sock_color;
        }
    }

    void show(const string& prompt) {
        cout << prompt << ":" << endl;
        for (auto i = 0; i < socks.size(); i++){
            cout << socks[i] << " ";
        }
        cout << endl;
    }

    void pair() {
        for (auto i = 0; i < socks.size(); i++) {
            std::vector<int>::iterator it = find(unpaired_socks.begin(), unpaired_socks.end(), socks[i]);
            if (it != unpaired_socks.end()) {
                unpaired_socks.erase(it);
                paired_socks.push_back(socks[i]);
                paired_socks.push_back(socks[i]);
            }
            else
                unpaired_socks.push_back(socks[i]);
        }

        socks = paired_socks;
        paired_socks.clear();
    }

private:
    int elemCount;
    vector<int> socks;
    vector<int> unpaired_socks;
    vector<int> paired_socks;
};

int main() {
    pileOfsocks socks;

    socks.show("unpaired socks");
    socks.pair();
    socks.show("paired socks");

    system("pause");
    return 0;
}
person Laszlo    schedule 16.02.2017
comment
Вы должны были быть, пока не использовали GOTO: :( - person NTDLS; 10.12.2020
comment
Я часто прошу детей помочь мне с этой задачей, и возникает вопрос: безопасен ли этот поток? - person NTDLS; 10.12.2020

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

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

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

At time i:

Blue  read  Pile[i]    : If Blue  then Blue.Count++  ; B=TRUE  ; sync

Red   read  Pile[i+1]  : If Red   then Red.Count++   ; R=TRUE  ; sync

Green read  Pile [i+2] : If Green then Green.Count++ ; G=TRUE  ; sync

С процессом синхронизации:

Sync i:

i++

If R is TRUE:
    i++
    If G is TRUE:
        i++

Для этого требуется инициализация:

Init:

If Pile[0] != Blue:
    If      Pile[0] = Red   : Red.Count++
    Else if Pile[0] = Green : Green.Count++

If Pile[1] != Red:
    If Pile[0] = Green : Green.Count++

Где

Best Case: B, R, G, B, R, G, .., B, R, G

Worst Case: B, B, B, .., B

Time(Worst-Case) = C * n ~ O(n)

Time(Best-Case) = C * (n/k) ~ O(n/k)

n: number of sock pairs
k: number of colors
C: sync overhead
person Community    schedule 25.05.2014

Две линии мышления: скорость, необходимая для поиска любого совпадения, по сравнению со скоростью, необходимой для поиска всех совпадений, по сравнению с хранилищем.

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

Если у вас есть несколько свойств, для которых нужно сопоставить, вы можете использовать сгруппированные кортежи и более причудливые итераторы zip и функции преобразования тяги, для простоты, хотя вот простой запрос на основе графического процессора:

//test.cu
#include <thrust/device_vector.h>
#include <thrust/sequence.h>
#include <thrust/copy.h>
#include <thrust/count.h>
#include <thrust/remove.h>
#include <thrust/random.h>
#include <iostream>
#include <iterator>
#include <string>

// Define some types for pseudo code readability
typedef thrust::device_vector<int> GpuList;
typedef GpuList::iterator          GpuListIterator;

template <typename T>
struct ColoredSockQuery : public thrust::unary_function<T,bool>
{
    ColoredSockQuery( int colorToSearch )
    { SockColor = colorToSearch; }

    int SockColor;

    __host__ __device__
    bool operator()(T x)
    {
        return x == SockColor;
    }
};


struct GenerateRandomSockColor
{
    float lowBounds, highBounds;

    __host__ __device__
    GenerateRandomSockColor(int _a= 0, int _b= 1) : lowBounds(_a), highBounds(_b) {};

    __host__ __device__
    int operator()(const unsigned int n) const
    {
        thrust::default_random_engine rng;
        thrust::uniform_real_distribution<float> dist(lowBounds, highBounds);
        rng.discard(n);
        return dist(rng);
    }
};

template <typename GpuListIterator>
void PrintSocks(const std::string& name, GpuListIterator first, GpuListIterator last)
{
    typedef typename std::iterator_traits<GpuListIterator>::value_type T;

    std::cout << name << ": ";
    thrust::copy(first, last, std::ostream_iterator<T>(std::cout, " "));
    std::cout << "\n";
}

int main()
{
    int numberOfSocks = 10000000;
    GpuList socks(numberOfSocks);
    thrust::transform(thrust::make_counting_iterator(0),
                      thrust::make_counting_iterator(numberOfSocks),
                      socks.begin(),
                      GenerateRandomSockColor(0, 200));

    clock_t start = clock();

    GpuList sortedSocks(socks.size());
    GpuListIterator lastSortedSock = thrust::copy_if(socks.begin(),
                                                     socks.end(),
                                                     sortedSocks.begin(),
                                                     ColoredSockQuery<int>(2));
    clock_t stop = clock();

    PrintSocks("Sorted Socks: ", sortedSocks.begin(), lastSortedSock);

    double elapsed = (double)(stop - start) * 1000.0 / CLOCKS_PER_SEC;
    std::cout << "Time elapsed in ms: " << elapsed << "\n";

    return 0;
}

    //nvcc -std=c++11 -o test test.cu

Время работы для 10 миллионов носков: 9 мс

person JMan Mousey    schedule 17.08.2017

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

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

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

person AlDante    schedule 13.04.2021

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

  1. Сделайте на полу позади себя две воображаемые секции, одну для себя, а другую для вашего супруга.

  2. Возьмите одну из стопки носков.

  3. Теперь положите носки на пол по очереди, следуя приведенному ниже правилу.

    • Определите, что это ваши носки, и посмотрите на соответствующую секцию на полу.

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

    • Поместите его в соответствующий раздел.

  4. Повторяйте 3, пока все носки не снимутся со стопки.


Пояснение:

Хеширование и абстракция

Абстракция - очень мощная концепция, которая использовалась для улучшения пользовательского опыта (UX). Примеры абстракции в реальных взаимодействиях с компьютерами включают:

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

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

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

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

Как определить наш хеш-ключ?

Приведенное ниже определение для нашего ключа также будет работать, если существует более одной пары похожих носков. То есть, допустим, есть две пары черных мужских носков PairA и PairB, и каждый носок называется PairA-L, PairA-R, PairB-L, PairB-R. Таким образом, PairA-L может быть объединена с PairB-R, но PairA-L и PairB-L не могут быть объединены в пару.

Допустим, любой носок можно однозначно идентифицировать по

Attribute[Gender] + Attribute[Colour] + Attribute[Material] + Attribute[Type1] + Attribute[Type2] + Attribute[Left_or_Right]

Это наша первая хеш-функция. Давайте использовать короткие обозначения для этого h1(G_C_M_T1_T2_LR). h1 (x) - это не наш ключ местоположения.

Другой хеш-функцией, исключающей атрибут Left_or_Right, будет h2(G_C_M_T1_T2). Вторая функция h2 (x) - это ключ нашего местоположения! (для пространства на полу позади вас).

  • Чтобы найти слот, используйте h2 (G_C_M_T1_T2).
  • Как только слот будет найден, используйте h1 (x), чтобы проверить их хэши. Если они не совпадают, у вас есть пара. Иначе бросьте носок в тот же слот.

ПРИМЕЧАНИЕ. Поскольку мы удаляем пару, как только находим ее, можно с уверенностью предположить, что будет только один слот с уникальным значением h2 (x) или h1 (x).

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

Почему так важно класть носки на пол

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

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

Почему важно снимать пару с пола?

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

Анализ

  1. Case 1: Worst case when Derpina cannot remember or spot the socks on the floor directly using the hashing technique. Derp does a linear search through the items on the floor. This is not worse than the iterating through the pile to find the pair.
    • Upper bound for comparison: O(n^2).
    • Нижняя граница для сравнения: (n / 2). (когда каждый второй носок, который подбирает Дерпина, оказывается парой предыдущего).
  2. Case 2: Derp remembers each the location of every sock that he placed on the floor and each sock has exactly one pair.
    • Upper bound for comparison: O(n/2).
    • Нижняя граница для сравнения: O (n / 2).

Я говорю об операциях сравнения, выбор носков из кучи обязательно потребует n операций. Таким образом, практическая нижняя граница будет равна n итерациям с n / 2 сравнениями.

Ускорение работы

Чтобы получить высший балл, чтобы Дерп получил O (n / 2) сравнений, я бы порекомендовал Дерпину,

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

Это эквивалентно проблеме отличимости элементов?

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

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

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

person Community    schedule 21.01.2013
comment
Итак, в основном другое, а не разделение проблемы на 2 подзадачи (без повторного разделения ее позже) - он предлагает кэшировать столько элементов, сколько я могу (верх каждой точки), при этом складывая их, и повторять, пока есть еще элементы. Можете ли вы провести анализ сложности? Моя интуиция подсказывает мне, что в среднем будет хуже, чем O (n ^ 2) (хотя я пока не могу это доказать), и вы не можете ограничить количество выполняемых итераций. Вам также понадобится некоторая рандомизация, чтобы гарантировать, что вы каждый раз будете брать элементы в разном порядке. Или мне что-то здесь не хватает? - person amit; 21.01.2013
comment
в худшем случае (при условии, что все пары мужские и разные) будет n ^ 2, а с другой стороны, количество линейных поисков, которые вам понадобятся, будет n / 2. Позже сегодня я улучшу свой ответ, чтобы объяснить, как итерации будут выполняться при сокращении множеств. - person D34dman; 22.01.2013
comment
@amit РЕДАКТИРОВАТЬ ПРИМЕЧАНИЕ: изначально я хотел указать, что хеширование возможно. Но из-за того, что поведение человеческого разума является спорадическим, хеширование не является полностью надежным, поэтому была предложена смесь хеширования и линейного поиска. Я выступаю за линейный поиск в отличие от любой другой формы поиска, поскольку он требует наименьшего напряжения для человеческого разума. Поскольку метод хеширования может оказаться довольно напряженным, линейный поиск будет большим облегчением. ИМХО, эффективность следует измерять относительно времени, необходимого для завершения этой операции, а не требуемых итераций. - person D34dman; 29.01.2013

person    schedule
comment
Это именно то, что я делаю! Я делаю стопки в зависимости от стиля открытия носка (у меня только белый), что дает мне достаточно ведер, чтобы быстро сопоставить каждое из них. - person Scott Chamberlain; 20.01.2013
comment
Является ли сортировка полезной или нет, зависит от предметной области, в частности от топографии фазового пространства основного критерия группировки. В качестве контрпримера к вашему утверждению, почти все мои носки в некоторой вариации черного цвета, поэтому основным критерием группировки вместо этого является форма, а быстрый способ определить форму черного носка - проверить длину. В этом случае, я бы сказал, сортировка повышает эффективность. - person mikołak; 20.01.2013
comment
Я обратился к проблеме параллелизма и различимости элементов. - person usr; 20.01.2013
comment
@TheTerribleSwiftTomato Я считаю, что сортировка по длине поможет здесь только потому, что люди не умеют хешировать по длине. Впрочем, можно было образовывать стопки на каждый миллиметр длины. Каждая куча адресуется в O(1), поэтому наша схема распределения по-прежнему работает и должна быть быстрее, чем сортировка (на самом деле мы почти сортируем, но только случайно). - person usr; 20.01.2013
comment
@usr: ну, я бы сказал, это потому, что а) люди уделяют большое внимание упорядочиванию (как, например, показывают эксперименты Ultimatum Game), б) люди обладают очень мощными, распараллеленными способностями оптического распознавания - видеть, как ряд носков вытаскивают из После сортировки стопки по длине вы, вероятно, сразу сможете поместить следующий носок из стопки в нужное место. Проблема в том, что поставленному в настоящее время вопросу не хватает ясности в одном отношении: относимся ли мы к людям как к реальным биологическим объектам (со всеми возможными оптимизациями) или как к биороботам без учета их возможностей? - person mikołak; 20.01.2013
comment
Сколько раз вам придется рекурсивно применять эту схему, пока вы не распределите все носки на очень маленькие стопки, которые вы сможете визуально обработать немедленно? Я бы посчитал это как O (n log n). Если мой расчет верен, чем это лучше сортировки? - person emory; 20.01.2013
comment
@emory прочтите абзац о проблеме различимости элементов. Я обращаюсь к этим опасениям там. Вполне может потребоваться только один шаг распределения; Помимо асимптотической сложности, я бы сказал, что распределение по стопкам проще для людей, чем сортировка по какому-то произвольному измерению и порядку (красный меньше синего? Больше не помню ...). - person usr; 20.01.2013
comment
Я пробовал это со своими носками (у меня легко набралось 30+ пар), и, черт возьми, это БЫСТРО. Одна проблема, которую я обнаружил, - это когда у меня не может быть достаточно хорошего алгоритма хеширования (у меня много белых носков без какого-либо рисунка), поэтому это становится сложно. В таком случае, что было бы оптимальным способом сделать это? - person NothingsImpossible; 20.01.2013
comment
@NothingsImpossible - вот как выглядят хэш-атаки для плохого веб-сервера! Различимы ли белые носки по какому-либо признаку? Должно быть что-то, на чем вы можете их распространять. В противном случае вы могли бы просто произвольно формировать пары. - person usr; 20.01.2013
comment
@usr Они различимы, но не с первого взгляда. По сравнению с хешированием файлов это похоже на то, что цветные носки - это файл размером 100 КБ, а белые - файлы размером 1 ГБ, на анализ уходит гораздо больше времени. На практике я все равно использую разные носки, потому что этого никто не заметит. - person NothingsImpossible; 20.01.2013
comment
Удовлетворяет ли это логарифмическому пределу пространства, зависит от качества хэш-функции. Допустим, есть идеальный хеш ... потребуется O (n) памяти, чтобы запомнить, какая черта связана с каким ведром. Это не проблема с целочисленным хешем, поскольку вам не нужно хранить таблицу значений для сегментов (вы просто применяете некоторую арифметику), но здесь это проблема. Если вы не храните таблицу поиска в памяти, вам необходимо выполнить сканирование всех сегментов, что (опять же, в зависимости от качества хэша) может быть не лучше, чем просто сканирование стопки. - person Mark Peters; 20.01.2013
comment
@MarkPeters хороший момент. Кто-то может возразить, что мы используем человеческий мозг как ассоциативный массив: мы можем сразу определить соответствующую кучу определенного цвета. В этом смысле мозг - это параллельная аппаратная машина. - person usr; 20.01.2013
comment
Еще одним частым отличительным признаком белых носков является носок - разноцветная нить, вышитое слово и т. Д. - person GalacticCowboy; 20.01.2013
comment
Это Radix Sort, и я согласен, что это правильный ответ. @MarkPeters Я не думаю, что вам нужна таблица поиска. Один линейный проход по носкам может преобразовать носки в числовые векторы, что делает отображение сегмента носка в ведро тривиальным. Носки можно привязать к векторам с помощью строки, так что вам не понадобится еще один линейный проход в конце. - person Pointy; 21.01.2013
comment
(@MarkPeters, хотя я предполагаю, что во время этого прохода вам понадобится какой-то механизм сопоставления.) - person Pointy; 21.01.2013
comment
криптографические хеш-функции, такие как md5, здесь не нужны. - person Janus Troelsen; 21.01.2013
comment
@JanusTroelsen правда. Это был пример практически идеальной хеш-функции. Подойдет любая хорошая хеш-функция, но для ясности мне пришлось назвать одну. - person usr; 21.01.2013
comment
Я предполагал, что все так поступают. Конечно, я обычно прерываю цикл после обнаружения первой пары, так как мне повезет, если заполнение носков приводит к набору только носков. - person Jodrell; 22.01.2013
comment
Парень, с которым я учился в колледже, действительно имел PairID. Его пришивали на каждую пару носков нитками: 1, 2, 3, 4 ... - person Ryan Lundy; 25.01.2013
comment
Для огромного количества носков это могло бы быть решением, но, вероятно, было бы излишним рекурсивно накапливать их. Учитывая, что процесс складывания будет намного сложнее каждый раз, когда вы попытаетесь различить носки в стопке, так как разница не будет мгновенной для человеческого глаза / мозга. Так что я думаю, что всего одного или двух раундов наложения будет достаточно, чтобы начать сопоставление в стопке. - person harun; 25.01.2013
comment
Или вы можете сделать то же самое, что и я, и купить 100% того же носка, и тогда вы можете гарантировать время O (1) на поиск и сортировку. - person davethegr8; 06.09.2013
comment
If each sock had an integer called "PairID" one could easily distribute them into 10 buckets according to […] the last digit Моей первой мыслью было купить большой черный светильник (каламбур не предназначен) и сделать маркировку на всех носках с помощью этого красителя, который можно увидеть только в ультрафиолетовом свете, так, чтобы любые два носка с одинаковой маркировкой совпадали. - person Blacklight Shining; 24.01.2014
comment
Вздох. Когда у вас разложены носки на столе, вам не нужно делать ничего особенного. При хорошем освещении и хорошем зрении вы мгновенно выбираете пары. Это полностью автоматизировано, и наш мозг обрабатывает изображение каждого носка параллельно, а также указывает пару, которая имеет наибольшую вероятность совпадения. Если таблица достаточно велика, вам может потребоваться пара объектов визуального сканирования (скажем, выступающих из рабочего места колышков), чтобы обеспечить шаблон визуального сканирования, охватывающий всю таблицу. Затраты времени на это пропорциональны количеству носков. - person Kuba hasn't forgotten Monica; 26.03.2014
comment
+1 Для параллельного решения вы можете создать поток для каждого цвета со своим собственным списком, если они идут синхронно, они могут читать одну и ту же структуру данных без ожидания - person Khaled.K; 25.05.2014
comment
@Pointy: технически это не хеширование или сортировка по основанию, а сортировка по ведру (что в основном означает обобщение сортировки по основанию). en.wikipedia.org/wiki/Bucket_sort - person ldog; 27.06.2014
comment
Что касается параллелизма, я думаю, мы могли бы также ввести сходство потоков, чтобы задействованные несколько воркеров фактически были разными владельцами носков. Каждый из них должен более эффективно выбирать носки, если их вкусы не похожи. - person rupps; 07.12.2014
comment
@ davethegr8, но спаривание все равно будет O(1) :-) - person k_g; 03.04.2015
comment
@usr Я собираюсь задать этот вопрос, чтобы выйти из вики-сообщества. Я буду рад, если вы сможете немного очистить его, если он стал беспорядочным за то время, когда это была вики сообщества. Спасибо. - person amit; 01.05.2015
comment
вы мгновенно выбираете пары - действительно вздох. Нет, очевидно, что это не мгновенно, и время обработки мозга нелинейно увеличивается с количеством носков ... как и время физического достижения случайных позиций на столе. Любой, кто действительно отсортировал носки, знает, что это будет намного быстрее, если вы воспользуетесь числовыми стопками, к которым вы можете быстро добраться, и избежите произвольного доступа. - person Jim Balter; 27.05.2015
comment
Я не могу поверить, что вы можете набрать 19K на SO, отвечая на вопрос о носках - person Mick; 31.08.2016
comment
@Mick - это не http://stackoverflow.com/questions/927358/how-to-undo-last-commit-in-git более вопиющий? :) Кстати, дневной прирост ограничен 200 очками. - person usr; 31.08.2016
comment
У меня много очень похожих носков, поэтому я не могу отсортировать их по градиенту цвета / рисунка, просто глядя на один, мне приходится сравнивать его с другими. Будет ли этот метод работать для меня? - person Fabian Röling; 21.07.2017
comment
@Fabian нет, хеширование требует сравнения на равенство. Вы можете немного упростить задачу, отсортировав носки по некоторому непрерывному атрибуту, например, по основному цвету. Вы можете поместить носки в R-дерево, если хотите использовать непрерывные атрибуты. Это может иметь смысл, если у вас ›1 миллион носков. - person usr; 26.07.2017
comment
Я дальтоник ... Шаг 1 - для каждого цвета ... Ах, дрянь! - person ; 04.08.2017
comment
Обратите внимание, что существует инструкция SIMD для случаев, когда всем рабочим нужно объединить свои наборы стопок, при условии, что у вас есть достаточно ровный пол, чтобы сдвинуть стопки носков вместе. - person TamaMcGlinn; 02.11.2018
comment
Я дал эту работу своим детям, по-видимому, они используют сортировку BOGO, которая, кажется, работает отлично, если это не так. - person NTDLS; 10.12.2020