Scrabble'da bir harf kutusundan bir kelime çizememe olasılığı


27

Her birinin üzerinde bir harf bulunan taşlı bir çantanız olduğunu varsayalım . Orada 'A' harfi ile fayans 'B' ile, vb, ve 'joker' karolar (Elimizdeki ). Sonlu sözcüklerden oluşan bir sözlüğünüz olduğunu varsayalım. Torbadan değiştirmeden karoları seçersiniz . Seçilen döşemeleri verilen sözlükten sıfır sözcük oluşturma olasılığını nasıl hesaplarsınız (veya tahmin edersiniz) ?n A n B n * n = n A + n B + ... + n Z + n * k knnbirnBn*n=nbir+nB+...+nZ+n*kk

Scrabble ™ ile aşina olmayanlar için, joker karakter herhangi bir harfle eşleştirmek için kullanılabilir. Böylece [ BOOT ] kelimesi 'B', '*', 'O', 'T' çinileri ile 'hecelenebilir'.

Sorunun ölçeği hakkında biraz fikir vermek için, 7 gibi küçük, 100 civarındadır ve sözlük veya daha küçük boyutlu 100,000 kelime içermektedir .n kknk

düzenleme: 'bir kelime' ile, daha büyük olmayan bir kelimeyi kastediyorum . Bu nedenle, [ A ] kelimesi sözlükte ise, o zaman torbadan tek bir 'A' bile çizildiğinde, biri 'bir kelime' oluşturmuştur. Joker karakter problemi, eğer sözlükte 1 uzunluğa sahip kelimeler varsayalımsa radikal bir şekilde basitleşir. Çünkü varsa, herhangi bir joker karakter otomatik olarak 1 kelimelik bir uzunluğa eşleşebilir ve böylece joker karakterlerin bulunmadığı duruma konsantre olabilir. Böylece problemin daha kaygan formu sözlükte 1 harfli kelimeler yoktur.k

Ayrıca, harflerin torbadan çıkarılma sırasının önemsiz olduğunu açıkça belirtmeliyim. Birinin harfleri kelimenin 'doğru' sırasına göre çizmek zorunda değilsiniz.


' Değişim olmadan k fayans seçmek' olmamalı mı ? Çok ilginç bir soru.

ayy. Gerçekten de olmalı.
shabbychef

Scrabble hatırladığım kadarıyla bir harfli kelimelere izin vermiyor, bu yüzden en azından sorunun bir kısmı çözüldü;)
nico

1
@ Nico iyi nokta, ama bunun sadece oyun ortasında olduğunu düşünüyorum. 1 harfli kelime ya birinin bir harf çalmasını gerektirmez, ya da açıkça kabul edilemez bir şekilde tahtada herhangi bir yere tek bir harf koymasına izin verir. Ancak açılış hareketini düşünüyordum. Aslında, Scrabble'a aşina olanlar için, “ilk oyuncunun geçme olasılığı ne olacak?” Sorusu sıkça belirtilebilir.
shabbychef

@ nico Bu açıklama için teşekkür ederim. Teorik olarak benzer bir konu, olası iki harfli kombinasyonların hepsini kelime olarak içeren sözlüklerle ilgilidir: bu durumda, 2 veya daha fazla harften herhangi bir el otomatik olarak bir kelime içerir. @ shabbychef'in oyunun ortası hakkındaki yorumu, orijinal sorunun Scrabble ile ne kadar alakasız olduğunu gösteriyor çünkü oyunun ortasında, 7 harfin yanı sıra, bir dizi kelime parçasını (önekler, sonekler ve hatta orta bölümler) kullanabiliyorsun. el. Bu, bir kelime yapmanın şansını büyük ölçüde artırır.
whuber

Yanıtlar:


14

Bu, @vqv'nin bu konuya gönderdiği güzel çalışma hakkında (uzun!) Bir yorum. Kesin bir cevap elde etmeyi amaçlar. Sözlüğü basitleştirmek için sıkı bir çalışma yaptı. Geriye kalan tek şey onu sonuna kadar kullanmak. Elde ettiği sonuçlar kaba kuvvetli bir çözümün mümkün olduğunu gösteriyor . Sonuçta, bir joker karakter dahil, en fazla kelimeden biri 7 karakterden oluşabiliyor ve bunların 1 / 10000'den daha azına benziyor - bir milyon civarında - olacak geçerli bir kelime içermemekte. 277=10,460,353,203

İlk adım, minimal sözlüğü "?" Joker karakteriyle genişletmektir. Harflerin 22'si iki harften oluşur (hepsi c, q, v, z hariç). Bu 22 harfe joker karakter ekleyin ve bunları şu sözlüğe ekleyin: {a ?, b ?, d ?, ..., y?} Şimdi içeride. Benzer şekilde, en az üç harften oluşan kelimeleri inceleyebiliriz, ek kelimelere neden olabiliriz. sözlükte görünmek için Sonunda "??" ekleriz. Sözlüğe Ortaya çıkan tekrarları sildikten sonra en az 342 kelime içerir.

Gerçekten de çok küçük bir kodlama kullanan, devam etmenin zarif bir yolu, bu sorunu cebirsel olarak görmektir . Sırasız bir harf kümesi olarak kabul edilen bir kelime, sadece bir monomialdir. Örneğin, "Spats" monomial olan . Bu nedenle sözlük, bir monom koleksiyonudur. Benziyorbirps2t

{bir2,birb,bird,...,Ozψ,wxψ,ψ2}

(karışıklıktan kaçınmak için, joker karakter için yazdım ).ψ

Bir raf, yalnızca bu kelime rafa bölündüğünde geçerli bir kelime içerir.

Daha soyut, ama son derece güçlü, bunu söylemenin bir yolu, sözlüğün R = Z [ a , b , , z , om ] polinomu halkasında ideal bir üretmesi ve geçerli kelimelere sahip rafların bölüm içinde sıfıra dönmesidir. halka R / I , oysa geçerli sözcük içermeyen raflar bölüm içinde sıfır kalmaz. Eğer R'deki tüm rafların toplamını oluşturur ve bu bölüm halkasında hesaplarsak, sözsüz raf sayısı, bölümdeki farklı monomiallerin sayısına eşittir.benR,=Z[bir,b,...,z,ψ]R,/benR,

Ayrıca, tüm rafların toplamının ifade edilmesi kolaydır. Let α = bir + b + + z + ψ alfabenin tüm harfleri toplamı olacaktır. α 7 her bir raf için, bir tek terimli içerir. (Ek bir avantaj olarak, katsayıları, her bir rafın oluşturulabileceği sayıları sayar ve eğer istersen olasılığını hesaplamamızı sağlar.)R,α=bir+b++z+ψα7

Basit bir örnek olarak (bunun nasıl çalıştığını görmek için), (a) joker karakter kullanmıyoruz ve (b) "a" dan "x" e kadar olan tüm harfleri kelimeler olarak kabul ediyoruz. Öyleyse, sözcüklerin oluşamayacağı olası raflar tamamen y ve z 'den oluşmalıdır. Bu işlem tarafından oluşturulan ideal bir modulo { a , b , c , ... , x } böylece her seferinde bir adım:α=(bir+b+c++x+y+z)7{bir,b,c,...,x}

α0=1α1=bir+b+c++x+y+zy+zşıkbenα2(y+z)(bir+b++y+z)(y+z)2şıkbenα7(y+z)6(bir+b++y+z)(y+z)7şıkben.

Son cevaptan kelime olmayan bir raf alma şansını okuyabiliriz, : her katsayı, ilgili rafın nasıl çekilebileceğini sayar. Örneğin, 2 (5 ve 26) mümkün) 2 y ve 5 z'yi çizmenin bir yolu vardır, çünkü y katsayısıy7+7y6z+21y5z2+35y4z3+35y3z4+21y2z5+7yz6+z7 21 eşittir.y2z5

Temel hesaplamalardan, bunun doğru cevap olduğu açıktır. Bütün mesele şu ki, bu prosedür sözlüğün içeriğinden bağımsız olarak çalışır.

Güç modülünün her aşamada ideal olarak azaltılmasının hesaplamayı nasıl azalttığına dikkat edin: bu, bu yaklaşımın ortaya çıkardığı kısayol. (Örneğin sonu.)

Polinom cebir sistemleri bu hesaplamaları uygular . Örneğin, işte Mathematica kodu:

alphabet =  a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + 
            p + q + r + s + t + u + v + w + x + y + z + \[Psi];
dictionary = {a^2, a b, a d, a e, ..., w z \[Psi], \[Psi]^2};
next[pp_] := PolynomialMod[pp alphabet, dictionary];
nonwords = Nest[next, 1, 7];
Length[nonwords]

(Sözlük @ vqv'nin min.dict'sinden basit bir şekilde oluşturulabilir; İsterseniz doğrudan belirtilmesinin yeterince kısa olduğunu gösteren bir çizgi koyuyorum.)

Hesaplama on dakika süren çıktı 577958 'dir. ( NB Bu mesajın önceki sürümlerinde sözlüğü hazırlarken ufak bir hata yaptım ve 577940' ı elde ettim. doğru sonuçlar!) Beklediğim milyondan biraz daha az, ama aynı büyüklükte.

Böyle bir raf alma şansını hesaplamak için , rafın nasıl çekilebileceğini hesaplamamız gerekir. Örnekte gördüğümüz gibi, bu katsayısına eşittir . Çizim şansı bazı tür raf 1'e eşit kolaylıkla tüm harfleri ayarlayarak bulunan tüm bu katsayılar, toplamıdır:α7

nonwords /. (# -> 1) & /@ (List @@ alphabet)

Cevap, 1066056120’ye eşittir,% 10.1914 oranında geçerli bir kelime oluşturulamayan bir raf çekme şansı verir (eğer tüm harfler eşit derecede muhtemel ise).

Harflerin olasılıkları değiştiğinde, sadece her bir harfi çizilme şansıyla değiştirin:

tiles = {9, 2, 2, 4, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1, 6, 4, 6, 
         4, 2, 2, 1, 2, 1, 2};
chances = tiles / (Plus @@ tiles);
nonwords /. (Transpose[{List @@ alphabet, chances}] /. {a_, b_} -> a -> b)

Çıktı % 1.079877553303'tür, kesin cevap (yaklaşık bir model kullanılsa da, değiştirilmesi ile çizim ). Geriye dönüp bakıldığında, verileri girmek için dört satır gerekiyordu (alfabe, sözlük ve alfabe frekansları) ve işi yapmak için sadece üç satır vardı: modulo I'in bir sonraki gücünün nasıl alınacağını, 7. gücün tekrarlı bir şekilde nasıl alınacağını ve ikame edicinin yerine geçeceğini tanımlayın . harfler için olasılıklar.αben


+1 Sözlüğe eklenmesi ve ardından tekrar küçültülmesi akıllıca bir fikirdir. Cebir benden öte, ama hipergeometreden ziyade multinom bir olasılık hesaplıyormuş gibi hissediyor. Bu nedenle olasılık değiştirme ile örnekleme içindir . Bunun% 1,08'lik cevabın neden% 0,4 tahminimden daha büyük olduğunu açıkladığını düşünüyorum. Değiştirmeden örnekleme işlemek için yaklaşımınızı değiştirmek için bir yolu var mı?
vqv

2
@vqv Evet. Şimdi, sözde yarı milyondan fazla rafın sözleri olmayan bir listeye sahip olduğumuza göre, her rafın (değiştirilmeden) şansını hesaplamak ve hipergeometrik sonucu elde etmek için (son iki kod satırını değiştirerek) basittir. Kesin cevap 349870667877/80678106432000 = % 0,43366'ya eşittir . N = 100K denemelerinde SE'niz% 0.021'dir, bu nedenle cevabınız% 0.38 ile% 0.49 (iki taraflı% 99 CI) arasında olmalıdır. Cevaplarımıza katıldığı için çok mutluyum!
whuber

@whuber Arkadaşlarla Kelimeleri (WWF) kiremit dağılımını kullanarak hesaplamayı yapabilir misiniz? Tahmini% 0,4, WWF sözlüğü ve WWF kiremit dağılımına dayanıyor. WWF sözlüğüyle birlikte Scrabble kiremit dağılımını kullandığınızı düşünüyorum.
vqv

Hata. Kesin cevap aslında 349870675899'dur (Sözlüğümdeki bir hata nedeniyle 8022 haklıydım.) Neyse ki pratik bir fark yaratmıyor.
whuber

@vqv Çeşitli fayans dağıtımlarına aşina değilim. Benimkini doğrudan kodundan kopyaladım (ve sözlüğünü kullandım) :-). Eğer osxreality.com/2010/01/01/… adresindeki dağılımı kastediyorsanız , o zaman % 1.15444 (değiştirme ile), % 0.43366 (değiştirme olmadan ) elde ederim . İkinci sayı aslında 8. önemli şekilde Scrabble frekanslarından farklı.
whuber

14

Scrabble ve değişkenlerinde geçerli bir kelime içermeyen bir raf çizmek çok zordur. Aşağıda, ilk 7 kiremit rafının geçerli bir kelime içermemesi ihtimalini tahmin etmek için yazdığım bir R programı verilmiştir. Monte bir carlo yaklaşımı ve Arkadaşlarla Sözler sözlüğünü kullanır (Resmi Scrabble sözlüğünü kolay bir biçimde bulamadım). Her deneme, 7 döşemeli bir raf çizmekten ve rafın geçerli bir kelime içerip içermediğini kontrol etmekten oluşur.

Minimal kelimeler

Rafın geçerli bir kelime içerip içermediğini kontrol etmek için sözlüğün tamamını taramanıza gerek yoktur. Sadece minimum kelimelerden oluşan minimal bir sözlüğü taramanız yeterli . Bir kelime, alt küme olarak başka bir kelime içermiyorsa, minimum düzeydedir. Örneğin 'em' asgari bir kelimedir; 'boş' değil. Bunun amacı, eğer bir raf x kelimesini içeriyorsa, o da herhangi bir x alt kümesini de içermesi gerektiğidir . Başka bir deyişle: Bir raf, hiç bir kelime içermiyorsa, minimum kelime içermiyorsa. Neyse ki, sözlükteki sözcüklerin çoğu minimal değil, bu yüzden yok edilebilirler. Permütasyon eşdeğeri kelimeleri de birleştirebilirsiniz. Arkadaşça Sözcükler sözlüğünü 172,820'den 201 en az kelimeye indirmeyi başardım.

Joker karakterler, raflara ve kelimelere harflerin üzerine dağıtılmış olarak bakılarak kolayca kullanılabilir. Bir rafın bir dağıtım diğerinden çıkarılarak bir kelime içerip içermediğini kontrol ederiz. Bu bize rafta eksik olan her bir mektubun numarasını verir. Bu sayının toplamı joker karakterlerin sayısı ise, kelime rafta demektir.

Monte edilmiş carlo yaklaşımındaki tek sorun, ilgilendiğimiz olayın çok nadir olması. Bu nedenle, yeterince küçük bir standart hatayla bir tahminde bulunmak için birçok denemenin yapılması gerekir. Programımı (altta yapıştırılmış) denemeyle çalıştırdım ve ilk rafın geçerli bir kelime içermemesi ihtimalinin 0.004 olabileceğini tahmin ettim . Bu tahminin tahmini standart hatası 0,0002'dir. Mac Pro'mda yayın yapmak sadece birkaç dakika sürdü, sözlüğü indirme de dahil.N-=100,000

Etkili bir algoritma ile birisinin ortaya çıkıp çıkamayacağını görmek isterim. Dahil etme-hariç tutma temelli naif bir yaklaşım, bir birleşimsel patlamayı içerebileceği görülüyor.

Dahil etme hariç tutma

Bunun kötü bir çözüm olduğunu düşünüyorum, ama yine de eksik bir taslak. Prensip olarak, hesaplama yapmak için bir program yazabilirsiniz, ancak şartname titiz olacaktır.

Hesaplamak istediğimiz olasılık Sağ taraftaki olasılık içindeki olay bir olaylar birliğidir: P ( k

P(kkiremit raf bir kelime içermiyor)=1-P(k-tile raf bir kelime içeriyor).
burada M
P(k-tile raf bir kelime içeriyor)=P(xM{k-tile rafı içerir x}),
Masgari bir sözlük. Dahil etme-hariç tutma formülünü kullanarak genişletebiliriz. Yukarıdaki olayların olası tüm kesişimlerini dikkate almayı içerir. Let güç kümesini göstermek M , olası tüm alt kümelerinin yani kümesi M . Sonra P(M)MM
P(k-tile rack contains a word)=P(xM{k-tile rack contains x})=j=1|M|(1)j1SP(M):|S|=jP(xS{k-tile rack contains x})

Belirlenecek son şey, yukarıdaki son satırdaki olasılığı nasıl hesaplayacağınızdır. Çok değişkenli bir hipergeometri içerir.
raf her kelimeyi içeren bir olaydır S . Bu, joker karakterler nedeniyle başa çıkmak için bir acıdır. Aşağıdaki durumların her birini koşullandırarak göz önünde bulundurmamız gerekir: raf joker karakter içermez, raf 1 joker karakter içerir, raf 2 joker karakter içerir ...

xS{k-tile rack contains x}
S

Sonra

P(xS{k-tile rafı içerir x})=Σw=0n*P(xS{k-tile rafı içerir x}|k-tile rafı içerir w joker)xP(k-tile rafı içerir w joker).

Burada duracağım, çünkü açılımlar tamamen aydınlanmaya değil, yazmaya zorlanıyor. Bunu yapmak için bir bilgisayar programı yazmak daha kolaydır. Ancak şimdiye kadar dahil etme-hariç tutma yaklaşımının anlaşılmaz olduğunu görmelisiniz. 2 içerir | M |2|M|Her biri de çok karmaşık olan terimler. Yukarıda düşündüğüm sözlüğü için .2|M|3.2x1060

Tüm olası rafları tarıyor

Bunun hesaplama açısından daha kolay olduğunu düşünüyorum çünkü minimal kelimelerin altkümelerinden daha az olası raf var. Biz gittikçe mümkün kümesi azaltmak k- Hiç kelime içermeyen raflar kümesini alana kadar rafları döşeyin. Scrabble için (veya Arkadaşlarla Kelimeler) olası 7 kiremitli rafların sayısı milyarlarca. Olası bir kelime içermeyenlerin sayısının sayılması, birkaç düzine R kodu ile yapılabilir. Ancak bence, tüm olası rafları numaralandırmaktan daha iyisini yapabilmelisiniz. Örneğin, 'aa' asgari bir kelimedir. Bu, birden fazla 'a' içeren tüm rafları derhal ortadan kaldırır. Diğer kelimelerle tekrarlayabilirsiniz. Bellek, modern bilgisayarlar için bir sorun olmamalıdır. 7 döşemeli bir Scrabble rafı, 7 bayttan daha az depolama alanı gerektirir. En kötüsü, tüm olası rafları saklamak için birkaç gigabayt kullanırdık, ama bunun da iyi bir fikir olduğunu sanmıyorum. Birileri bu konuda daha fazla düşünmek isteyebilir.

Monte Carlo R programı

# 
#  scrabble.R
#  
#  Created by Vincent Vu on 2011-01-07.
#  Copyright 2011 Vincent Vu. All rights reserved.
# 

# The Words With Friends lexicon
# http://code.google.com/p/dotnetperls-controls/downloads/detail?name=enable1.txt&can=2&q=
url <- 'http://dotnetperls-controls.googlecode.com/files/enable1.txt'
lexicon <- scan(url, what=character())

# Words With Friends
letters <- c(unlist(strsplit('abcdefghijklmnopqrstuvwxyz', NULL)), '?')
tiles <- c(9, 2, 2, 5, 13, 2, 3, 4, 8, 1, 1, 4, 2, 5, 8, 2, 1, 6, 5, 7, 4, 
           2, 2, 1, 2, 1, 2)
names(tiles) <- letters

# Scrabble
# tiles <- c(9, 2, 2, 4, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1, 6, 4, 6, 4, 
#            2, 2, 1, 2, 1, 2)


# Reduce to permutation equivalent words
sort.letters.in.words <- function(x) {
  sapply(lapply(strsplit(x, NULL), sort), paste, collapse='')
}

min.dict <- unique(sort.letters.in.words(lexicon))
min.dict.length <- nchar(min.dict)

# Find all minimal words of length k by elimination
# This is held constant across iterations:
#   All words in min.dict contain no other words of length k or smaller
k <- 1
while(k < max(min.dict.length))
{
  # List all k-letter words in min.dict
  k.letter.words <- min.dict[min.dict.length == k]

  # Find words in min.dict of length > k that contain a k-letter word
  for(w in k.letter.words)
  {
    # Create a regexp pattern
    makepattern <- function(x) {
      paste('.*', paste(unlist(strsplit(x, NULL)), '.*', sep='', collapse=''), 
            sep='')
    }
    p <- paste('.*', 
               paste(unlist(strsplit(w, NULL)), 
                     '.*', sep='', collapse=''), 
               sep='')

    # Eliminate words of length > k that are not minimal
    eliminate <- grepl(p, min.dict) & min.dict.length > k
    min.dict <- min.dict[!eliminate]
    min.dict.length <- min.dict.length[!eliminate]
  }
  k <- k + 1
}

# Converts a word into a letter distribution
letter.dist <- function(w, l=letters) {
  d <- lapply(strsplit(w, NULL), factor, levels=l)
  names(d) <- w
  d <- lapply(d, table)
  return(d)
}

# Sample N racks of k tiles
N <- 1e5
k <- 7
rack <- replicate(N,
                  paste(sample(names(tiles), size=k, prob=tiles), 
                        collapse=''))

contains.word <- function(rack.dist, lex.dist)
{
  # For each word in the lexicon, subtract the rack distribution from the 
  # letter distribution of the word.  Positive results correspond to the 
  # number of each letter that the rack is missing.
  y <- sweep(lex.dist, 1, rack.dist)

  # If the total number of missing letters is smaller than the number of 
  # wildcards in the rack, then the rack contains that word
  any(colSums(pmax(y,0)) <= rack.dist[names(rack.dist) == '?'])
}

# Convert rack and min.dict into letter distributions
min.dict.dist <- letter.dist(min.dict)
min.dict.dist <- do.call(cbind, min.dict.dist)
rack.dist <- letter.dist(rack, l=letters)

# Determine if each rack contains a valid word
x <- sapply(rack.dist, contains.word, lex.dist=min.dict.dist)

message("Estimate (and SE) of probability of no words based on ", 
        N, " trials:")
message(signif(1-mean(x)), " (", signif(sd(x) / sqrt(N)), ")")

Vay ... çok güzel takip.
Matt Parker

201 kelimeye düşürülmesine biraz şaşırdım. Her ne kadar ilk kelime çalınsa da, ev kurallarımız 'I' ve 'A' kelimelerini sözcük olarak kabul eder, ki bu muhtemelen en az kelime sayısını azaltacaktır. Birinin, oldukça kıllı olması gereken dahil etme-hariç tutma analizini
bozduğunu görmeyi umuyordum

@shabbychef Sözcük sözlüğünde 1 harfli kelimeler yoktur. En az sayıda kelime 2- ve 3 harfli sözcüklerdir. İşte minimum kelime uzunluklarının tam dağılımı: 2: 73, 3:86, 4:31, 5: 9, 6: 2. 6 harfli kelimeler: GLYCYL ve SYZYGY.
vqv

@ shabbychef Tam bir dahil etme-hariç tutma yaklaşımının bir taslağını içerecek şekilde cevabımı güncelledim. Kıllıdan daha kötü.
vqv

harika iş! Tek bir cümle olarak söylenebilecek bu sorunun (yeterli özgeçmişe sahip olanlar için), monte edilmiş carlo, içerme-dışlama, DAG'lar, ağaçları arama, polinom cebiri ve simülasyonlarının @ whuber. şerefe!
perişanlık

7

1k

İkinci sebep, MC'nin gerçekten uygulanabilir olduğudur: Sadece doğru şekilde yapmalısınız. Yukarıdaki paragraf bir ipucu sağlar: sadece rastgele kelimeler üretmek değil, onları aramak; bunun yerine, önce sözlüğü analiz et ve yapısından faydalan.

k!-1

Başka bir deyişle, bir multiset olup olmadığını belirlemek için kdaha sonra bu sıralanan "kelimeyi", orijinal sözlükteki kelimelerin sıralı temsilcilerinden oluşturulmuş bir ağaçta arayın. Bu aslında orijinal ağaçtan daha küçük olacaktır, çünkü {stop, post, tencere, opts, spot} gibi sıralama kelimesine eşdeğer tüm sözcük gruplarını birleştirir. Aslında, bir İngilizce sözlükte, bu kelimelere hiçbir zaman ulaşılmazdı, çünkü “so” ilk önce bulunacaktı. Bunu eylemde görelim. Sıralanan çoklu ayar "opst"; "o" sadece {o, p, ..., z} harflerini içeren tüm kelimelere dallanır, "p" sadece {o, p, ..., z} harflerini içeren en fazla kelimeye dallanır ve en fazla bir "o" ve nihayet "s" "so" yaprağına dallanacak! (Mantıklı adayların hiçbirinin "o", "op", "olmadığını varsaydım.

Joker karakterlerle başa çıkmak için bir değişiklik yapılması gerekiyor: Aralarındaki programcı türlerinin bunu düşünmesine izin vereceğim. Sözlük boyutunu artırmaz (gerçekte küçültmesi gerekir); ağaç geçişini hafifçe yavaşlatır, ancak herhangi bir temel şekilde değiştirmeden. İngilizce ("a", "i") gibi tek harfli bir kelime içeren herhangi bir sözlükte, hiçbir komplikasyon yoktur: bir joker karakterin varlığı, bir kelime oluşturabileceğiniz anlamına gelir! (Bu, orijinal sorunun göründüğü kadar ilginç olamayacağına işaret eder.)

kkO(kgünlük(k))O(k) . Toplam çalışma süresini elde etmek için bunu yineleme sayısı ile çarpın.

Bahse girerim bu çalışmayı gerçek bir Scrabble seti ve birkaç saniyede bir milyon yineleme ile yapabilirsin.


@whuber Ağaç temiz bir fikir (bu fikre yönelik oy) ama çok fazla hafıza gerektirmez mi? Sözlüğün ne kadar çeşitli olduğuna bağlı olduğunu sanıyorum ama makul bir şekilde farklı bir sözlüğün çok sayıda ağaç gerektireceğini tahmin ediyorum. Örneğin, 'b' ağacı, 'a' yerine 'a' harfi ile başlayacaktı. İçlerinde 'a' var. Benzer şekilde, 'c' ağacı, 'a' ve 'b' olmayan ama 'c' olan kelimeler için 'c' harfiyle başlar. Önerilen doğrudan yaklaşımım sözlükteki tüm kelimelerin bir defalık geçişini gerektirdiği için daha basit görünüyor, değil mi?

1
@Srikant: Ağaç, başlaması için tüm sözlüğü önbelleğe almaktan çok daha az RAM gerektirir. Zaten birkaç megabayt RAM konusunda endişeli misiniz? BTW, sadece bir ağaç var, çok değil: hepsi boş kelimeye dayanıyor. Anladığım kadarıyla yaklaşımınız, her yinelemede birden fazla sözlük (7'ye kadar!) Aranmasını gerektiriyor, bu da @shabbychef'in korktuğu gibi pratik olmamasını sağlıyor. Aklınızdaki “bir kelime oluşturabilecek misiniz bir bakın” yazdığın algoritmayı geliştirebilirseniz, bu bir çok önemli ayrıntıyı gizler!
whuber

@ whuber: Yorumumu yayınladıktan sonra sadece bir ağaç olduğunu gördüm. Benim yaklaşımımla - monte edilmiş carlo önerimin bulanık olduğu ve cevabınızın, bu ortamda monte edilmiş carlo'yu nasıl uygulayabileceği konusunda karar veriyorum. Aslında doğrudan yaklaşımın (cevabımı görün) aslında ağaç üzerinde binlerce yineleme gerektiren monte edilmiş bir carlodan farklı olarak sözlükte tek seferlik bir işlem gerektirdiğinden daha basit olabileceğini kastediyordum . Sadece yaklaşımların göreceli değerlerini merak ediyorum.

@Srikant Doğrudan yaklaşımınız hakkında yorum yapmaktan kaçındım çünkü yanlış cevaplar aldığından şüpheleniyorum. Sözlük yapısını açıklıyor gibi görünmüyor: yani kelimeler arasındaki alt küme ilişkileri. Örneğin, formülünüz tüm olası bir harfli kelimeleri içeren tüm sözlükler için sıfıra doğru cevap verir mi?
whuber

@whuber hmmm iyi bir nokta. Belki de yanlış soruya cevap veriyorum!

2

Monte Carlo Yaklaşımı

kmkmw

1-mwm

Doğrudan yaklaşım

Stssincisincimbir,mb,...,mzsincimbirN-

N-=(nk)

ve

ts=(nbirmbir)(nbmb)...(nzmz)

(Joker işaretlerin etkisinin dahil edilmesi biraz daha zor. Bu konuyu şimdilik erteleyeceğim.)

Böylece istenen olasılık:

1-ΣstsN-

Hızlı ve kirli yaklaşım bu kadar hızlı olmayabilir! Sözlük 100.000 kelime içerebilir ve verilen çinilerin bir eşleşmesinin aranması bir kodlama felaketi olabilir.
shabbychef

@ shabbychef Bu, yazım denetleyicileri için uygun bir işlemdir. Bkz. Örneğin n3labs.com/pdf/lexicon-squeeze.pdf

@ shabbychef Reg monte-carlo- Eğer sözlük sıralanırsa bir maç oldukça hızlı olmalı mı? Her durumda, daha önce ana hatlarıyla belirttiğim doğrudan yaklaşım hatalıydı. Düzelttim. Daha önceki çözümümdeki sorun, aynı kelimenin birçok yoldan oluşturulabilmesiydi (örneğin, 'yarasa', 'b * t' vb.).

1
@shabbychef Daha fazla yansıtma üzerine, monte carlo yaklaşımının işe yaramayacağına katılıyorum. Bir sorun, k karolarıyla gerçekte hangi kelimeleri oluşturabileceğinizi ve ikincisi k karolarla birden çok kelime oluşturabildiğinizi bulmanız gerektiğidir. Bu kombinasyonları k döşemelerden hesaplamak muhtemelen o kadar kolay değildir.

1
@Srikant Teşekkürler. Formülünüz, kelimeyi oluşturmak için tüm k harflerini kullanmanız gerektiğini varsayıyor gibi görünüyor, ancak OP'nin istediği şeyin bu olduğunu sanmıyorum. (Yine de Scrabble böyle oynanmaz.) Bu açık varsayımla, doğru yoldasın ama algoritmayı değiştirmelisin: sözlükte birbirlerinin izinleri olan kelimeler için hesaplamayı tekrarlamamalısın. Örneğin, formülünüzde hem t_ {stop} hem de t_ {post} çıkarmamalısınız. (Bu, uygulanması kolay bir değişikliktir.)
whuber
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.