Як можна з’єднати шкарпетки з ворсу?


3911

Вчора я спарував шкарпетки з чистої білизни і зрозумів, як я це роблю, не дуже ефективно. Я робив наївний пошук - вибирав один шкарпетку і "повторював" купу, щоб знайти її пару. Це вимагає ітерації по п / 2 * N / 4 = п 2 /8 шкарпетки в середньому.

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

Хешинг чи інші невідповідні рішення - це не варіант, тому що я не в змозі дублювати шкарпетки (хоча це могло б бути приємно, якби міг).

Отже, питання в основному:

Враховуючи купу nпар шкарпеток, що містять 2nелементи (припустимо, у кожного шкарпетки є рівно одна відповідна пара), який найкращий спосіб з’єднати їх ефективно з логарифмічним додатковим простором? (Я вважаю, що я можу запам'ятати цю кількість інформації, якщо потрібно.)

Я буду вдячний за відповідь, що стосується таких аспектів:

  • Загальне теоретичне рішення для величезної кількості шкарпеток.
  • Дійсна кількість шкарпеток не така вже й велика, я не вірю, що у мого подружжя і в мене більше 30 пар. (І відрізнити мої шкарпетки від її досить легко; чи можна це використовувати і?)
  • Це еквівалентно проблемі відмінності елементів ?

448
Я використовую принцип голубових отворів, щоб з'єднати рівно один з купою для білизни. У мене є 3 різних кольори шкарпеток (Червоний, Синій та Зелений) і по 2 пари кожного кольору. Я щодня беру чотири шкарпетки і завжди складаю пару і берусь на роботу.
Шрінівас

59
Ще один принцип отворів для голубів: якщо ви берете підмножину з n / 2 +1 шкарпеток, у цьому підмножині має бути принаймні одна пара.
wildplasser

40
Чудове запитання! Можливо, вас зацікавить моя стаття про пов’язану проблему, яка полягає в обговоренні ймовірності витягнути зі стопки два зібраних
Ерік Ліпперт

335
Чому б не покласти нересту дитину, waitpidщоб ви, як батько, навіть не сортували шкарпетки?
Mxyk

137
Я вирішив цю проблему, лише володіючи білими носками на колінах. Всі вони відповідають. Я міг просто схопити будь-які два шкарпетки навмання зі стопки, і вони відповідали б. Я ще більше спрощую проблему, НЕ спарюючи шкарпетки. У мене є ящик для шкарпеток, в який я просто кидаю всі свої шкарпетки, не спарені. Я щоранку хапаю двох навмання з шухляди. Я спростив його до О (0). Неможливо отримати щось простіше. :)
Лі

Відповіді:


2448

Рішення для сортування запропоновано, але сортування трохи забагато : нам не потрібен порядок; нам просто потрібні групи рівності .

Тож хешування буде досить (і швидше).

  1. Для кожного кольору шкарпеток сформуйте ворс . Повторіть всі шкарпетки у вхідному кошику та розподіліть їх на кольорові палі .
  2. Повторіть кожну купу і розподіліть її за допомогою іншої метрики (наприклад, шаблону) у другому наборі паль
  3. Рекурсивно застосовуйте цю схему, поки не розподілите всі шкарпетки на дуже маленькі палі, які ви зможете візуально обробити негайно

Цей тип рекурсивного хеш-розбиття фактично робиться SQL Server, коли йому потрібно об'єднати хеш або агрегувати хеш для величезних наборів даних. Він розподіляє вхідний потік збірки на безліч незалежних розділів. Ця схема лінійно масштабує довільну кількість даних та декілька процесорів.

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

Якщо кожен шкарпетка мав ціле число під назвою "PairID", можна було легко розподілити їх у 10 відрах відповідно до PairID % 10(остання цифра).

Найкращий розділ у реальному світі, про який я можу придумати, - це створення прямокутника паль : один вимір - колір, інший - візерунок. Чому прямокутник? Тому що нам потрібен O ​​(1) випадковий доступ до паль. (3D- кубоїд також працював би, але це не дуже практично.)


Оновлення:

А як щодо паралелізму ? Чи може кілька людей швидше співставити шкарпетки?

  1. Найпростіша стратегія паралелізації полягає в тому, щоб кілька робітників взяли з вхідного кошика і наділи шкарпетки на палі. Це лише настільки масштабує - уявіть, що 100 людей борються за 10 паль. Витрати на синхронізацію (проявляючи себе як зіткнення рук та спілкування між людьми) руйнують ефективність та швидкість (див. Закон про загальну масштабованість !). Це схильне до тупиків ? Ні, тому що кожному працівникові потрібно отримати доступ до однієї купи за один раз. За допомогою лише одного «блокування» не може бути глухого кута. Livelocks можуть бути можливі залежно від того, як люди координують доступ до паль. Вони можуть просто використовувати випадковий бакфікяк, наприклад, мережеві карти, роблять це на фізичному рівні, щоб визначити, яка карта може виходити виключно з мережевого проводу. Якщо він працює для НІК , він повинен працювати і для людей.
  2. Він масштабується майже нескінченно, якщо кожен робітник має свій набір паль . Потім робітники можуть взяти великі шматки шкарпеток із вхідного кошика (дуже мало суперечок, оскільки вони роблять це рідко), і їм взагалі не потрібно синхронізуватись, коли вони роздають шкарпетки (бо вони мають локальні палі). Зрештою, всі працівники повинні об'єднати свої набори. Я вважаю, що це можна зробити в O (журнал (кількість робітників * паль на одного робітника)), якщо працівники формують дерево агрегації .

Що з проблемою відмінності елементів ? Як зазначається в статті, проблема розрізнення елементів може бути вирішена в O(N). Це те саме для проблеми шкарпеток (також O(N), якщо вам потрібен лише один крок розподілу (я запропонував кілька кроків лише тому, що люди погані в обчисленнях - одного кроку достатньо, якщо ви поширюєте на md5(color, length, pattern, ...), тобто ідеальний хеш усіх атрибутів)).

Зрозуміло, що не можна йти швидше O(N), тому ми досягли оптимальної нижньої межі .

Хоча виходи не зовсім однакові (в одному випадку просто булеві. В іншому випадку пари шкарпеток), асимптотичні складності однакові.


72
Це саме те, що я роблю! Я роблю палі залежно від стилю відкриття шкарпетки (у мене тільки білий), що дає мені достатньо «відра», щоб швидко відповідати кожному з них.
Скотт Чемберлен

29
Я спробував це з своїми шкарпетками (у мене легко 30+ пар), і людина це Швидше. Я знайшов одну з проблем, коли я не можу мати достатньо хорошого алгоритму хешування (у мене багато білих шкарпеток без будь-якого шаблону), тому стає важко. У такому випадку, який був би оптимальний спосіб зробити це?
Нічого не можливе

56
@NothingsImpossible - так виглядають атаки хеш-зіткнення для поганого веб-сервера! Чи можна відрізняти білі шкарпетки за якоюсь ознакою? Має бути щось, на чому ви можете їх розповсюджувати. В іншому випадку ви могли просто сформувати пари довільно.
usr

37
Це сортування Radix, на який я згоден - це правильна відповідь. @MarkPeters Я не думаю, що вам не потрібна таблиця пошуку. Один лінійний прохід над шкарпетками може перетворити шкарпетки на числові вектори, зробивши відображення «сегмента шкарпетки» у відро тривіальним. Шкарпетки можна прив’язати до векторів струною, так що вам не потрібен ще один лінійний прохід в кінці.
Pointy

49
Хлопець, з яким я ходив до коледжу, насправді мав PairIDs. Її пришивали на кожну пару шкарпеток з ниткою: 1, 2, 3, 4 ...
Ryan Lundy

579

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

Люди можуть перемогти алгоритми процесора, використовуючи той факт, що «пошук відповідної пари» може бути однією операцією для набору, який не надто великий.

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

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);
}

Принаймні, це те, що я використовую в реальному житті, і я вважаю це дуже ефективним. Недоліком є ​​те, що вона вимагає плоскої поверхні, але вона зазвичай рясна.


228
зі збільшенням кількості шкарпеток SIMD людини стає не кращим, ніж процесор.
Лежати Райан

25
Найкраща відповідь, ІМО. Хоча це цікаво і розумно (і підходить для SO), щоб зменшити щоденну проблему до комп’ютерного алгоритму, має набагато більше сенсу використовувати силу роздільної здатності ока / мозку людини для набору, що становить ~ 60 шкарпеток.
drug_user841417

13
@LieRyan Якщо шкарпетки будуть рівномірно розподілені, ви в кінцевому підсумку помітите пару в будь-якому достатньо невеликому наборі шкарпеток через парадокс дня народження (якщо ви не зможете розрізнити кольори до довільної точності, в чому я сумніваюся), тому вузького місця тут не буде алгоритм відповідності кольорів людини, але крок розповсюдження.
Томас

13
@ dpc.ucore.info Ні, тому що вони мають різні плетені манжети, довжину манжети, загальну довжину та відтінки чорного (моя дружина, ймовірно, фізично зачепила б мене за цю останню).
Крістіан

199
Ви краще сподіваєтесь, що у вас є рівна кількість шкарпеток, інакше довго збираєте шкарпетки ...
Патрік Джеймс МакДугле

258

Випадок 1 : Усі шкарпетки однакові (це, до речі, я роблю в реальному житті).

Виберіть будь-який із них, щоб скласти пару. Постійний час.

Випадок 2 : Існує постійна кількість комбінацій (форма власності, колір, розмір, фактура тощо).

Використовуйте сортування radix . Це лише лінійний час, оскільки порівняння не потрібно.

Випадок 3 : Кількість комбінацій не відома заздалегідь (загальний випадок).

Ми маємо зробити порівняння, щоб перевірити, чи поєднуються два шкарпетки в парі. Виберіть один із O(n log n)алгоритмів сортування на основі порівняння.

Однак у реальному житті, коли кількість шкарпеток є відносно невеликою (постійною), ці теоретично оптимальні алгоритми не спрацюють добре. Це може зайняти навіть більше часу, ніж послідовний пошук, який теоретично вимагає квадратичного часу.


8
> Це може зайняти навіть більше часу, ніж послідовний пошук, який теоретично вимагає квадратичного часу. Так, тому я ненавиджу це робити, можливо, я повинен скинути всі свої шкарпетки і почати зі справи 1.
Нілс,

57
нижня сторона всіх однакових шкарпеток полягає в тому, що вони мають тенденцію до старіння з різними темпами. Тож ви все ще намагаєтеся їх зрівняти з урахуванням того, наскільки вони зношені. (що складніше, ніж просто узгодити за зразком)
SDC

118
Проблема з наявністю 60 пар однакових шкарпеток, "оскільки це спрощує створення пари", полягає в тому, що це створює враження, що ви працюєте з комп'ютерами.
Стів Івз

13
Випадок 1 - це не постійний час, коли є якась операція, наприклад, складання пар разом. У цьому випадку це лінійний час з найменшим постійним коефіцієнтом (доведення цього залишається як вправа для читача). Один не може займати той же час складається одну пару і відро шкарпеток. Однак вона масштабується лінійно. За законом Амдала, він має необмежену швидкість, ігноруючи накладні витрати. За законом Густафсона ви можете скласти стільки пар, скільки потрібно, щоб скласти одну пару, даючи достатню кількість робітників (кількість яких залишається читачем як вправа), ігноруючи накладні витрати.
ацелент

7
@PauloMadeira Сортування - це постійний час - ти просто береш купу і кладеш її у свій ящик. Єдиною операцією в цьому випадку є фактично надягання шкарпеток на ноги, що також є постійним. Продуктивність досягається відкладеним виконанням шкарпетки, можливо, з певною жертвою в просторі (споживаний простір не складених шкарпеток більший, ніж у складених). Я стверджую, що це того варте; Я зазвичай програю цей аргумент зі своєю дружиною.
Тревіс

157

Неалгоритмічна відповідь, але "ефективна", коли я це роблю:

  • крок 1) відкиньте всі наявні шкарпетки

  • крок 2) перейдіть до Walmart і придбайте їх по 10 - n пакетів білого і m пакетів чорного кольору. Немає потреби в інших кольорах у повсякденному житті.

Але мені доводиться робити це ще раз (втрачені шкарпетки, пошкоджені шкарпетки тощо), і я ненавиджу занадто часто відкидати ідеально хороші шкарпетки (і я хотів, щоб вони продовжували продавати однакові посилання на шкарпетки!), Тому я нещодавно взяв інший підхід.

Алгоритмічна відповідь:

Поміркуйте, ніж якщо ви намалюєте лише один шкарпетку для другої стопки шкарпеток, як це робите, шанси на пошук відповідного шкарпетки в наївному пошуку досить низькі.

  • Тож візьміть їх п’ять навмання і запам’ятайте їх форму або довжину.

Чому п’ять? Зазвичай люди добре пам’ятають між п'ятьма і семима різними елементами робочої пам’яті - трохи схожий на людський еквівалент стека RPN - п'ять - це безпечний дефолт.

  • Візьміть один із стека 2n-5.

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

  • Тримайте випадковим чином вибираючи шкарпетки зі стопки і порівняйте свої 5 + 1 шкарпетки на матч. У міру зростання вашої стеки це знизить вашу ефективність, але підвищить шанси. Набагато швидше.

Не соромтеся записати формулу, щоб обчислити, скільки зразків потрібно намалювати для 50% шансів відповідності. IIRC - це закон гіпергеометричної форми.

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

До речі , я виявив, що сума трансакційних витрат на сортування всіх шкарпеток кожного разу, коли мені потрібна пара, була набагато меншою, ніж робити це один раз і прив’язувати шкарпетки. Тільки вчасно працює краще, тому що тоді не потрібно зв’язувати шкарпетки, а також зменшується граничне повернення (тобто ви продовжуєте шукати два-три шкарпетки, що колись у пральні і які вам потрібні щоб закінчити відповідність шкарпеток, і ви на це втрачаєте час).


25
Підвищення відповіді на "не алгоритмічну" відповідь. Це саме те, що я роблю, і це чудово працює. Проблема із заміною не є проблемою, якщо ви «обертаєте» свій шкарпетковий запас, поклавши випрані шкарпетки спиною і витягнувши з передньої частини ящика вранці. Всі шкарпетки носять рівномірно. Коли я починаю помічати деякий одяг на одному, я ставлю на список покупок, щоб повністю замінити весь цей клас шкарпеток. Для старих шкарпеток я даю найкращі 20% на Гудвіл (прив’язаний до продуктового мішка, щоб вони не змішалися назад) і залишити решту. Ви не витрачаєте шкарпетки, на даний момент у 80% все одно залишилось лише 6 місяців.
FastAl

2
BTW (1) Пов'язування шкарпеток призводить до того, що еластичний зберігається розтягнутим, а воля вийде з ладу набагато швидше. Обмеження видів унікальних шкарпеток робить обв’язку необмеженою. (2) Недоліком обмеження унікальних шкарпеток є те, що для людей з певними модними проблемами метод може бути непридатним.
FastAl

3
Я прийшов сюди спеціально, щоб опублікувати вашу "не алгоритмічну" відповідь. Як і в справжній інформатиці, більшість людей ніколи не приділяють належної уваги даним та його структурі.
bkconrad

Я використовую цей алгоритмічний підхід щоранку, і він працює як шарм! Крім того, я поклав зношені шкарпетки на іншу купу, щоб пізніше їх викинути (на жаль, їм вдається знову дістатись до оригінальної ворсинки, перш ніж я знайду час її виправити).
Donatas Olsevičius

3
«N пакетів білого кольору та m пакетів чорного кольору. Немає потреби в інших кольорах у повсякденному житті »Хорошим стандартним правилом для легкого вибору шкарпеток є насправді те, що вони повинні відповідати або кольору ваших штанів, або кольору вашого пояса. З цієї причини кольори, що найчастіше використовуються, швидше за все, будуть чорний, синій, сірий та деякі коричневі. Важко повірити, що потрібно багато білих шкарпеток.
Андреа Лацаротто

106

Що я роблю, це те, що я беру перший шкарпетку і кладу його (скажімо, на край чаші для білизни). Потім я беру ще один шкарпетку і перевіряю, чи він такий, як перший носок. Якщо це так, я виймаю їх обох. Якщо це не так, я відкладаю його біля першого шкарпетки. Потім я беру третій носок і порівнюю його з першими двома (якщо вони ще є). І т.д.

Цей підхід можна досить легко реалізувати в масиві, якщо припустити, що "зняття" шкарпеток - це варіант. Насправді вам навіть не потрібно «знімати» шкарпетки. Якщо вам не потрібне сортування шкарпеток (див. Нижче), ви можете просто перемістити їх і закінчити масивом, у якому всі шкарпетки розташовані парами в масиві.

Якщо припустити, що єдиною операцією для шкарпеток є порівняння рівності, цей алгоритм в основному все ще є n 2 алгоритмом, хоча я не знаю про середній випадок (ніколи не навчився його обчислювати).

Сортування, звичайно, підвищує ефективність, особливо в реальному житті, де можна легко «вставити» шкарпетку між двома іншими шкарпетками. У обчисленні того ж можна досягти деревом, але це додатковий простір. І, звичайно, ми знову в NlogN (або трохи більше, якщо є кілька шкарпеток, однакових за критеріями сортування, але не від тієї ж пари).

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


7
Це також я роблю, (зауважте, що якщо ви просто залишите пробіли, то вставки також є O (1)), але це погано масштабується з теоретично великою кількістю шкарпеток.
Mooing Duck

15
ваги погано з теоретично великою кількістю видів шкарпеток
Стівен Лу

@StevenLu - як я вже сказав - це n * n чи nLogn, залежно від того, сортуєте ви його чи ні. Таким чином, він масштабується приблизно так само погано, як і будь-який алгоритм сортування. Якщо ви хочете швидше, пронумеруйте їх і скористайтеся радіо-сортуванням.
Vilx-

Це, по суті, зберігає знайдені, але не збігаються шкарпетки в пошуку на основі хешу. Ідеальний хеш - це O (n), але якщо у вас збережено достатньо шкарпеток, що хеш починає вироджуватися, він стає відповідно складнішим.
Джон Ханна

3
яке значення введення шкарпетки між двома іншими шкарпетками забезпечує мету спарювання шкарпеток? немає кардинальності шкарпеток. : -x
JoeBrockhaus

60

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

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

Часто добре зробити крок назад і продумати проблему.

І є спосіб!

Знайдіть шкарпетку, яка вам подобається. Враховуйте всі відповідні функції: колір в різних умовах освітлення, загальну якість та довговічність, комфорт в різних кліматичних умовах та поглинання запаху. Також важливо те, що вони не повинні втрачати еластичність при зберіганні, тому натуральні тканини хороші, і вони повинні бути доступними в пластиковій упаковці.

Краще, якщо між шкарпетками лівої та правої стопи немає різниці, але це не критично. Якщо шкарпетки ліворуч праворуч симетричні, пошук пари - це операція O (1), а сортування шкарпеток - приблизна операція O (M), де M - кількість місць у вашому домі, які ви засмітили шкарпетками, в ідеалі деякі невелике постійне число.

Якщо ви вибрали вигадливу пару з різним лівим і правим шкарпетками, роблячи повне сортування відра для лівих і правих відро для ніг, візьміть O (N + M), де N - кількість шкарпеток, а M - те саме, що вище. Хтось ще може дати формулу для середніх ітерацій пошуку першої пари, але найгіршим випадком для пошуку пари при сліпому пошуку є N / 2 + 1, що стає астрономічно малоймовірним для розумного Н. Це можна прискорити, використовуючи розширене зображення алгоритми розпізнавання та евристики при скануванні купи несортованих шкарпеток за допомогою Mk1 Eyeball .

Отже, алгоритм досягнення ефективності спарювання шкарпеток O (1) (якщо вважати симетричний носок):

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

  2. Вам потрібно дізнатися, як ви можете замовити вибраний шкарпетку оптом і скільки це коштує, і чи доставляють вони.

  3. Замовляйте шкарпетки!

  4. Позбавтеся від своїх старих шкарпеток.

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

Проблема вирішена. Отож, просто дістаньте нові шкарпетки, киньте / пожертвуйте своїх старих і живіть щасливо, коли дізнаєтесь, що ви щодня економите гроші та час на все життя.


Постачання шкарпеток (якщо припустимо, що вичерпаєте 4 пари / місяць, що складає 3600 пар) протягом усього життя (за умови, що нова пара шкарпеток займає 20 кубічних дюймів) зайняла б усього 1 1/2 кубічних ярдів. Це величезна кількість місця. Якщо припустити, що вони доставлять вам його в коробці, яка приблизно є кубом, то ящик буде приблизно 3 фути 4 дюйми на стороні.
AJMansfield

2
@AJMansfield дійсне занепокоєння. Однак я не згоден з кількома вашими номерами. Я б зайняв проміжок часу всього 40 років (25 ... 65) (час між нежиттям у батьків / гуртожитку / тощо і виходом на пенсію, див. Вище). Крім того, я думаю, що одна пара займає більше, ніж 0,5х4х6 дюймів у оригінальній упаковці. Ці цифри дуже скорочують ваш космічний естем!
Гайд

Крок 4 зайво марнотратний, -1.
Ден Бешард

2
Посібник для інших, хто може бути збентежений вимірюваннями AJMansfield, переклад на метрику: »зайняв би (якщо нова пара шкарпеток займає 327 см³) загалом 1,14 м³. Це величезна кількість місця. Якщо припустити, що вони доставлять вам його в коробці, яка приблизно є кубом, то ящик буде приблизно 1,04 м на стороні. «
Джої

Як питання, яке базується на цікавості, може бути "неправильним питанням"? Класичний StackOverflow ...
Timmmm

52

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

Ви можете домогтися O (n) за допомогою радіокс . Вам просто потрібно вибрати кілька атрибутів для відра.

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

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


3
Шкарпетки часто бувають у 4-х пакетах і більші, оскільки це дешевше, але це також робить їх невідрізними. Щоб протистояти цьому, моя дружина пришиває крихітний знак до кожної нової пари шкарпеток, які я купую. Марка має різний колір для кожної пари або іншої форми, якщо у неї не вистачає кольорів. При такому підході вам навіть не потрібен обмежений набір атрибутів. Просто зшийте унікальну цифру на кожній парі. :) Для додаткових очок використовуйте двійкові.
Vilx-

29
@ Vilx- Чому?!? Чи не вся суть у тому, що вони не відрізняються?
флюп

2
@flup - Я думаю, вся справа в тому, щоб продавати в більшій кількості. :) Що стосується мене, це допомагає зносити їх попарно. Інакше я можу закінчитися трьома дуже зношеними шкарпетками та одним абсолютно новим. Якийсь дурний.
Vilx-

13
Я не згоден з обчисленням O (n). Що таке $ k $? $ k $ - кількість атрибутів. Я б стверджував, що $ k $ - це $ O (log n) $, оскільки його повинно вистачити для унікальної ідентифікації кожної пари. Якщо у вас є 2 пари (чорно-біла), то кольорів ($ k = 1, n = 2 $) достатньо. Якщо у вас є одна пара чорного кольору, коротка; одна пара чорного кольору, довга; одна пара білого кольору, коротка; і одна пара білого, довга - тоді $ k = 2, n = 4 $. Тоді якщо ми обмежуємо $ k $, ми одночасно обмежуємо $ n $. Якщо ми будемо обмежувати $ n $, то розрахунок замовлення вже не має сенсу.
emory

3
@emory, я думаю, що ти шукаєш backtick, а не $персонаж, щоб зробити свої речі кодовими.
Xymostech

33

Як практичне рішення:

  1. Швидко зробіть палі з шкарпеток, що легко помітні. (Скажіть за кольором)
  2. Кікшортуйте кожну купу і використовуйте довжину шкарпетки для порівняння. Як людина, ви можете прийняти досить швидке рішення, яке шкарпетку використовувати для перегородки, що дозволяє уникнути гіршого випадку. (Ви можете бачити кілька шкарпеток паралельно, використовуйте це на вашу користь!)
  3. Зупиніть сортування паль, коли вони досягли порогу, при якому вам зручно миттєво знаходити пари плям та непотрібні шкарпетки

Якщо у вас 1000 шкарпеток, з 8 кольорами і середнім розподілом, ви можете зробити 4 палі з кожних 125 шкарпеток за c * n час. З порогом 5 шкарпеток ви можете сортувати кожну купу за 6 пробіжок. (Якщо рахувати 2 секунди, щоб надіти шкарпетку на праву ворс, це знадобиться вам трохи менше 4 годин.)

Якщо у вас всього 60 шкарпеток, 3 кольори та 2 сорти шкарпеток (ваші / ваші дружини), ви можете сортувати кожну купу з 10 шкарпеток за 1 пробіг (Знову поріг = 5). (Підрахунок 2 секунди знадобиться вам 2 хв.)

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

Цей підхід буде сприятливим порівняно з будь-яким c*x*n + O(1)методом приблизно до тих пір, поки log(k) < x - 1.


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

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


3
Оптимізація людини: Я б заперечував, що, як людина, на етапі 2 вам слід розкладати шкарпетки приблизно в порядку зростання, а потім повторювати з більш тонкою і тонкою деталізацією до упорядкування, трохи схожий на тип оболонки. Це буде набагато швидше для людини (візуальна оцінка), ніж підхід на основі порівняння.
AndrewC

28

Ви намагаєтеся вирішити неправильну проблему.

Рішення 1: Кожен раз, коли ви кладете брудні шкарпетки в свою кошик для білизни, зав'яжіть їх по маленькому вузлу. Таким чином вам не доведеться робити сортування після прання. Подумайте про це як про реєстрацію індексу в базі даних Mongo. Трохи попереду на деяку економію процесора в майбутньому.

Рішення 2: Якщо зима, вам не доведеться носити відповідні шкарпетки. Ми програмісти. Ніхто не повинен знати, поки це працює.

Рішення 3: Розкладіть твір. Ви хочете виконувати такий складний процес процесора асинхронно, не блокуючи інтерфейс користувача. Візьміть ту купу шкарпеток і складіть їх у мішок. Шукайте пару лише тоді, коли вам це потрібно. Таким чином, кількість роботи, яку вона потребує, є значно менш помітною.

Сподіваюся, це допомагає!


5
Пов'язування шкарпеток (або будь-якого одягу) у вузол знижує здатність пральної машини мити білизну, а також ускладнює їх надягання носити набагато складніше. Рішення 2 ускладнює технічне обслуговування, чим довше прогресує стан справ; через 6 місяців, коли вам потрібні два чорних шкарпетки на щиколотці, щоб надіти пару шортів і кросівок, 6 місяців виконання будь-яких робіт буде робити знаходження цієї пари в такому ж стані (брудний / чистий, подібний знос) набагато рідше. Рішення 3 - менш "асинхронний" і більш прямолінійний "ледачий"; виконуйте мінімальну роботу, яка вам потрібна саме тоді, коли вам потрібно.
KeithS

Re: рішення 2: Люди будуть знати, що я не ношу відповідні шкарпетки, тому що вони побачать їх у моїх Бірках :)
Боб Пробст

@BobProbst Так, але ваші колеги-програмісти також будуть носити неперевершені шкарпетки з Birks, і тому будуть просто раді, помітивши, що вони не єдині.
Франческо Паса

27

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

Очевидним алгоритмом сортування шкарпеток є:

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 пар, що є оптимальним. Загальні теги замовлення дозволяють використовувати стандартне хешування для отримання однакового результату або з людським, або з апаратним комп'ютером.


Гаразд, це краще, хоча це все ще зовсім неправильно ... це питання не про це. Незалежно від того, чи є теза Церкви Тьюрінга чи ні, і люди, і наші комп’ютери можуть сортувати шкарпетки. (Реальність полягає в тому, що люди, будучи висококонечними сутностями, мають набагато меншу обчислювальну потужність, ніж машини Тюрінга ... і те ж саме стосується наших комп'ютерів, але обмеження різні.)
Джим Балтер,

Я не погоджуюсь. Звичайно, будь-який з наших сучасних комп'ютерів є по суті і величезним DFA (різниця між модулями вводу / виводу), а не TM. Однак будь-який аналоговий пристрій, як-от наше тіло, здатний наслідувати нескінченну стрічку. Ми ще не маємо корисної характеристики того, як обчислює наш розум.
Гена

Жодної нескінченної стрічки для людей чи інших фізичних пристроїв, тому що ніщо в людському мозку не має нескінченної роздільної здатності, і це не могло. Це також допомогло б вивчити деяку нейронауку. У будь-якому випадку тут не було глибокого філософського питання, незалежно від вашого бажання ввести його. Але повірте, що ви будете ... Це не місце для подібних дебатів, і я був у нього занадто багато разів раніше. Але мене завжди цікавить люди, які ледве вирішують найпростіші проблеми (це всі ми), уявляючи, що вони є еквівалентними ТМ.
Джим Балтер

22

Вартість: переміщення шкарпеток -> високо, пошук / пошук шкарпеток в черзі -> малий

Що ми хочемо зробити, це зменшити кількість рухів і компенсувати кількість пошукових запитів. Крім того, ми можемо використовувати багатопоточне середовище Homo Sapiens, щоб утримувати більше речей у кеш-пам'яті.

X = твої, Y = твої подружжя

З ворсу A всіх шкарпеток:

Візьміть два шкарпетки, помістіть відповідні носки X у рядок X та Y шкарпетку у рядок Y у наступному доступному положенні.

Робіть, поки A не буде порожнім.

Для кожного рядка X і Y

  1. Виберіть перший шкарпетку в рядку, шукайте по лінії, поки не знайде відповідний носок.

  2. Покладіть у відповідну готову лінію шкарпеток.

  3. Необов’язково. Коли ви шукаєте лінію і поточний шкарпетка, на який ви дивитесь, ідентичний попередньому, виконайте крок 2 для цих шкарпеток.

Необов'язково для першого кроку ви піднімаєте два шкарпетки з цього рядка замість двох, оскільки пам'ять кешування достатньо велика, ми можемо швидко визначити, чи відповідає один з носок поточному на лінії, яку ви спостерігаєте. Якщо вам пощастить мати три руки, ви, можливо, зможете одночасно проаналізувати три шкарпетки, враховуючи, що пам’ять предмета досить велика.

Робіть, поки і X, і Y не будуть порожніми.

Зроблено

Однак, оскільки це має подібну складність у ролі вибору, витрачений час значно менший за рахунок швидкості вводу / виводу (переміщення шкарпеток) та пошуку (пошук лінії для шкарпетки).


22

Ось нижня межа Omega (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}. Усвідомлення цього не може ускладнити проблему. Є n! можливі результати (відповідність між першою та другою половиною), що означає, що вам потрібно порівняння log (n!) = Omega (n log n). Це можна отримати шляхом сортування.

Оскільки ви зацікавлені у зв’язку з проблемою розрізнення елементів: довести Omega (n log n), пов'язаний для відмінності елементів, важче, тому що вихід є двійковим так / ні. Тут результат повинен бути відповідним, і кількість можливих результатів достатня для отримання гідної межі. Однак є варіант, пов'язаний з виразністю елементів. Припустимо, вам подарують 2н шкарпеток і поцікавтеся, чи можуть вони бути однозначно спареними. Можна зменшити від ED, відправивши (a 1 , 2 , ..., a n ) на (a 1 , a 1 , 2 , a 2 , ..., a n , a n ). (Патетично доказ твердості ЕД дуже цікавий за допомогою топології.)

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


19

Ось як я це роблю, для p пар шкарпеток ( n = 2p індивідуальних шкарпеток):

  • Візьміть носок навмання зі стопки.
  • Для першого шкарпетки, або якщо всі вибрані раніше шкарпетки були спарені, просто покладіть шкарпетку в перший "проріз" "масиву" непарних шкарпеток перед собою.
  • Якщо у вас є один або декілька вибраних непарних шкарпеток, перевірте свій поточний шкарпетку щодо всіх непарних шкарпеток у масиві.
    • При складанні масиву можна розділити шкарпетки на загальні класи або типи (білі / чорні, щиколотки / екіпажі, атлетичні / сукні) та "деталізовані", щоб порівняти лише подібні.
    • Якщо ви виявите прийнятну відповідність, складіть обидва шкарпетки разом і вийміть їх із масиву.
    • Якщо цього немає, покладіть поточний шкарпетку в перший відкритий слот масиву.
  • Повторіть з кожним носком.

Найгірший сценарій цієї схеми полягає в тому, що кожна пара шкарпеток досить різна, що вона повинна бути точно підібрана і що перші n / 2 шкарпетки, які ви вибираєте, всі різні. Це ваш сценарій O (n 2 ), і це вкрай малоймовірно. Якщо кількість унікальних типів шкарпетки t менша за кількість пар p = n / 2 , а шкарпетки у кожного типу достатньо однакові (як правило, з точки зору зносу), то будь-який шкарпетку такого типу можна з'єднати з будь-яким інше, то, як я зробив висновок вище, максимальна кількість шкарпеток, з якими вам коли-небудь доведеться порівнювати, - це t , після чого наступний, який ви будете тягнути, будевідповідати одному з парних шкарпеток. Цей сценарій набагато вірогідніший у середньому ящику шкарпетки, ніж у гіршому випадку, та зменшує складність у гіршому випадку до O (n * t), де зазвичай t << n .


1
Це, мабуть, досить близько до мого розумового процесу. У мене доданий шар оптимізації перед сортуванням. Мої спортивні шкарпетки миються білими, а мої шкарпетки одягаються кольорами. Це означає, що поки я не скидаю два вантажі білизни разом, мої шкарпетки вже згруповані за типом. Біле навантаження йде дуже швидко (багато однакових шкарпеток), але плаття носки займає більше часу. Інша ключова порада - створіть більше доступної пам’яті для сортування (спочатку складіть та видаліть усі не шкарпетки, а потім запустіть алгоритм сполучення)
ор

17

Реальний підхід:

Якнайшвидше зніміть шкарпетки з несортованої ворсинки по черзі і поставте в стопки перед собою. Палі повинні бути розташовані дещо просторо, причому всі шкарпетки мають вказівку в одному напрямку; кількість паль обмежена відстані, яку ви легко можете досягти. Вибір ворсу, на який надіти шкарпетку, повинен бути якнайшвидшим - надягаючи шкарпетку на купу, схоже на шкарпетки; епізодичний тип I (надягання шкарпетки на купу, до якої він не належить) або тип II (надягання шкарпетки у власну купу, коли є наявна купа подібних шкарпеток) може бути допущено помилку - найважливішим фактором є швидкість .

Як тільки всі шкарпетки знаходяться в палях, швидко пройдіться через пальчики, що створюють пари, створюючи пари і виймаючи їх (вони спрямовуються до шухляди). Якщо в купі є шкарпетки, що не співпадають, скомпонуйте їх якнайкраще (в межах якнайшвидшого обмеження). Коли всі мульти-шкарпетки були оброблені, підберіть відповідні залишкові шкарпетки, які не були парними через помилки типу II. Огонь, ти закінчиш - і у мене багато шкарпеток і не прати їх, поки велика частка не забрудниться. Ще одна практична примітка: я перевертаю верхню частину пари шкарпеток вниз поверх іншої, користуючись їх еластичними властивостями, тому вони залишаються разом під час транспортування до ящика і перебуваючи в ящику.


15

З вашого запитання зрозуміло, що ви не маєте багато фактичного досвіду з пранням :). Вам потрібен алгоритм, який добре працює з невеликою кількістю непарних шкарпеток.

На сьогодні відповіді не використовують наших можливостей розпізнавання образів людини. Гра Набір дає зрозуміти, як це зробити добре: покладіть всі шкарпетки в двовимірний простір, щоб ви могли добре розпізнати їх і легко дістатись до них руками. Це обмежує площу приблизно 120 * 80 см або близько того. Звідти виберіть пари, які ви розпізнаєте, та видаліть їх. Покладіть зайві шкарпетки у вільний простір і повторіть. Якщо ви стираєте людей з легко впізнаваними шкарпетками (маленькі діти приходять на думку), ви можете зробити сортування радіацією, вибравши спочатку ці шкарпетки. Цей алгоритм працює добре лише тоді, коли кількість одиничних шкарпеток невелика


Як правило, я це роблю. Працює набагато краще, ніж щоразу повторюючи всі шкарпетки, що залишилися.
yu_ominae

Хороший підхід, і я думаю, що він може бути застосований і до деяких реальних проблем з КС. Чи можете ви, будь ласка, додати приклад такого (проблема CS, де ми могли б використовувати подібний підхід для вирішення проблем)? Крім того, як це рішення масштабує мільйони шкарпеток?
Аміт

Я думаю, що це в основному те саме, що і інша відповідь тут, stackoverflow.com/a/14423956 , від 20 січня. Обидва +1. Система зору людини масово паралельна.
Чи буде Несс

15

Візьміть перший шкарпетку і поставте його на стіл. Тепер виберіть інший шкарпетку; якщо він відповідає першому вибраному, помістіть його поверх першого. Якщо ні, покладіть його на стіл невелику відстань від першого. Підберіть третій носок; якщо він відповідає будь-якому з попередніх двох, розмістіть його поверх них або ж поставте на невелику відстань від третьої. Повторюйте, поки не наберете всі шкарпетки.


1
Це єдина правильна відповідь. Всі інші нехтують тим фактом, що найбільше часу витрачається на розмежування подібних шкарпеток (так що згуртування їх усіх разом фізичним виглядом робить це ще гірше).
entonio

Для розваги я написав цей метод збивання шкарпеток в маленьку програму python gist.github.com/justinfay/53b574cf0a492f6795ef
Джастін Фей

12

Для того, щоб сказати, наскільки ефективно спарювати шкарпетки з палі, спочатку ми повинні визначити машину, тому що спарювання не проводиться ні тюрінгом, ні машиною з випадковим доступом, які зазвичай використовуються як основа для алгоритмічний аналіз.

Машина

Машина - це абстракція елемента реального світу, який називається людиною. Він здатний читати з оточення за допомогою пари очей. А наша модель машини здатна маніпулювати навколишнім середовищем, використовуючи 2 зброї. Логічні та арифметичні операції обчислюються за допомогою нашого мозку (сподіваємось ;-)).

Ми також повинні враховувати внутрішнє виконання атомних операцій, які можна здійснити за допомогою цих інструментів. Через фізичні обмеження операції, які виконуються рукою чи оком, мають непостійну часову складність. Це тому, що ми не можемо пересувати рукою нескінченно велику купу шкарпеток, а око не може бачити верхнього шкарпетки на нескінченно великій купі шкарпеток.

Однак механічна фізика також дає нам користь. Ми не обмежуємося рухати максимум одним носком з рукою. Ми можемо перемістити одразу цілу пару з них.

Отже, залежно від попереднього аналізу, наступні операції слід використовувати у порядку зменшення:

  • логічні та арифметичні операції
  • екологічні читання
  • екологічні модифікації

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

Алгоритм

Тому ось моя пропозиція:

  1. Розкладіть всі шкарпетки в ворсі по підлозі.
  2. Знайдіть пару, дивлячись на шкарпетки на підлозі.
  3. Повторюйте з 2 до тих пір, поки жодна пара не зможе зробити.
  4. Повторюйте з 1, поки на підлозі не з’явиться шкарпеток.

Операція 4 необхідна, тому що при розкладанні шкарпеток по підлозі одні шкарпетки можуть ховати інші. Ось аналіз алгоритму:

Аналіз

Алгоритм припиняється з високою ймовірністю. Це пов’язано з тим, що на кроці №2 неможливо знайти пари шкарпеток.

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

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

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


1
це те саме, що stackoverflow.com/a/14423956 і stackoverflow.com/a/14468913 Я думаю.
Буде Несс

@WillNess Так, ще трохи пояснень
SpaceTrucker

12
List<Sock> UnSearchedSocks = getAllSocks();
List<Sock> UnMatchedSocks = new list<Sock>();
List<PairOfSocks> PairedSocks = new list<PairOfSocks>();

foreach (Sock newSock in UnsearchedSocks)
{
  Sock MatchedSock = null;
  foreach(Sock UnmatchedSock in UnmatchedSocks)
  {
    if (UnmatchedSock.isPairOf(newSock))
    {
      MatchedSock = UnmatchedSock;
      break;
    }
  }
  if (MatchedSock != null)
  {
    UnmatchedSocks.remove(MatchedSock);
    PairedSocks.Add(new PairOfSocks(MatchedSock, NewSock));
  }
  else
  {
    UnmatchedSocks.Add(NewSock);
  }
}

12

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

Передумови: немає гарантії того, що є однакові шкарпетки. Якщо вони одного кольору, це не означає, що вони мають однаковий розмір або візерунок. Шкарпетки випадковим чином перетасовуються. Може бути непарна кількість шкарпеток (деякі відсутні, ми не знаємо, скільки). Підготуйтеся до запам'ятовування змінної "індекс" і встановіть її на 0.

Результат матиме одну або дві палі: 1. "зіставлені" та 2. "відсутні"

Евристичний:

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

Також може бути додана перевірка на наявність пошкоджених шкарпеток також, як якщо б їх зняли. Він може бути вставлений між 2 і 3 та між 13 і 14.

Я з нетерпінням чекаю чути про будь-які переживання чи виправлення.


Після того, як я написав це, я використовую його щоразу. Це допомогло мені стати трохи ефективнішим, і робота зараз менш нудна.
Саса

11

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

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

Я роблю це:

  1. Підбираючи виразний шкарпетку (все, що впадає мені в очі вперше).
  2. Початок сортування радикса з цього концептуального місця, витягнувши шкарпетки з ворсу на основі подібності з цим.
  3. Помістіть новий шкарпетку близько до поточної ворсу, відстань залежно від того, наскільки він різний. Якщо ви виявите, що носок ставите поверх іншого, тому що він однаковий, сформуйте там пару і вийміть їх. Це означає, що майбутні порівняння вимагають менше зусиль, щоб знайти правильне місце.

Це використовує здатність людини до нечіткого збігу за час O (1), що дещо еквівалентно встановленню хеш-карти на обчислювальному пристрої.

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

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

У якийсь момент різниці між шкарпетками досить малі, що інші люди не помітять різниці, і ніяких подальших зусиль для узгодження не потрібно.


10

Щоразу, коли ви підбираєте шкарпетку, кладіть її в одне місце. Тоді наступний носок, який ви взяли, якщо він не відповідає першому шкарпетку, встановіть його поруч із першим. Якщо це так, є пара. Таким чином, насправді не важливо, скільки комбінацій існує, і є лише дві можливості для кожного шкарпетки, який ви підберете - або він має відповідність, яка вже є у вашому масиві шкарпеток, або це не так, це означає, що ви додайте його до місця в масиві.

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


Це те, що я роблю ... О (п)
Pykler

2
@Pykler - це O (n) в кращому випадку і O (n * n) в гіршому.
Vilx-

2
Це припущення, що ви не можете створити повністю унікальний хеш у ваших думках усіх шкарпеток, які ви вже бачили, що для мене є O (1), щоб відповідати шкарпетку, який я бачив і раніше, і помістити в очікування відповідного хешу
Pykler

10

Розглянемо хеш-таблицю розміром 'N'.

Якщо припустити нормальний розподіл, то орієнтовна кількість "вставок", щоб мати принаймні один шкарпеток, відображений на одне відро, є NlogN (тобто всі відра заповнені)

Я зрозумів це як частину іншої головоломки, але буду радий, що я підтвердив себе неправильним. Ось моя стаття в блозі про те саме

Нехай 'N' відповідає приблизній верхній межі кількості унікальних кольорів / візерунку шкарпеток.

Як тільки у вас зіткнення (він же: сірник) просто зніміть цю пару шкарпеток. Повторіть той же експеримент із наступною партією шкарпеток NlogN. Краса полягає в тому, що ви могли проводити паралельні порівняння NlogN (вирішення колізій) через те, як працює людський розум. :-)


10

Шкарпетки, чи то справжні, чи якась аналогічна структура даних, поставлятимуться парами.

Найпростіша відповідь - перед тим, як дозволяти розділити пару, повинна бути ініціалізована єдина структура даних для пари, яка містила вказівник на лівий і правий носок, таким чином дозволяючи прямим або через їхню пару передавати шкарпетки. Шкарпетку можна також подовжити, щоб містити вказівник на свого партнера.

Це вирішує будь-яку задачу обчислювального сполучення, видаляючи її шаром абстракції.

Застосовуючи ту саму ідею до практичної проблеми спарювання шкарпеток, очевидною відповіддю є: не дозволяйте вашим шкарпеткам ніколи не бути парними. Шкарпетки надаються у вигляді пари, кладуть у шухляду як пару (можливо, розбиваючи їх між собою), носять як пару. Але пункт, коли можлива розпарювання, знаходиться в шайбі, тому все, що потрібно, - це фізичний механізм, який дозволяє шкарпеткам залишатися разом і ефективно прати.

Є дві фізичні можливості:

Для об'єкта "пари", який зберігає вказівник на кожен шкарпетку, у нас може бути тканинний мішок, який ми використовуємо, щоб тримати шкарпетки разом. Це здається масивним накладними.

Але для кожного шкарпетки, щоб зберегти посилання на інший, є акуратне рішення: поппер (або "кнопка", якщо ви американці), такі як:

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

Тоді все, що ви робите, - це зв'язати шкарпетки разом після того, як ви знімете їх і покладете в кошик для прання, і ви знову усунули проблему необхідності з’єднати шкарпетки з фізичною абстракцією концепції "пари".


Це не дає відповіді на запитання, оскільки обробляти з уже парними даними легко, питання полягає в тому, що робити, коли дані НЕПАРАТНІ, і ви хочете їх з’єднати.
Аміт

8

Якщо операція "переміщення" є досить дорогою, а операція "порівняння" - дешевою, і вам все одно потрібно перемістити весь набір, у буфер, де пошук набагато швидший, ніж у оригінальному сховищі ... просто інтегруйте сортування в обов'язкове рухатися.

Я виявив, що інтегрувати процес сортування в висяче для висихання робить вітер. Мені потрібно підібрати кожен шкарпетку і повісити його (перемістити), і це не коштує мені нічого, щоб повісити його в певному місці на струнах. Тепер тільки не змушувати шукати весь буфер (рядки), я вирішу розміщувати шкарпетки за кольором / відтінком. Темніше ліворуч, яскравіше праворуч, барвистіше спереду і т. Д. Тепер перед тим, як повісити кожен шкарпетку, я дивлюсь у його "праву околицю", якщо відповідна вже є - це обмежує "сканування" на 2-3 інших шкарпетки - і якщо це , Іншу підвішую прямо поруч. Потім розкачую їх на пари, знімаючи з струн, коли вони висохнуть.

Тепер це може здатися не таким, що відрізняється від "формування палі за кольором", запропонованого верхніми відповідями, але по-перше, не вибираючи дискретні палі, а діапазони, у мене немає проблем класифікувати, чи "фіолетовий" переходить до "червоного" або "синього" ворсу; це просто йде між. А потім, інтегруючи дві операції (повісити, щоб висушити і сортувати), накладні сортування під час підвішування - це приблизно 10% від того, що було б окреме сортування.


Цей підхід має дві інші переваги: ​​сушіння ліній втрачає набагато меншу кількість шкарпеток IME, ніж сушарка, і процес сортування може бути поширений на іншу білизну, тому (наприклад, всі рушники знаходяться поруч один з одним, щоб їх скласти рядок і порізаний і доставлений прямо на їх сховище. Це також працює за два пропуски з невеликими зусиллями, складаючи одяг і знову знімаючи їх.
cphlewis

8

Я закінчив спарювати шкарпетки прямо зараз, і я виявив, що найкращий спосіб зробити це наступним чином:

  • Виберіть один з шкарпеток і відкладіть його (створіть «відро» для цієї пари)
  • Якщо наступним є пара попереднього, то покладіть його на існуюче відро, інакше створіть нове.

У гіршому випадку це означає, що у вас буде n / 2 різних відра, і ви будете мати n-2 визначення щодо того, яке відро містить пару поточного носка. Очевидно, що цей алгоритм працює добре, якщо у вас всього кілька пар; Я зробив це з 12 пар.

Це не так науково, але добре працює :)


Це все ще алгоритм O (n ^ 2), оскільки вам потрібно повторювати кожне відро кожного разу, коли витягуєте новий шкарпетку. Але, враховуючи той факт, що навіть шкарпетки, придбані в одній партії, мають незначні відмінності, що робить їх ефективно унікальними для пари (або навіть єдиним унікальним), кращого способу все одно немає
Semisonic

Погодьтеся, але мій алгоритм припускає, що людина займається сполученням. Тому у вашій свідомості буде кеш своєрідного кешу, коли ви шукаєте відповідне відерце, тож вам дійсно не потрібно перебирати відра. Не впевнений, яка структура даних побудована для цього механізму кешування в моїй голові під час сполучення.
маестро

8

Моє рішення не відповідає точно вашим вимогам, оскільки формально вимагає O(n)«зайвого» місця. Однак, враховуючи мої умови, це дуже ефективно в моєму практичному застосуванні. Тому я думаю, що це має бути цікаво.

Поєднайте з іншими завданнями

Особлива умова в моєму випадку полягає в тому, що я не використовую сушильну машину, просто вішаю свої полотна на звичайну сушарку з тканини. Підвішування полотна вимагає O(n)операцій (до речі, я завжди вважаю проблемою упаковки у сміттєві контейнери ), а проблема за своєю природою вимагає лінійного "додаткового" простору. Коли я беру новий шкарпетку з відра, я намагаюся повісити його поруч зі своєю парою, якщо пара вже підвішена. Якщо це шкарпетка від нової пари, я залишаю трохи місця поруч.

Oracle Machine краще ;-)

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

Майте це майже O(n)!

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


8

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

Крім того, нам не потрібно вважати велику кількість шкарпеток, навіть для великих сімей. Шкарпетки виймають з шухляди і надягають, а потім їх кидають у місце (можливо, у відро), де вони залишаються, перш ніж відмити. Хоча я б не називав сказаний бін 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, обмежена нормальна пральна машина та обмежена нормальна лінія одягу - але це все ще працює з дуже великою кількістю шкарпеток.

Про паралелізм: Поки ви кидаєте обидва шкарпетки в один і той же смітник, ви можете легко паралелізувати всі ці кроки.


Шкарпетки - лише метафора для сполучення довільних об'єктів у деякій базі даних.
Аміт

1
Зрозумів, не бачив, що ти автор. Якби ви хотіли загального рішення, ви справді повинні так сказати. У будь-якому випадку, нічого поганого в тому, щоб взяти до уваги будь-яку інформацію, яку ви маєте, якщо тільки вам не доведеться приймати загальне рішення - відмова від повторного використання рішення може призвести до значно кращих показників. У цьому випадку, враховуючи випадок використання та наявну базу даних в цілому, вигідно. Однак ця особлива відповідь на ваше особливе запитання має проблеми з подібними на вигляд шкарпетками, наприклад, чорними шкарпетками різного розміру, тому в деяких випадках це не застосовується.
Філіп Фленкер

1
Крім того, ви не отримали оновлення> 2k, тому що ви задали питання про об'єднання довільних об'єктів у базі даних. Ви спеціально обмежили питання через саму природу шкарпеток (яку ви не можете дублювати, на відміну від даних), ви навіть рекомендували використовувати той факт, що ви можете легко відрізнити свої шкарпетки від шкарпеток вашого чоловіка. Якщо ви задаєте питання про шкарпетки, не чекайте, що відповіді стосуватимуться баз даних ;-)
Philipp Flenker

1
Є кілька припущень: нормальна машинка для прання, нормальна білизна, і той факт, що ви кидаєте обидва шкарпетки у відро одночасно, це означає, що в більшості випадків обидва шкарпетки знаходяться в одній машині, і кількість Тому залишки шкарпеток для сортування є невеликими. Але оскільки ви дуже хотіли відповіді про збереження довільних об'єктів у базі даних, чи справді корисно обговорювати моє рішення?
Філіп Фленкер

1
Як я вже говорив, я думаю, що я звернувся до всього, про що ви просили, крім проблеми розрізнення стихії, на яку відповіли інші люди. Я не намагаюся бути душем тут, але я доклав багато зусиль у цій відповіді на деякий час назад, і я дуже розчарований, що зараз ви переглянете деякі відповіді і стверджуєте, що вони не відповіли на початкове запитання . Чому ти просто не залишиш цілу нитку в спокої - це все ще цікаве прочитання через 2 роки після того, як ти це запитував?
Філіп Фленкер

8

Я вжив простих кроків, щоб зменшити свої зусилля на процес, який забирає час O (1).

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

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

Такі випереджаючі зусилля багато разів бачили у дуже популярному та ефективному коді. Приклади включають # DEFINE'ing pi до декількох десяткових знаків (існують інші приклади, але це той, що спадає на думку зараз).


7

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


Як це зробити не на місці, як конкретно зазначено у питанні?
Аміт

7

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

Тепер наступне питання - просто ти робиш свою пральню, і твоя дружина робить її. Це проблема, ймовірно, у зовсім іншій області проблем . :)


Це не дає відповіді на питання, де шкарпетки - лише метафора.
Аміт

Питання полягало в тому, як з’єднати шкарпетки з непарної ворсу, а не як уникнути необхідності спарювати.
Аміт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.