Möglichkeiten zur Angabe der zufälligen Generierung in Herausforderungen

16

Hinweis : Gemäß Konsens über Meta , Fragen zum Thema finden Sie hier.

Angesichts dieser "Sache, die man beim Schreiben von Herausforderungen vermeiden sollte" , begann ich über Herausforderungen nachzudenken, bei denen bestimmte Arten von Objekten zufällig generiert wurden.

Es kommt manchmal vor, dass ich eine Herausforderung posten möchte , bei der zufällig ein Foo generiert wird

  1. Es ist sehr einfach zu überprüfen, ob eine bestimmte Sache ein Foo ist, und
  2. Es ist etwas schwieriger, schnell einen zufälligen Foo mit "guter Qualität" zu generieren.

Zum Beispiel könnte ein foo eine binäre Matrix sein, in der es in keiner Richtung Segmente mit 4 gleichen Bits gibt. Es ist leicht zu überprüfen, ob eine gegebene binäre Matrix ein Foo ist, aber das Erzeugen eines zufälligen Foo mit einer gut verteilten Verteilung scheint einen Backtracking-Algorithmus oder etwas Ähnliches zu erfordern.

Wie auch immer, jetzt muss ich objektiv angeben, was als zufälliges Foo zu bezeichnen ist, und ich möchte, dass es in dem intuitiven Sinne "unvorhersehbar" ist, dass die Ergebnisse immer unterschiedlich aussehen, wenn ich das Programm mehrmals ausführe. Der restriktivste Ansatz besteht darin, eine gleichmäßig zufällige Ausgabe zu verlangen: Alle gültigen Foos haben die gleiche Wahrscheinlichkeit, generiert zu werden. Dies ist in der Regel zu restriktiv, da ich keine Ahnung habe, wie es gemacht werden soll, um alle gültigen Foos zu generieren, Duplikate zu entfernen und eines auszuwählen, das langweilig und langsam ist.

Meine nächste Idee ist, vorauszusetzen, dass alle gültigen Foos eine positive Wahrscheinlichkeit haben, generiert zu werden. Dies bedeutet jedoch, dass der folgende Ansatz gültig ist: Erzeugen Sie ein zufälliges foo-ähnliches Objekt (in unserem Beispiel eine zufällige binäre Matrix). Wenn es ein foo ist, geben Sie es zurück, andernfalls geben Sie ein fest codiertes foo zurück (z. B. die Identitätsmatrix) ). Dies ist auch etwas langweilig, da es im Grunde nur ein Erkennungsmerkmal für Foos ist, die an einem Zufallsmatrixgenerator befestigt sind.

Könnte es eine schöne allgemeine Definition für ein unvorhersehbares zufälliges Foo geben?

TL; DR

Gibt es eine gute Möglichkeit, ein "unvorhersehbares" zufällig generiertes Objekt anzugeben, das die Verteilung nicht repariert, aber von der Hardcodierung abhält?

Zgarb
quelle
Wir haben eine Standarddefinition für zufällige Metas, die die Hartcodierung verbietet, aber nicht so weit einschränkt, dass sie vollkommen einheitlich ist.
Geobits
5
Gute Frage. Ich habe in der Vergangenheit festgestellt, dass die Angabe von Zufälligkeiten schwierig ist . Insbesondere für das von Ihnen beschriebene Szenario gibt es auch das Problem, dass Sie nur zufällige Kandidaten generieren und wiederholen können, wenn diese ungültig sind. Das gibt Ihnen sogar eine gleichmäßige Verteilung, aber nicht deterministische Laufzeit. Bei der Festlegung einer gleichmäßigen Verteilung gibt es auch das Problem, dass echte Lösungen niemals perfekt gleich sind . Dies ist ein sehr subtiles Problem. +1
Martin Ender
@MartinEnder Richtig, ich habe diesen Ansatz vergessen. Ich kann es und den anderen langsamen Algorithmus mit Zeitbeschränkungen verbieten, aber sie erlauben immer noch die "one hard-coded foo" -Lösung.
Zgarb
scheint , wie Sie die meisten Sprachen K3 / K4 CPRNG, wird eine Bibliothek geben könnte en.wikipedia.org/wiki/Pseudorandom_number_generator
Ewan
1
@Zgarb Ein großes Problem beim Nichtzulassen von "Generieren und Wiederherstellen" ist, dass die meisten RNG-Bibliotheken der Sprache genau das tun.
Nathan Merrill

Antworten:

5

Gib tausend verschiedene Foos zurück

Dies macht es unmöglich, fest codierte Werte zurückzugeben und ein halbwegs anständiges Golf zu haben. Ein legitimer Foo-Generator hat jedoch eine geringe Chance, doppelte Foos auszugeben, es sei denn, er überprüft sie tatsächlich. Um die Last der Überprüfung zu beseitigen, könnte eine empirisch getestete Fehlerrate von beispielsweise 10% als akzeptabel angegeben werden.

Beachten Sie das Geburtstagsparadoxon , dass die Wahrscheinlichkeit von Duplikaten höher sein kann, als Sie denken. Wenn es nur eine Million mögliche Foos gibt, haben tausend zufällige Foos eine Wahrscheinlichkeit von ungefähr 0,6, dass sich irgendwo ein Duplikat befindet, und das unter der Annahme, dass die FOO-Erzeugung völlig gleichmäßig ist. Wenn dies ein Problem sein könnte, benötigen Sie 900 eindeutige Foos pro 1000 generierte, was für einen echten Foo-Generator weitaus großzügiger ist, für die Hardcodierung jedoch immer noch unpraktisch.

Dies ermöglicht Ihnen auch, wiederholt foo-ähnliche Dinge zu generieren und Fooness zu überprüfen, bis Sie Foos bekommen. Ich denke, das ist eine gültige Lösung, aber wenn Sie es nicht mögen:

Mach es schnell

Die Wahrscheinlichkeit, dass eine völlig zufällige foo-artige Sache foo ist, ist wahrscheinlich sehr gering. Die Angabe eines Zeitlimits erzwingt also wahrscheinlich einen echten Versuch, foo zu generieren.

Um die Geschwindigkeitsunterschiede zwischen verschiedenen Sprachen auszugleichen, möchten Sie möglicherweise unterschiedliche Zeitlimits festlegen, abhängig von der Sprache wie Hackerrank: https://www.hackerrank.com/environment . Wenn Sie jedoch groß genug angeben, ist die Wahrscheinlichkeit, dass zufällige foo-ähnliche Dinge foo werden, sehr gering. Daher ist möglicherweise eine Regel "vor dem Tod des Universums" ausreichend.

James Hollis
quelle
Ich denke, Sie sind auf etwas hier. "N-maliges Ausführen des Programms erzeugt mindestens 90% der Zeit keine Duplikate" ist konkret und ziemlich einfach zu testen und kann mit einer zeitlichen Beschränkung kombiniert werden, um brachiales Erzwingen und einfaches Ablehnungs-Sampling zu verhindern.
Zgarb
2

Ich behaupte nicht, die ultimative Lösung für das Problem zu haben (oder dass diese Liste vollständig ist), aber ich möchte einige mögliche Ansätze skizzieren, die mir in den Sinn kommen und warum sie funktionieren würden oder nicht. Ich werde auch nicht auf tangentiale Probleme eingehen, wie die Frage, ob die Verwendung des aktuellen Zeitstempels als Zufallsquelle ausreichend "unvorhersehbar" ist und wie bestimmte Eigenschaften der Wahrscheinlichkeitsverteilung erzwungen werden können. Ich werde mich nur darauf konzentrieren, Lösungen zu vermeiden, die Hardcoding verwenden.

Keine Lösung: Festcodierung explizit nicht zulassen

Das ist eine schlechte Idee. Es ist eine nicht beobachtbare Anforderung (was bedeutet, dass Sie nicht feststellen können, ob sie nur durch Ausführen des Programms erfüllt ist), von der in PPCG dringend abgeraten wird und die möglicherweise völlig unmöglich ist, wenn das Programm auf einer anderen Plattform ausgeführt wird, auf der die Einreichungen in einem verifiziert werden automatisierte Weise. Das Problem bei einer solchen Anforderung ist, dass Sie zunächst eine objektive Definition für "Hardcodierung" finden müssen. Wenn Sie dies versuchen, werden Sie die Dinge im Allgemeinen nur noch schlimmer machen.

Mach Hard-Coding unmöglich

Wenn Sie es nicht vollständig verbieten können, aber nicht möchten, dass Benutzer es verwenden, können Sie versuchen, die Herausforderung so zu gestalten, dass Hardcodierung einfach kein wettbewerbsorientierter Ansatz ist. Dies ist möglich, wenn die Objekte, die generiert werden sollen, ausreichend groß und inkomprimierbar sind, sodass das Einfügen eines Beispiels in den Code viel mehr Bytes erfordert als das Schreiben eines Algorithmus, der zufällig gültige Lösungen generiert. In Ihrem speziellen Beispiel ist dies natürlich nicht der Fall, da Identitätsmatrizen gültig und im Allgemeinen leicht zu generieren sind. Bei anderen Problemen ist dies möglicherweise nicht der Fall. Wenn die Zielobjekte ausreichend unregelmäßig sind, müssen sie nur eine große Größe haben, was wahrscheinlich die Byteanzahl eines tatsächlichen Algorithmus nicht beeinflusst, aber den hartcodierten Teil in die Luft sprengt.

Ausgang parametrieren

Häufig hängen diese Probleme mit einem oder mehreren natürlichen Parametern zusammen, z. B. der Größe der Matrix in Ihrem Beispiel. In diesem Fall kann die Eingabe dieses Parameters ausreichen, um eine harte Codierung unmöglich oder zumindest unpraktisch zu machen. In einigen Fällen ist es möglicherweise einfach, eine bestimmte Lösung für einen bestimmten Parameterwert, der manuell oder über eine umfangreiche Suche gefunden wurde, fest zu codieren. Es gibt jedoch möglicherweise keine einfache geschlossene Form für eine Instanz dieser Lösung im Allgemeinen, sodass dies nicht der Fall ist leicht einen Standardwert für beliebige Eingaben zu generieren. Auch dies ist für das von Ihnen erwähnte Beispiel nicht der Fall, da die Identitätsmatrix in jeder Größe funktioniert, sondern eine optimale Lösung für dieses verwandte Problemist normalerweise sehr unregelmäßig, daher ist es nicht möglich, einen Standardwert zu haben, ohne aktiv nach gültigen Werten zu suchen. Sie können dies mit einem Zeitlimit kombinieren, um eine Brute-Force-Suche nach einem Standardwert zu vermeiden.

Legen Sie eine Beschränkung für die Wahrscheinlichkeitsverteilung

Wenn Sie bereit sind, auf eine völlig uneingeschränkte Wahrscheinlichkeitsverteilung zu verzichten, können Sie einige Einschränkungen festlegen, die den Antwortenden noch viel Freiheit bei der Auswahl ihrer Verteilung einräumen, die das Hardcodieren jedoch erschweren oder unmöglich machen:

  • Die einfachste denkbare Einschränkung besteht darin, die Differenz zwischen minimaler und maximaler Wahrscheinlichkeit zu fordern, damit eine mögliche Ausgabe unter einem bestimmten Schwellenwert liegt. Ein hartcodierter Ansatz wird wahrscheinlich für fast alle Ausgaben Wahrscheinlichkeiten nahe Null und für den Standardwert eine Wahrscheinlichkeit nahe 1 haben. Wenn Sie eine maximale Differenz von weniger als 0,1 benötigen, müssten 10 (zufällig ausgewählte) Standardwerte verwendet werden, um die Annäherung zu einer Option zu machen. In ähnlicher Weise könnten Sie auch nur eine minimale Wahrscheinlichkeit für jede mögliche Ausgabe verlangen, z. B. 1 / (2 * N *), wobei N die Anzahl der möglichen Ausgaben ist.
  • Alternativ können Sie verlangen, dass es keine (Wahrscheinlichkeits-) Lücken in der Verteilung gibt, so dass es kein (von Ihnen gewähltes) Intervall der Größe δ gibt, so dass sowohl höhere als auch niedrigere Wahrscheinlichkeiten existieren. Das bedeutet, dass es hinsichtlich der Wahrscheinlichkeit keine Ausreißer geben kann, die wahrscheinlich durch einen Hard-Coding-Ansatz erzeugt werden.

Das Hauptproblem bei diesen Ansätzen ist, dass es viel schwieriger ist, darüber nachzudenken, dass es schwierig ist, die Richtigkeit der Antworten zu beweisen, und das experimentelle Überprüfen der Richtigkeit kann für große Ausgaberäume unmöglich sein. Dennoch stellen sie eine grundsätzlich beobachtbare Anforderung an das Programm dar, die eine Hardcodierung unmöglich machen kann.

Diese Ansätze können auch eine zeitliche Begrenzung erfordern, da eine Möglichkeit zur Erhöhung der Wahrscheinlichkeit der Nicht-Standardwerte darin besteht, zu versuchen, ein zufälliges foo mehrmals zu finden, bevor auf den Standardwert zurückgegriffen wird.

Martin Ender
quelle