Supposons que vous ayez un sac avec tuiles, chacune avec une lettre dessus. Il y a tuiles avec la lettre 'A', avec 'B', et ainsi de suite, et 'wildcard' tuiles (nous avons ). Supposons que vous disposiez d'un dictionnaire avec un nombre fini de mots. Vous choisissez tuiles du sac sans remplacement. Comment calculeriez-vous (ou estimeriez-vous) la probabilité que vous puissiez former zéro mot à partir du dictionnaire étant donné les tuiles sélectionnées?
Pour ceux qui ne connaissent pas Scrabble (TM), le caractère générique peut être utilisé pour correspondre à n'importe quelle lettre. Ainsi, le mot [ BOOT ] pourrait être «orthographié» avec les tuiles «B», «*», «O», «T».
Pour donner une idée de l'ampleur du problème, est petit, comme 7, est d'environ 100, et le dictionnaire contient environ 100 000 mots de taille ou moins.
modifier: Par «former un mot», je veux dire un mot de longueur ne dépassant pas . Ainsi, si le mot [ A ] est dans le dictionnaire, alors en tirant même un seul «A» du sac, on a «formé un mot». Le problème des caractères génériques est radicalement simplifié si l'on peut supposer qu'il y a des mots de longueur 1 dans le dictionnaire. Car s'il y en a, tout tirage d'un caractère générique peut automatiquement correspondre à un mot de longueur 1, et donc on peut se concentrer sur le cas où il n'y a pas de caractères génériques. Ainsi, la forme la plus glissante du problème n'a pas de mots à 1 lettre dans le dictionnaire.
En outre, je dois déclarer explicitement que l'ordre dans lequel les lettres sont tirées du sac est sans importance. Il n'est pas nécessaire de dessiner les lettres dans l'ordre «correct» du mot.
la source
Réponses:
Ceci est un (long!) Commentaire sur le beau travail que @vqv a publié dans ce fil. Il vise à obtenir une réponse définitive. Il a fait le travail acharné de simplification du dictionnaire. Il ne reste plus qu'à l'exploiter au maximum. Ses résultats suggèrent qu'une solution de force brute est faisable . Après tout, y compris un caractère générique, il y a au plus mots que l'on peut faire avec 7 caractères, et il semble que moins de 1/10000 d'entre eux - disons, environ un million - ne pas inclure un mot valide.277= 10 , 460 , 353 , 203
La première étape consiste à augmenter le dictionnaire minimal avec un caractère générique, "?". 22 des lettres apparaissent en deux lettres (toutes sauf c, q, v, z). Joignez un caractère générique à ces 22 lettres et ajoutez-les au dictionnaire: {a ?, b ?, d ?, ..., y?} Sont maintenant entrés. De même, nous pouvons inspecter les mots minimaux à trois lettres, provoquant quelques mots supplémentaires à apparaître dans le dictionnaire. Enfin, nous ajoutons "??" au dictionnaire. Après avoir supprimé les répétitions qui en résultent, il contient 342 mots minimum.
Une manière élégante de procéder - qui utilise en effet une très petite quantité d'encodage - est de considérer ce problème comme un problème algébrique . Un mot, considéré comme un ensemble de lettres non ordonné, n'est qu'un monôme. Par exemple, "spats" est le monôme . Le dictionnaire est donc une collection de monômes. Ça ressemble àa p s2t
(où, pour éviter toute confusion, j'ai écrit pour le caractère générique).ψ
Un rack contient un mot valide si et seulement si ce mot divise le rack.
Une façon plus abstraite, mais extrêmement puissante, de dire ceci est que le dictionnaire génère un idéal dans l'anneau polynomial R = Z [ a , b , … , z , ψ ] et que les racks avec des mots valides deviennent nuls dans le quotient anneau R / I , tandis que les racks sans mots valides restent différents de zéro dans le quotient. Si nous formons la somme de tous les racks dans R et que nous la calculons dans cet anneau de quotient, alors le nombre de racks sans mots est égal au nombre de monômes distincts dans le quotient.je R = Z [ a , b , … , z, ψ ] R/I R
De plus, la somme de tous les racks en est simple à exprimer. Soit α = a + b + ⋯ + z + ψ la somme de toutes les lettres de l'alphabet. α 7 contient un monôme pour chaque rack. (En prime, ses coefficients comptent le nombre de façons dont chaque rack peut être formé, ce qui nous permet de calculer sa probabilité si nous le voulons.)R α=a+b+⋯+z+ψ α7
À titre d'exemple simple (pour voir comment cela fonctionne), supposons (a) que nous n'utilisons pas de caractères génériques et (b) toutes les lettres de "a" à "x" sont considérées comme des mots. Ensuite, les seuls racks possibles à partir desquels les mots ne peuvent pas être formés doivent être entièrement composés de y et de z. On calcule modulo l'idéal généré par { a , b , c , … , x } une étape à la fois, donc:α=(a+b+c+⋯+x+y+z)7 {a,b,c,…,x}
Nous pouvons lire la possibilité d'obtenir un rack non mot à partir de la réponse finale, : chaque coefficient compte les façons dont le rack correspondant peut être dessiné. Par exemple, il existe 21 façons (sur 26 ^ 7 possibles) de dessiner 2 y et 5 z car le coefficient de yy7+ 7 y6z+ De 21 ans5z2+ 35 y4z3+ 35 y3z4+ De 21 ans2z5+ 7 yz6+ z7 est égal à 21.y2z5
D'après les calculs élémentaires, il est évident que c'est la bonne réponse. Le fait est que cette procédure fonctionne quel que soit le contenu du dictionnaire.
Remarquez comment la réduction du module de puissance idéal à chaque étape réduit le calcul: c'est le raccourci révélé par cette approche. (Fin de l'exemple.)
Les systèmes d'algèbre polynomiale implémentent ces calculs . Par exemple, voici le code Mathematica :
(Le dictionnaire peut être construit de manière simple à partir du min.dict de @ vqv; je mets ici une ligne montrant qu'il est suffisamment court pour être spécifié directement si vous le souhaitez.)
La sortie - qui prend dix minutes de calcul - est 577958. ( NB Dans une version antérieure de ce message, j'avais fait une petite erreur dans la préparation du dictionnaire et obtenu 577940. J'ai édité le texte pour refléter ce que j'espère être maintenant les résultats corrects!) Un peu moins que le million environ que j'attendais, mais du même ordre de grandeur.
Pour calculer les chances d'obtenir un tel rack, nous devons tenir compte du nombre de façons dont le rack peut être dessiné. Comme nous l'avons vu dans l'exemple, cela équivaut à son coefficient en . La chance de dessiner un tel rack est la somme de tous ces coefficients, facilement trouvée en mettant toutes les lettres égales à 1:α7
La réponse est égale à 1066056120, ce qui donne une chance de 10,1914% de dessiner un rack à partir duquel aucun mot valide ne peut être formé (si toutes les lettres sont également probables).
Lorsque les probabilités des lettres varient, il suffit de remplacer chaque lettre par sa chance d'être tirée:
La sortie est 1,079877553303%, la réponse exacte (bien qu'en utilisant un modèle approximatif, dessin avec remplacement). Avec le recul, il a fallu quatre lignes pour saisir les données (alphabet, dictionnaire et fréquences de l'alphabet) et seulement trois lignes pour faire le travail: décrire comment prendre la prochaine puissance de modulo I , prendre la 7e puissance récursivement et remplacer la probabilités pour les lettres.α I
la source
Il est très difficile de dessiner un rack qui ne contient aucun mot valide dans Scrabble et ses variantes. Ci-dessous, un programme R que j'ai écrit pour estimer la probabilité que le rack initial de 7 cases ne contienne pas de mot valide. Il utilise une approche monte carlo et le lexique Words With Friends (je n'ai pas pu trouver le lexique officiel du Scrabble dans un format facile). Chaque essai consiste à dessiner un rack de 7 cases, puis à vérifier si le rack contient un mot valide.
Mots minimaux
Vous n'avez pas besoin de scanner l'intégralité du lexique pour vérifier si le rack contient un mot valide. Il vous suffit de scanner un lexique minimal composé de mots minimaux . Un mot est minimal s'il ne contient aucun autre mot comme sous-ensemble. Par exemple, «em» est un mot minimal; «vide» ne l'est pas. Le fait est que si un rack contient le mot x, il doit également contenir tout sous-ensemble de x . En d'autres termes: un rack ne contient aucun mot ssi il ne contient aucun mot minimal. Heureusement, la plupart des mots du lexique ne sont pas minimes, ils peuvent donc être éliminés. Vous pouvez également fusionner des mots équivalents à permutation. J'ai pu réduire le lexique Words With Friends de 172 820 à 201 mots minimum.
Les caractères génériques peuvent être facilement gérés en traitant les racks et les mots comme des distributions sur les lettres. Nous vérifions si un rack contient un mot en soustrayant une distribution de l'autre. Cela nous donne le nombre de chaque lettre manquante dans le rack. Si la somme de ces nombres est le nombre de caractères génériques, alors le mot est dans le rack.≤
Le seul problème avec l'approche de Monte Carlo est que l'événement qui nous intéresse est très rare. Il faut donc de nombreux essais pour obtenir une estimation avec une erreur standard suffisamment petite. J'ai couru mon programme (collé au fond) avec essais et a obtenu une probabilité estimée de 0,004 que le support ne contient pas un mot valide . L'erreur-type estimée de cette estimation est de 0,0002. Il n'a fallu que quelques minutes pour fonctionner sur mon Mac Pro, y compris le téléchargement du lexique.N= 100 , 000
Je serais intéressé de voir si quelqu'un peut trouver un algorithme exact efficace. Une approche naïve basée sur l'inclusion-exclusion semble impliquer une explosion combinatoire.
Inclusion-exclusion
Je pense que c'est une mauvaise solution, mais voici quand même un croquis incomplet. En principe, vous pouvez écrire un programme pour effectuer le calcul, mais la spécification serait tortueuse.
La probabilité que nous souhaitons calculer est L'événement à l'intérieur de la probabilité sur le côté droit est une union d'événements: P ( k -rack de tuiles contient un mot ) = P ( ∪ x ∈ M { k -rack de tuiles contient x } ) , où M
ensuite
Numérisation de tous les racks possibles
Je pense que c'est plus facile à calculer, car il y a moins de racks possibles que de sous-ensembles possibles de mots minimaux. On réduit successivement l'ensemble des possiblesk -tile racks jusqu'à ce que nous obtenions l'ensemble de racks qui ne contiennent aucun mot. Pour Scrabble (ou Words With Friends), le nombre de racks possibles à 7 cases est de l'ordre de dizaines de milliards. Compter le nombre de ceux qui ne contiennent pas de mot possible devrait être réalisable avec quelques dizaines de lignes de code R. Mais je pense que vous devriez pouvoir faire mieux que simplement énumérer tous les racks possibles. Par exemple, «aa» est un mot minimal. Cela élimine immédiatement tous les racks contenant plus d'un «a». Vous pouvez répéter avec d'autres mots. La mémoire ne devrait pas être un problème pour les ordinateurs modernes. Un rack Scrabble à 7 tuiles nécessite moins de 7 octets de stockage. Au pire, nous utiliserions quelques gigaoctets pour stocker tous les racks possibles, mais je ne pense pas que ce soit une bonne idée non plus. Quelqu'un voudra peut-être y réfléchir davantage.
Programme Monte Carlo R
la source
Srikant a raison: une étude de Monte Carlo est la voie à suivre. Il y a deux raisons. Premièrement, la réponse dépend fortement de la structure du dictionnaire. Deux extrêmes sont (1) le dictionnaire contient tous les mots possibles d'une seule lettre. Dans ce cas, la chance de ne pas faire un mot dans un tirage au sort de1 ou plusieurs lettres est zéro. (2) Le dictionnaire ne contient que des mots formés d'une seule lettre ( par exemple , "a", "aa", "aaa", etc. ). La chance de ne pas faire un mot dans un tirage au sortk les lettres sont facilement déterminées et sont évidemment non nulles. Toute réponse définitive sous forme fermée devrait incorporer toute la structure du dictionnaire et serait une formule vraiment horrible et longue.
La deuxième raison est que MC est en effet réalisable: il suffit de le faire correctement. Le paragraphe précédent fournit un indice: ne vous contentez pas de générer des mots au hasard et de les rechercher; au lieu de cela, analysez d'abord le dictionnaire et exploitez sa structure.
Une façon représente les mots du dictionnaire sous forme d'arbre. L'arbre est enraciné au symbole vide et se ramifie sur chaque lettre tout en bas; ses feuilles sont (bien sûr) les mots eux-mêmes. Cependant, nous pouvons également insérer toutes les permutations non triviales de chaque mot dans l'arbre (jusqu'àk ! - 1 d'entre eux pour chaque mot). Cela peut être fait efficacement car il n'est pas nécessaire de stocker toutes ces permutations; seuls les bords de l'arborescence doivent être ajoutés. Les feuilles restent les mêmes. En fait, cela peut être simplifié davantage en insistant pour que l'arbre soit suivi dans l'ordre alphabétique .
En d'autres termes, pour déterminer si un multiset dek caractères est dans le dictionnaire, organisez d'abord les éléments dans un ordre trié,puis recherchez ce «mot» trié dans un arbre construit à partir des représentants triés des mots dans le dictionnaire d'origine. Il sera en fait plus petit que l'arborescence d'origine car il fusionne tous les ensembles de mots qui sont équivalents au tri, tels que {stop, post, pots, opts, spot}. En fait, dans un dictionnaire anglais, cette classe de mots ne serait jamais atteinte de toute façon parce que "so" serait trouvé en premier. Voyons cela en action. Le multiset trié est "opst"; le "o" se ramifierait à tous les mots ne contenant que les lettres {o, p, ..., z}, le "p" se ramifierait à tous les mots ne contenant que {o, p, ..., z} et au plus un "o", et enfin le "s" se ramifierait à la feuille "so"! (J'ai supposé qu'aucun des candidats plausibles "o", "op", "
Une modification est nécessaire pour gérer les caractères génériques: je vais laisser les programmeurs parmi vous réfléchir à cela. Il n'augmentera pas la taille du dictionnaire (il devrait en fait le diminuer); il ralentira légèrement la traversée de l'arbre, mais sans le modifier de façon fondamentale. Dans tout dictionnaire qui contient un mot d'une seule lettre, comme l'anglais ("a", "i"), il n'y a pas de complication: la présence d'un caractère générique signifie que vous pouvez former un mot! (Cela laisse entendre que la question d'origine pourrait ne pas être aussi intéressante qu'elle y paraît.)
Le résultat est qu’une seule recherche dans un dictionnaire nécessite (a) de trierk -letter multiset et (b) traversant pas plus de k bords d'un arbre. Le temps de course estO ( k log( k ) ) . Si vous générez intelligemment des multisets aléatoires dans un ordre trié (je peux penser à plusieurs façons efficaces de le faire), le temps d'exécution se réduit àO ( k ) . Multipliez cela par le nombre d'itérations pour obtenir la durée totale d'exécution.
Je parie que vous pourriez mener cette étude avec un vrai set de Scrabble et un million d'itérations en quelques secondes.
la source
Approche de Monte Carlo
L'approche rapide et sale est de faire une étude à Monte Carlo. Dessinerk carrelage m fois et pour chaque tirage au sort k les tuiles voient si vous pouvez former un mot. Indiquez le nombre de fois que vous pourriez former un mot enmw . La probabilité souhaitée serait:
Approche directe
Soit le nombre de mots du dictionnaire donné parS . Laisserts être le nombre de façons dont nous pouvons former le se mot. Soit le nombre de lettres nécessaire ause mot soit désigné par mune, mb, . . . , mz (c.-à-d. se besoins de mots mune nombre de lettres «a», etc.). Indique le nombre de mots que nous pouvons former avec toutes les tuiles parN .
et
(Y compris l'impact des tuiles génériques est un peu plus délicat. Je vais reporter ce problème pour l'instant.)
Ainsi, la probabilité souhaitée est:
la source