Kemungkinan tidak menggambar sepatah kata pun dari kantong surat di Scrabble

27

Misalkan Anda memiliki tas dengan ubin, masing-masing dengan huruf di atasnya. Ada ubin dengan huruf 'A', dengan 'B', dan seterusnya, dan 'wildcard' (kami memiliki ). Misalkan Anda memiliki kamus dengan jumlah kata yang terbatas. Anda memilih ubin dari kantong tanpa pengganti. Bagaimana Anda menghitung (atau memperkirakan) probabilitas bahwa Anda dapat membentuk nol kata dari kamus mengingat ubin dipilih?n A n B n n = n A + n B + + n Z + n k knnAnBnn=nA+nB++nZ+nkk

Bagi mereka yang tidak terbiasa dengan Scrabble (TM), karakter wildcard dapat digunakan untuk mencocokkan huruf apa pun. Dengan demikian kata [ BOOT ] dapat 'dieja' dengan ubin 'B', '*', 'O', 'T'.

Untuk memberikan gambaran tentang skala masalah, bertubuh kecil, seperti 7, sekitar 100, dan kamus berisi sekitar 100.000 kata ukuran atau lebih kecil.n kknk

sunting: Dengan 'membentuk kata', maksud saya kata dengan panjang tidak lebih dari . Jadi, jika kata [ A ] ada di kamus, maka dengan menggambar bahkan satu 'A' dari tas, seseorang telah 'membentuk kata'. Masalah wildcard secara radikal disederhanakan jika seseorang dapat berasumsi ada kata-kata dengan panjang 1 dalam kamus. Karena jika ada, setiap undian wildcard secara otomatis dapat mencocokkan panjang 1 kata, dan dengan demikian seseorang dapat berkonsentrasi pada kasus di mana tidak ada wildcard. Jadi, bentuk masalah yang lebih licin tidak memiliki kata 1 huruf dalam kamus.k

Juga, saya harus secara eksplisit menyatakan bahwa urutan surat-surat yang diambil dari tas tidak material. Orang tidak harus menggambar huruf dalam urutan kata yang 'benar'.

shabbychef
sumber
Bukankah seharusnya 'memilih ubin tanpa penggantian'? Pertanyaan yang sangat menarik.
oops. memang seharusnya begitu.
shabbychef
Sejauh yang saya ingat Scrabble tidak mengizinkan satu kata kata, jadi setidaknya bagian dari masalah itu diselesaikan;)
nico
1
@nico poin bagus, tapi saya pikir ini hanya untuk pertengahan pertandingan. Kata 1 huruf tidak memerlukan satu untuk memainkan huruf, atau akan memungkinkan seseorang untuk menempatkan satu huruf di mana saja di papan tulis, keduanya jelas tidak dapat diterima. Namun, saya memikirkan langkah pembukaan. Bahkan, pertanyaannya dapat dinyatakan secara ringkas, bagi mereka yang akrab dengan Scrabble, sebagai "berapa probabilitas yang harus dilewati pemain pertama?"
shabbychef
@nico Terima kasih atas klarifikasi itu. Secara teoritis, masalah yang sama berkaitan dengan kamus yang berisi semua kombinasi dua huruf yang mungkin sebagai kata-kata: ketika itu masalahnya, setiap tangan dari 2 huruf atau lebih secara otomatis berisi kata. Komentar @ shabbychef tentang mid-game menunjukkan betapa tidak relevannya pertanyaan asli bagi sebagian besar Scrabble, karena pada mid-game Anda telah menyediakan array bagian kata (awalan, sufiks, dan bahkan bagian tengah) di samping 7 huruf di Anda tangan. Ini sangat meningkatkan peluang untuk dapat membuat kata.
whuber

Jawaban:

14

Ini adalah komentar (panjang!) Pada karya bagus yang telah diposting @vqv di utas ini. Ini bertujuan untuk mendapatkan jawaban yang pasti. Dia telah melakukan kerja keras menyederhanakan kamus. Yang tersisa hanyalah mengeksploitasinya secara maksimal. Hasilnya menunjukkan bahwa solusi brute-force layak dilakukan . Lagipula, termasuk wildcard, paling banyak ada kata yang dapat dibuat dengan 7 karakter, dan sepertinya kurang dari 1/10000 di antaranya - katakanlah, sekitar satu juta - akan gagal memasukkan beberapa kata yang valid. 277=10,460,353,203

Langkah pertama adalah menambah kamus minimal dengan karakter wildcard, "?". 22 huruf muncul dalam kata-kata dua huruf (semua kecuali c, q, v, z). Sesuaikan wildcard ke 22 huruf tersebut dan tambahkan ke kamus: {a ?, b?, D ?, ..., y?} Sekarang sudah masuk. Demikian pula kita dapat memeriksa kata-kata tiga huruf minimal, menyebabkan beberapa kata tambahan muncul di kamus. Akhirnya, kami menambahkan "??" ke kamus. Setelah menghapus pengulangan yang menghasilkan, itu berisi 342 kata-kata minimal.

Cara yang elegan untuk melanjutkan - yang menggunakan jumlah pengkodean yang sangat kecil - adalah untuk melihat masalah ini sebagai aljabar . Sebuah kata, yang dianggap sebagai seperangkat huruf yang tidak teratur, hanyalah sebuah monomial. Misalnya, "pertengkaran" adalah monomial . Kamus karena itu adalah kumpulan monomial. Sepertinyaaps2t

{a2,ab,ad,...,ozψ,wxψ,ψ2}

(di mana, untuk menghindari kebingungan, saya telah menulis untuk karakter wildcard).ψ

Rak berisi kata yang valid jika dan hanya jika kata itu membagi rak.

Cara yang lebih abstrak, tetapi sangat kuat, untuk mengatakan ini adalah bahwa kamus menghasilkan ideal dalam cincin polinomial R = Z [ a , b , , z , ψ ] dan bahwa rak dengan kata-kata yang valid menjadi nol dalam hasil bagi dering R / I , sedangkan rak tanpa kata-kata yang valid tetap tidak nol dalam hasil bagi. Jika kita membentuk jumlah semua rak dalam R dan menghitungnya dalam cincin hasil bagi ini, maka jumlah rak tanpa kata sama dengan jumlah monomial yang berbeda dalam hasil bagi.IR=Z[a,b,,z,ψ]R/IR

Selain itu, jumlah semua rak di mudah untuk diekspresikan. Biarkan α = a + b + + z + ψ menjadi jumlah dari semua huruf dalam alfabet. α 7 berisi satu monomial untuk setiap rak. (Sebagai bonus tambahan, koefisiennya menghitung jumlah cara setiap rak dapat dibentuk, memungkinkan kita menghitung probabilitasnya jika kita mau.)Rα=a+b++z+ψα7

Sebagai contoh sederhana (untuk melihat bagaimana ini bekerja), misalkan (a) kita tidak menggunakan wildcard dan (b) semua huruf dari "a" hingga "x" dianggap sebagai kata. Maka satu-satunya rak yang memungkinkan dari mana kata-kata tidak dapat dibentuk harus seluruhnya terdiri dari y dan z. Kami menghitung modulo yang ideal dihasilkan oleh { a , b , c , , x } satu langkah pada satu waktu, dengan demikian:α=(a+b+c++x+y+z)7{a,b,c,,x}

α0=1α1=a+b+c++x+y+zy+zmodIα2(y+z)(a+b++y+z)(y+z)2modIα7(y+z)6(a+b++y+z)(y+z)7modI.

Kita dapat membaca peluang mendapatkan rak non-kata dari jawaban akhir, : masing-masing koefisien menghitung cara rak yang sesuai dapat ditarik. Misalnya, ada 21 (dari 26 ^ 7 kemungkinan) cara untuk menggambar 2 y dan 5 z karena koefisien yy7+7y6z+21y5z2+35y4z3+35y3z4+21y2z5+7yz6+z7 sama dengan 21.y2z5

Dari perhitungan dasar, jelas ini adalah jawaban yang benar. Intinya adalah bahwa prosedur ini berfungsi terlepas dari isi kamus.

Perhatikan bagaimana mengurangi daya modulo ideal pada setiap tahap mengurangi perhitungan: itulah cara pintas yang diungkapkan oleh pendekatan ini. (Akhir contoh.)

Sistem aljabar polinomial menerapkan perhitungan ini . Misalnya, ini adalah kode Mathematica :

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]

(Kamus dapat dibangun secara langsung dari min.dict @ vqv; Saya meletakkan garis di sini yang menunjukkan bahwa itu cukup pendek untuk ditentukan secara langsung jika Anda suka.)

Output - yang memerlukan sepuluh menit perhitungan - adalah 577958. ( NB Dalam versi sebelumnya dari pesan ini saya telah membuat kesalahan kecil dalam mempersiapkan kamus dan memperoleh 577940. Saya telah mengedit teks untuk mencerminkan apa yang saya harap sekarang adalah hasil yang benar!) Sedikit kurang dari satu juta atau lebih yang saya harapkan, tetapi dengan urutan yang sama besarnya.

Untuk menghitung kemungkinan mendapatkan rak seperti itu, kita perlu memperhitungkan sejumlah cara di mana rak dapat ditarik. Seperti yang kita lihat dalam contoh, ini sama dengan koefisiennya di . Peluang menggambar beberapa rak tersebut adalah jumlah dari semua koefisien ini, mudah ditemukan dengan menyetel semua huruf sama dengan 1:α7

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

Jawabannya sama dengan 1066056120, memberikan peluang 10,1914% menggambar rak dari mana tidak ada kata yang valid dapat dibentuk (jika semua huruf sama-sama kemungkinan).

Ketika probabilitas surat berbeda-beda, ganti saja setiap huruf dengan kemungkinan ditarik:

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)

Outputnya adalah 1,079877553303%, jawaban yang tepat (meskipun menggunakan model perkiraan, menggambar dengan penggantian). Melihat kembali, butuh empat baris untuk memasukkan data (alfabet, kamus, dan alfabet frekuensi) dan hanya tiga baris untuk melakukan pekerjaan: menjelaskan bagaimana untuk mengambil kekuatan berikutnya modulo saya , mengambil kekuasaan 7 rekursif, dan mengganti probabilitas untuk surat-surat itu.αI

whuber
sumber
+1 Menyatukan leksikon dan meminimalkannya kembali adalah ide yang cerdas. Aljabar di luar saya, tetapi rasanya seperti Anda menghitung probabilitas multinomial, bukan hipergeometrik. Jadi kemungkinannya adalah untuk pengambilan sampel dengan penggantian. Saya pikir itu menjelaskan mengapa jawaban Anda sebesar 1,08% jauh lebih besar dari perkiraan saya sebesar 0,4%. Apakah ada cara untuk memodifikasi pendekatan Anda untuk menangani pengambilan sampel tanpa penggantian?
vqv
2
@ vqv Ya. Sekarang kami memiliki daftar setengah juta rak tanpa kata-kata, sangat mudah (dengan mengubah dua baris kode terakhir) untuk menghitung peluang setiap rak (tanpa penggantian) dan mendapatkan hasil hypergeometric. Jawaban pastinya sama dengan 349870667877/80678106432000 = 0,43366% . Dengan uji N = 100K SE Anda adalah 0,021%, jadi jawaban Anda seharusnya berkisar antara 0,38% dan 0,49% (CI dua sisi 99%). Saya sangat senang jawaban kami setuju!
whuber
@whuber Bisakah Anda menjalankan perhitungan menggunakan distribusi ubin Words With Friends (WWF)? Perkiraan saya sebesar 0,4% didasarkan pada leksikon WWF dan distribusi ubin WWF. Saya pikir Anda menggunakan distribusi ubin Scrabble dengan leksikon WWF.
vqv
Ups. Jawaban tepatnya sebenarnya adalah 349870675899 (saya 8022 tidak aktif karena kesalahan dalam kamus saya.) Untungnya, tidak ada perbedaan praktis.
Whuber
@ vqv Saya tidak terbiasa dengan berbagai distribusi ubin. Saya menyalin milik saya langsung dari kode Anda (dan saya menggunakan kamus Anda) :-). Jika Anda maksud distribusi di osxreality.com/2010/01/01/… , maka saya memperoleh 1,15444% (dengan penggantian), 0,43366% (tanpa penggantian). Angka kedua sebenarnya berbeda dari frekuensi Scrabble pada angka signifikansi ke-8.
whuber
14

Sangat sulit untuk menggambar rak yang tidak mengandung kata yang valid di Scrabble dan variannya. Di bawah ini adalah program R yang saya tulis untuk memperkirakan probabilitas bahwa rak 7-ubin awal tidak mengandung kata yang valid. Ini menggunakan pendekatan monte carlo dan leksikon Words With Friends (saya tidak dapat menemukan leksikon Scrabble resmi dalam format yang mudah). Setiap percobaan terdiri dari menggambar rak 7-ubin, dan kemudian memeriksa apakah rak berisi kata yang valid.

Kata-kata minimal

Anda tidak perlu memindai seluruh leksikon untuk memeriksa apakah rak berisi kata yang valid. Anda hanya perlu memindai leksikon minimal yang terdiri dari kata-kata minimal . Sebuah kata minimal jika tidak mengandung kata lain sebagai himpunan bagian. Misalnya 'em' adalah kata minimal; 'kosong' tidak. Intinya adalah bahwa jika sebuah rak berisi kata x maka itu juga harus mengandung subset dari x . Dengan kata lain: rak tidak mengandung kata-kata jika tidak mengandung kata-kata minimal. Untungnya, sebagian besar kata dalam leksikon tidak minimal, sehingga dapat dihilangkan. Anda juga dapat menggabungkan kata-kata yang setara permutasi. Saya dapat mengurangi leksikon Words With Friends dari 172.820 menjadi 201 kata minimal.

Wildcard dapat dengan mudah ditangani dengan memperlakukan rak dan kata-kata sebagai distribusi atas surat-surat. Kami memeriksa apakah rak berisi kata dengan mengurangi satu distribusi dari yang lain. Ini memberi kita jumlah setiap huruf yang hilang dari rak. Jika jumlah angka itu jumlah wildcard, maka kata itu ada di rak.

Satu-satunya masalah dengan pendekatan monte carlo adalah bahwa peristiwa yang kami minati sangat jarang terjadi. Jadi perlu banyak, banyak percobaan untuk mendapatkan perkiraan dengan kesalahan standar yang cukup kecil. Saya menjalankan program saya (disisipkan di bagian bawah) dengan percobaan dan mendapat probabilitas diperkirakan 0,004 bahwa rak awal tidak mengandung kata yang valid . Kesalahan standar estimasi estimasi itu adalah 0,0002. Hanya perlu beberapa menit untuk berjalan di Mac Pro saya, termasuk mengunduh leksikon.N=100,000

Saya akan tertarik melihat apakah seseorang dapat datang dengan algoritma tepat yang efisien. Pendekatan naif berdasarkan inklusi-eksklusi tampaknya bisa melibatkan ledakan kombinatorial.

Inklusi-pengecualian

Saya pikir ini adalah solusi yang buruk, tapi ini sketsa yang tidak lengkap. Pada prinsipnya Anda dapat menulis program untuk melakukan perhitungan, tetapi spesifikasinya akan berliku.

Probabilitas yang ingin kita hitung adalah Peristiwa di dalam probabilitas di sisi kanan adalah gabungan peristiwa: P ( k -tile rak mengandung kata ) = P ( x M { k -tile rak berisi  x } ) , di mana M

P(k-tile rack does not contain a word)=1P(k-tile rack contains a word).
P(k-tile rack contains a word)=P(xM{k-tile rack contains x}),
Madalah leksikon minimal. Kami dapat mengembangkannya menggunakan rumus inklusi-pengecualian. Ini melibatkan mempertimbangkan semua persimpangan yang mungkin dari peristiwa di atas. Mari menunjukkan kekuatan set M , yaitu himpunan semua himpunan bagian yang mungkin dari M . Kemudian 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})


xS{k-tile rack contains x}
S

Kemudian

P(xS{k-tile rack contains x})=w=0nP(xS{k-tile rack contains x}|k-tile rack contains w wildcards)×P(k-tile rack contains w wildcards).

2|M|2|M|3.2×1060

Memindai semua kemungkinan rak

krak -tile sampai kita mendapatkan set rak yang tidak mengandung kata-kata. Untuk Scrabble (atau Words With Friends) jumlah rak 7-ubin yang mungkin ada dalam puluhan miliar. Menghitung jumlah orang yang tidak mengandung kata yang mungkin harus dilakukan dengan beberapa lusin baris kode R. Tapi saya pikir Anda harus bisa melakukan lebih baik daripada hanya menghitung semua rak yang mungkin. Misalnya, 'aa' adalah kata minimal. Itu segera menghilangkan semua rak yang berisi lebih dari satu 'a'. Anda bisa mengulanginya dengan kata lain. Memori seharusnya tidak menjadi masalah bagi komputer modern. Rak Scrabble 7-ubin membutuhkan kurang dari 7 byte penyimpanan. Paling buruk kami akan menggunakan beberapa gigabyte untuk menyimpan semua rak yang mungkin, tapi saya pikir itu juga bukan ide yang baik. Seseorang mungkin ingin lebih memikirkan hal ini.

Program Monte Carlo R.

# 
#  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)), ")")
vqv
sumber
Wow ... tindak lanjut yang sangat bagus.
Matt Parker
Saya agak terkejut itu berkurang menjadi 201 kata. Meskipun untuk kata pertama yang dimainkan, aturan rumah kami menerima 'I' dan 'A' sebagai kata-kata, yang mungkin akan semakin mengurangi jumlah kata minimal. Saya berharap untuk melihat seseorang memecahkan analisis inklusi-eksklusi, yang seharusnya sangat berbulu ...
shabbychef
@shabbychef Tidak ada kata 1 huruf dalam leksikon. Kebanyakan kata minimal adalah kata 2 dan 3 huruf. Berikut adalah distribusi penuh panjang kata minimal: 2: 73, 3:86, 4:31, 5: 9, 6: 2. Kata-kata 6 huruf adalah: GLYCYL dan SYZYGY.
vqv
@shabbychef Saya memperbarui jawaban saya untuk memasukkan sketsa pendekatan inklusi-eksklusi yang tepat. Ini lebih buruk daripada berbulu.
vqv
kerja bagus! Saya suka bahwa pertanyaan ini, yang dapat diajukan sebagai satu kalimat (kepada mereka yang memiliki latar belakang yang cukup), telah mengeluarkan monte carlo, inklusi-pengecualian, DAG, pencarian pohon, aljabar polinomial, dan bahwa simulasi Anda dikonfirmasi oleh teori @ whuber. tepuk tangan!
shabbychef
7

Srikant benar: belajar di Monte Carlo adalah jalan yang harus ditempuh. Ada dua alasan. Pertama, jawabannya sangat tergantung pada struktur kamus. Dua ekstrem adalah (1) kamus berisi setiap kata dengan satu huruf. Dalam hal ini, peluang untuk tidak membuat kata dalam undian1atau lebih banyak huruf adalah nol. (2) Kamus hanya berisi kata-kata yang dibentuk dari satu huruf ( misalnya , "a", "aa", "aaa", dll .). Kesempatan untuk tidak membuat kata dalam undiankhuruf mudah ditentukan dan jelas bukan nol. Setiap jawaban pasti bentuk tertutup harus menggabungkan seluruh struktur kamus dan akan menjadi formula yang benar-benar mengerikan dan panjang.

Alasan kedua adalah bahwa MC memang layak: Anda hanya harus melakukannya dengan benar. Paragraf sebelumnya memberikan petunjuk: jangan hanya menghasilkan kata-kata secara acak dan mencarinya; sebagai gantinya, menganalisis kamus terlebih dahulu dan memanfaatkan strukturnya.

Salah satu cara mewakili kata-kata dalam kamus sebagai pohon. Pohon itu berakar pada simbol dan ranting kosong pada setiap huruf sampai ke bawah; daunnya (tentu saja) adalah kata-kata itu sendiri. Namun, kami juga dapat memasukkan semua permutasi nontrivial dari setiap kata ke pohon, juga (hinggak!-1dari mereka untuk setiap kata). Ini dapat dilakukan secara efisien karena seseorang tidak harus menyimpan semua permutasi tersebut; hanya ujung-ujung pohon perlu ditambahkan. Daunnya tetap sama. Bahkan, ini dapat disederhanakan lebih lanjut dengan menegaskan bahwa pohon tersebut harus diikuti dalam urutan abjad .

Dengan kata lain, untuk menentukan apakah multiset dari kkarakter ada di kamus, pertama mengatur elemen ke dalam urutan, lalu cari "kata" yang diurutkan ini di pohon yang dibangun dari perwakilan kata yang diurutkan di kamus asli. Ini sebenarnya akan lebih kecil dari pohon asli karena menggabungkan semua set kata yang setara, seperti {stop, post, pot, opts, spot}. Bahkan, dalam kamus bahasa Inggris, kelas kata ini tidak akan pernah tercapai karena "begitu" akan ditemukan terlebih dahulu. Mari kita lihat ini dalam aksi. Multiset yang diurutkan adalah "opst"; "o" akan bercabang ke semua kata yang hanya berisi huruf {o, p, ..., z}, "p" akan bercabang ke semua kata yang hanya berisi {o, p, ..., z} dan paling banyak satu "o", dan akhirnya "s" akan bercabang ke daun "begitu"!

Diperlukan modifikasi untuk menangani wildcard: Saya akan membiarkan tipe programmer di antara Anda memikirkannya. Itu tidak akan menambah ukuran kamus (sebenarnya akan menguranginya); itu akan sedikit memperlambat traversal pohon, tetapi tanpa mengubahnya dengan cara mendasar. Dalam kamus apa pun yang berisi kata satu huruf, seperti bahasa Inggris ("a", "i"), tidak ada kerumitan: kehadiran wildcard berarti Anda dapat membentuk sebuah kata! (Ini mengisyaratkan bahwa pertanyaan awal mungkin tidak semenarik kedengarannya.)

Hasilnya adalah bahwa pencarian kamus tunggal membutuhkan (a) pengurutan a kmultiset-newsletter dan (b) melintasi tidak lebih dari kujung-ujung pohon. Waktu berjalan adalahHAI(klog(k)). If you cleverly generate random multisets in sorted order (I can think of several efficient ways to do this), the running time reduces to O(k). Multiply this by the number of iterations to get the total running time.

I bet you could conduct this study with a real Scrabble set and a million iterations in a matter of seconds.

whuber
sumber
@whuber The tree is a neat idea (upvote for that idea) but would it not require lot of memory? I guess it depends on how diverse the dictionary is but I am guessing a reasonably diverse dictionary would require many trees For example, the 'b' tree would start with the letter 'b' instead of 'a' for all those words which do not have 'a' in them. Similarly, the 'c' tree would start with the letter 'c' for those words which do not have 'a' and 'b' but have 'c'. My proposed direct approach seems simpler as it requires a one-time traversal of all the words in the dictionary, no?
1
@Srikant: The tree would likely require far less RAM than caching the entire dictionary to begin with. Are you really concerned about a few megabytes of RAM, anyway? BTW, there's only one tree, not many: they are all rooted at the empty word. Your approach, as I have understood it, requires multiple searches of the dictionary (up to 7! of them) on every iteration, making it impracticable as @shabbychef fears. It would help if you could elaborate on the algorithm you have in mind where you write "see if you can form a word": that hides a lot of important details!
whuber
@whuber: I realized the fact that there is only one tree after I posted my comment. Reg my approach- I agree that my monte carlo proposal is fuzzy and your answer fleshes out how one can actually implement monte carlo in this setting. I actually meant that the direct approach (see my answer) may actually be simpler as that approach requires a one-time operation on the dictionary unlike a monte carlo which requires several thousands of iterations on the tree. Just wondering on the relative merits of the approaches.
@Srikant Saya menahan diri untuk tidak mengomentari pendekatan langsung Anda karena saya kira itu mendapatkan jawaban yang salah. Tampaknya tidak memperhitungkan struktur kamus: yaitu, hubungan subset di antara kata-kata. Misalnya, apakah rumus Anda mendapatkan jawaban yang benar yaitu nol untuk semua kamus yang berisi semua kata satu huruf yang mungkin?
whuber
@whuber hmmm poin bagus. Mungkin, saya menjawab pertanyaan yang salah!
2

Pendekatan Monte Carlo

Pendekatan cepat dan kotor adalah melakukan studi monte carlo. Serik ubin m waktu dan untuk setiap undian k tiles see if you can form a word. Denote the number of times you could form a word by mw. The desired probability would be:

1mwm

Direct Approach

Let the number of words in the dictionary be given by S. Let ts be the number of ways in which we can form the sth word. Let the number of letters needed by the sth word be denoted by ma,mb,...,mz (i.e., the sth word needs ma number of 'a' letters etc). Denote the number of words we can form with all tiles by N.

N=(nk)

and

ts=(nama)(nbmb)...(nzmz)

(Including the impact of wildcard tiles is a bit trickier. I will defer that issue for now.)

Thus, the desired probability is:

1stsN

sumber
The quick and dirty approach may not be so quick! The dictionary may contain 100,000 words, and the search for a match of the given tiles could be a coding disaster.
shabbychef
@shabbychef This is something well done to suit spell checkers. See for instance n3labs.com/pdf/lexicon-squeeze.pdf
@shabbychef Reg monte-carlo- if the dictionary is sorted a match should be fairly quick no? In any case, the direct approach that I outlined earlier was flawed. I fixed it. The problem in my earlier solution was that the same word can be formed multiple ways (e.g., 'bat', 'b*t' etc).
1
@shabbychef On further reflection, I agree with you that the monte carlo approach will not work. One issue is that you need to figure out which words you can actually form with the k tiles and the second one is that you can form multiple words with the k tiles. Calculating these combinations from k tiles is probably not that easy.
1
@Srikant Thanks. Your formula seems to assume you have to use all k letters to form the word, but I don't think that's what the OP is asking. (That's not how Scrabble is played, anyway.) With that implicit assumption, you're on the right track but you need to modify the algorithm: you mustn't repeat the calculation for words in the dictionary that are permutations of each other. For example, you mustn't subtract both t_{stop} and t_{post} in your formula. (This is an easy modification to implement.)
whuber