Шляхи визначення випадкової генерації в завданнях


16

Примітка : Відповідно до консенсусу щодо Meta , тут питання щодо .

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

Іноді трапляється, що я хочу опублікувати виклик з який передбачає випадкове генерування дурня, де

  1. дуже легко перевірити, чи дана річ є foo, і
  2. трохи складніше швидко створити "якісну" випадкову частину.

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

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

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

Чи може бути приємне загальне визначення для непередбачувано випадкового фоа?

TL; DR

Чи є хороший спосіб вказати "непередбачуваний" випадково генерований об'єкт, який не фіксує розподіл, але перешкоджає жорсткому кодуванню?


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

5
Чудове запитання. У минулому я виявив, що визначити випадковість важко . Спеціально для описаного сценарію є також проблема, що ви можете просто генерувати випадкових кандидатів і повторно повторювати, якщо вони недійсні. Це навіть дає рівномірний розподіл, але недетермінований час виконання. Вказуючи рівномірний розподіл, існує також питання про те, що реальні рішення ніколи не бувають абсолютно однаковими. Це дуже тонке питання. +1
Мартін Ендер

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

здається , що ви могли б вказати K3 / K4 CPRNG, більшість мов матиме бібліотеку en.wikipedia.org/wiki/Pseudorandom_number_generator
Ewan

1
@Zgarb Велика проблема із забороною "Створити та повторити" полягає в тому, що більшість мовних бібліотек RNG роблять саме це.
Натан Меррілл

Відповіді:


5

Поверніть тисячу різних футів

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

Пам’ятайте про парадокс дня народження , що ймовірність дублікатів може бути вищою, ніж ви думаєте. Якщо є лише мільйон можливих фосів, тисяча випадкових фосів матиме ймовірність приблизно 0,6, що там десь є дублікат, і це припускаючи, що покоління foo є повністю рівномірним. Якщо це може бути проблемою, вимагайте сказати 900 унікальних кадрування на кожні 1000 згенерованих, що набагато щедріше для справжнього генератора foo, але все ще недоцільно для жорсткого кодування.

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

Зробіть це швидко

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

Щоб врахувати різницю швидкостей між різними мовами, ви можете мати різні часові обмеження залежно від мови, як Hackerrank: https://www.hackerrank.com/environment . Однак якщо вказати достатньо великий фус, ймовірність того, що випадкові речі, подібні до дурників, можуть бути дуже низькими, тому правило "до теплової смерті Всесвіту" може бути достатнім.


Я думаю, ти тут щось на те. "Запуск програми N разів не дасть дублікатів щонайменше 90% часу", це конкретно і досить легко перевірити, і це може бути поєднано з обмеженим часом, щоб запобігти жорстокому змушенню та простому відбору відмов також.
Згарб

2

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

Не рішення: явно забороняйте жорстке кодування

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

Зробіть жорстке кодування нездійсненним

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

Параметризуйте вихід

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

Поставте деяке обмеження щодо розподілу ймовірностей

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

  • Найпростішим обмеженням, яке спадає на думку, є вимагати різниці між мінімальною та максимальною ймовірністю, щоб будь-який можливий вихід був нижче певного порогу. У жорстко кодованому підході, ймовірно, буде майже нульова ймовірність майже для всіх результатів і ймовірність, близька до 1 для значення за замовчуванням. Якщо вам потрібно, щоб максимальна різниця була нижче 0,1 скажіть, для визначення підходу можливим буде 10 (вибраних випадковим чином) значень за замовчуванням. Аналогічно, ви також можете вимагати мінімальної ймовірності для кожного можливого виходу, наприклад, 1 / (2 * N *), де N - кількість можливих виходів.
  • Крім того, ви можете вимагати, щоб у розподілі не було (ймовірних) прогалин, щоб не було інтервалу розміру δ (обраний вами) таким, щоб існували як більш високі, так і нижчі ймовірності. Це означає, що не може бути жодних переживаючих людей з точки зору ймовірності, які, ймовірно, породжуються підходом жорсткого кодування.

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

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

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