Xác suất không vẽ một từ trong túi chữ cái trong Scrabble


27

Giả sử bạn có một cái túi có gạch, mỗi cái có một chữ cái trên đó. Có các gạch có chữ 'A', với 'B', v.v. và gạch 'ký tự đại diện' (chúng tôi có ). Giả sử bạn đã có một từ điển với số lượng từ hữu hạn. Bạn chọn gạch từ túi mà không cần thay thế. Làm thế nào bạn sẽ tính toán (hoặc ước tính) xác suất mà bạn có thể tạo thành các từ không trong từ điển cho các ô được chọn?n A n B n * n = n Một + n B + ... + n Z + n * k knnAnBnn=nA+nB++nZ+nkk

Đối với những người không quen thuộc với Scrabble (TM), ký tự đại diện có thể được sử dụng để khớp với bất kỳ chữ cái nào. Do đó, từ [ BOOT ] có thể được 'đánh vần' với các ô 'B', '*', 'O', 'T'.

Để đưa ra một số ý tưởng về quy mô của vấn đề, k là nhỏ, như 7, n là khoảng 100, và từ điển chứa khoảng 100.000 từ có kích thước k hoặc nhỏ hơn.

chỉnh sửa: Bằng cách 'tạo thành một từ', ý tôi là một từ có độ dài không lớn hơn k . Do đó, nếu từ [ A ] có trong từ điển, thì bằng cách vẽ ngay cả một chữ 'A' từ túi, người ta đã 'tạo thành một từ'. Vấn đề về ký tự đại diện được đơn giản hóa triệt để nếu người ta có thể giả sử có những từ có độ dài 1 trong từ điển. Vì nếu có, bất kỳ hình vẽ ký tự đại diện nào cũng có thể tự động khớp với độ dài 1 từ và do đó, người ta có thể tập trung vào trường hợp không có ký tự đại diện. Do đó, dạng vấn đề trơn hơn không có từ 1 chữ cái trong từ điển.

Ngoài ra, tôi nên nói rõ rằng thứ tự các chữ cái được rút ra từ túi là không quan trọng. Người ta không phải vẽ các chữ cái theo thứ tự 'chính xác' của từ.


Không nên 'chọn k gạch mà không thay thế'? Câu hỏi rất thú vị.

Rất tiếc. thực sự nó nên
shabbychef

Theo như tôi nhớ thì Scrabble không cho phép một từ chữ cái, vì vậy ít nhất một phần của vấn đề đã được giải quyết;)
nico

1
@nico điểm tốt, nhưng tôi nghĩ cái này chỉ dành cho mid-game. 1 chữ cái hoặc không yêu cầu một chữ cái chơi hoặc sẽ cho phép một chữ cái đặt bất cứ nơi nào trên bảng, cả hai đều rõ ràng không thể chấp nhận được. Tuy nhiên, tôi đã nghĩ đến động thái mở đầu. Trên thực tế, câu hỏi có thể được nêu ra một cách gọn gàng, đối với những người quen thuộc với Scrabble, vì "xác suất mà người chơi đầu tiên sẽ phải vượt qua là gì?"
shabbychef

@nico Cảm ơn bạn đã làm rõ. Về mặt lý thuyết, một vấn đề tương tự liên quan đến từ điển có chứa tất cả các kết hợp hai chữ cái có thể là các từ: khi đó là trường hợp, bất kỳ tay nào có từ 2 chữ cái trở lên sẽ tự động chứa một từ. Nhận xét của @ shabbychef về mid-game cho thấy câu hỏi ban đầu không liên quan đến hầu hết Scrabble như thế nào, bởi vì trong mid game bạn có sẵn một loạt các phần từ (tiền tố, hậu tố và thậm chí cả phần giữa) ngoài 7 chữ cái trong bạn tay. Điều này làm tăng đáng kể cơ hội để có thể tạo ra một từ.
whuber

Câu trả lời:


14

Đây là một nhận xét (dài!) Về tác phẩm hay mà @vqv đã đăng trong chủ đề này. Nó nhằm mục đích để có được một câu trả lời dứt khoát. Ông đã làm công việc khó khăn để đơn giản hóa từ điển. Tất cả những gì còn lại là khai thác nó một cách đầy đủ nhất. Kết quả của ông cho thấy một giải pháp vũ phu là khả thi . Rốt cuộc, bao gồm cả ký tự đại diện, có nhiều nhất là từ có thể tạo với 7 ký tự và có vẻ như chưa đến 1/10000 trong số đó - khoảng một triệu - sẽ không bao gồm một số từ hợp lệ. 277=10,460,353,203

Bước đầu tiên là tăng từ điển tối thiểu bằng ký tự đại diện, "?". 22 trong số các chữ cái xuất hiện trong các từ hai chữ cái (tất cả trừ c, q, v, z). Nối một ký tự đại diện vào 22 chữ cái đó và thêm chúng vào từ điển: {a?, B?, D?, ..., y?} Hiện đang ở. Tương tự chúng ta có thể kiểm tra các từ ba chữ cái tối thiểu, gây ra một số từ bổ sung để xuất hiện trong từ điển. Cuối cùng, chúng tôi thêm "??" vào từ điển Sau khi loại bỏ sự lặp lại kết quả đó, nó chứa 342 từ tối thiểu.

Một cách thức thanh lịch để tiến hành - một cách sử dụng một lượng mã hóa rất nhỏ thực sự - là xem vấn đề này như một vấn đề đại số . Một từ, được coi là một tập hợp các chữ cái không có thứ tự, chỉ là một từ đơn. Ví dụ: "spats" là đơn thức . Do đó, từ điển là một bộ sưu tập các đơn thức. Nó có vẻ nhưaps2t

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

(ở đâu, để tránh nhầm lẫn, tôi đã viết cho ký tự đại diện).ψ

Một giá chứa một từ hợp lệ khi và chỉ khi từ đó chia giá.

Một trừu tượng hơn, nhưng cực kỳ mạnh mẽ, cách nói này là từ điển tạo ra một lý tưởng trong đa thức nhẫn R = Z [ một , b , ... , z , ψ ] và rằng kệ với các từ hợp lệ trở thành số không trong thương ring R / I , trong khi giá đỡ không có từ hợp lệ vẫn không khác biệt trong thương số. Nếu chúng ta tạo tổng của tất cả các giá đỡ trong R và tính nó trong vòng thương số này, thì số lượng giá đỡ không có từ bằng với số lượng đơn thức riêng biệt trong thương số.IR=Z[a,b,,z,ψ]R/IR

Hơn nữa, tổng của tất cả các giá đỡ trong là đơn giản để thể hiện. Đặt α = a + b + + z + ψ là tổng của tất cả các chữ cái trong bảng chữ cái. α 7 chứa một đơn thức cho mỗi giá đỡ. (Là một phần thưởng bổ sung, các hệ số của nó sẽ đếm số cách mỗi giá có thể được hình thành, cho phép chúng tôi tính xác suất của nó nếu chúng tôi muốn.)Rα=a+b++z+ψα7

Như một ví dụ đơn giản (để xem cách thức hoạt động của nó), giả sử (a) chúng ta không sử dụng ký tự đại diện và (b) tất cả các chữ cái từ "a" đến "x" đều được coi là từ. Sau đó, giá đỡ duy nhất có thể từ đó các từ không thể được hình thành phải bao gồm toàn bộ y và z. Chúng tôi tính toán modulo lý tưởng được tạo bởi { a , b , c , Trần , x } một bước tại một thời điểm, do đó:α=(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.

Chúng ta có thể đọc được cơ hội nhận được giá không từ từ câu trả lời cuối cùng, : mỗi hệ số đếm các cách mà giá đỡ tương ứng có thể được rút ra. Ví dụ: có 21 cách (trong số 26 ^ 7 có thể) để vẽ 2 y và 5 z vì hệ số của yy7+7y6z+21y5z2+35y4z3+35y3z4+21y2z5+7yz6+z7 bằng 21.y2z5

Từ các tính toán cơ bản, rõ ràng đây là câu trả lời chính xác. Toàn bộ vấn đề là thủ tục này hoạt động bất kể nội dung của từ điển.

Lưu ý cách giảm modulo công suất lý tưởng ở từng giai đoạn làm giảm tính toán: đó là lối tắt được tiết lộ theo phương pháp này. (Kết thúc ví dụ.)

Hệ thống đại số đa thức thực hiện các tính toán này . Ví dụ, đây là Mathematica mã:

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]

(Từ điển có thể được xây dựng theo cách đơn giản từ min.dict của @ vqv; Tôi đặt một dòng ở đây cho thấy rằng nó đủ ngắn để được chỉ định trực tiếp nếu bạn muốn.)

Đầu ra - mất mười phút tính toán - là 577958. ( NB Trong phiên bản trước của thông báo này, tôi đã mắc một lỗi nhỏ trong việc chuẩn bị từ điển và thu được 577940. Tôi đã chỉnh sửa văn bản để phản ánh những gì tôi hy vọng bây giờ kết quả chính xác!) Ít hơn một triệu so với tôi dự kiến, nhưng có cùng độ lớn.

Để tính toán cơ hội có được giá như vậy, chúng ta cần tính đến số cách có thể rút ra giá. Như chúng ta đã thấy trong ví dụ, điều này bằng với hệ số của nó trong . Cơ hội vẽ một số giá như vậy là tổng của tất cả các hệ số này, dễ dàng tìm thấy bằng cách đặt tất cả các chữ cái bằng 1:α7

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

Câu trả lời bằng 1066056120, mang lại cơ hội 10,1914% cho việc vẽ một giá đỡ mà từ đó không có từ nào hợp lệ có thể được hình thành (nếu tất cả các chữ cái đều có khả năng như nhau).

Khi xác suất của các chữ cái khác nhau, chỉ cần thay thế từng chữ cái với cơ hội được rút ra:

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)

Đầu ra là 1.079877553303%, câu trả lời chính xác (mặc dù sử dụng một mô hình gần đúng, bản vẽ thay thế). Nhìn lại, phải mất bốn dòng để nhập dữ liệu (bảng chữ cái, từ điển và tần số bảng chữ cái) và chỉ có ba dòng để thực hiện công việc: mô tả cách lấy sức mạnh tiếp theo của modulo I , lấy đệ quy nguồn thứ 7 và thay thế xác suất cho các chữ cái.αI


+1 Liền kề từ vựng và sau đó thu nhỏ lại nó là một ý tưởng thông minh. Đại số nằm ngoài tôi, nhưng có cảm giác như bạn đang tính một xác suất đa cực, thay vì siêu âm. Vì vậy, xác suất là để lấy mẫu với sự thay thế. Tôi nghĩ điều đó giải thích tại sao câu trả lời của bạn là 1,08% lớn hơn nhiều so với ước tính của tôi là 0,4%. Có cách nào để sửa đổi cách tiếp cận của bạn để xử lý lấy mẫu mà không cần thay thế?
vqv

2
@vqv Vâng. Bây giờ chúng tôi có một danh sách gồm nửa triệu giá trị không có từ nào, thật đơn giản (bằng cách thay đổi hai dòng mã cuối cùng) để tính toán cơ hội của từng giá (không thay thế) và có được kết quả siêu âm. Câu trả lời chính xác bằng 349870667877/80678106432000 = 0.43366% . Với N = 100K thử nghiệm, SE của bạn là 0,021%, vì vậy câu trả lời của bạn phải nằm trong khoảng từ 0,38% đến 0,49% (CI hai mặt 99%). Tôi rất vui vì câu trả lời của chúng tôi đồng ý!
whuber

@whuber Bạn có thể chạy phép tính bằng cách sử dụng phân phối gạch Words With Friends (WWF) không? Ước tính của tôi là 0,4% dựa trên phân phối gạch từ vựng WWF và WWF. Tôi nghĩ rằng bạn đang sử dụng phân phối gạch Scrabble với từ vựng WWF.
vqv

Rất tiếc. Câu trả lời chính xác thực sự là 349870675899 (tôi đã tắt 8022 do một lỗi trong từ điển của tôi.) Điều này không có sự khác biệt thực tế, may mắn thay.
whuber

@vqv Tôi không quen thuộc với các bản phân phối gạch khác nhau. Tôi đã sao chép trực tiếp từ mã của bạn (và tôi đã sử dụng từ điển của bạn) :-). Nếu bạn có nghĩa là phân phối tại osxreality.com/2010/01/01/ , thì tôi nhận được 1,15444% (có thay thế), 0,43366% (không thay thế). Số thứ hai thực sự khác với tần số Scrabble ở con số đáng kể thứ 8.
whuber

14

Rất khó để vẽ một giá đỡ không chứa bất kỳ từ hợp lệ nào trong Scrabble và các biến thể của nó. Dưới đây là chương trình R tôi đã viết để ước tính xác suất giá đỡ 7 ô ban đầu không chứa từ hợp lệ. Nó sử dụng cách tiếp cận monte carlo và từ vựng Words With Friends (Tôi không thể tìm thấy từ vựng Scrabble chính thức ở định dạng dễ dàng). Mỗi thử nghiệm bao gồm vẽ một giá đỡ 7 gạch, sau đó kiểm tra xem giá đó có chứa một từ hợp lệ không.

Từ tối thiểu

Bạn không phải quét toàn bộ từ vựng để kiểm tra xem giá có chứa một từ hợp lệ hay không. Bạn chỉ cần quét một từ vựng tối thiểu bao gồm các từ tối thiểu . Một từ là tối thiểu nếu nó không chứa từ nào khác dưới dạng tập hợp con. Ví dụ: 'em' là một từ tối thiểu; 'trống rỗng' thì không. Điểm của điều này là nếu một giá chứa từ x thì nó cũng phải chứa bất kỳ tập hợp con nào của x . Nói cách khác: giá đỡ không chứa từ iff nó không chứa từ tối thiểu. May mắn thay, hầu hết các từ trong từ vựng không phải là tối thiểu, vì vậy chúng có thể được loại bỏ. Bạn cũng có thể hợp nhất các từ tương đương hoán vị. Tôi đã có thể giảm từ vựng Words With Friends từ 172.820 xuống 201 từ tối thiểu.

Ký tự đại diện có thể được xử lý dễ dàng bằng cách coi giá đỡ và từ như phân phối trên các chữ cái. Chúng tôi kiểm tra xem giá có chứa một từ hay không bằng cách trừ đi một phân phối từ phân phối khác. Điều này cho chúng ta số lượng của mỗi chữ cái bị thiếu từ giá đỡ. Nếu tổng của những số là số lượng ký tự đại diện, sau đó từ đó có trong các rack.

Vấn đề duy nhất với phương pháp monte carlo là sự kiện mà chúng tôi quan tâm là rất hiếm. Vì vậy, cần nhiều, rất nhiều thử nghiệm để có được ước tính với sai số chuẩn nhỏ. Tôi đã chạy chương trình của mình (dán ở phía dưới) với thử nghiệm và cóxác suất ước tính là 0,004 rằng giá đỡ ban đầu không chứa từ hợp lệ. Lỗi tiêu chuẩn ước tính của ước tính đó là 0,0002. Chỉ mất vài phút để chạy trên Mac Pro của tôi, bao gồm cả việc tải xuống từ vựng.N=100,000

Tôi muốn biết liệu ai đó có thể đưa ra một thuật toán chính xác hiệu quả hay không. Một cách tiếp cận ngây thơ dựa trên loại trừ bao gồm có vẻ như nó có thể liên quan đến một vụ nổ tổ hợp.

Bao gồm loại trừ

Tôi nghĩ rằng đây là một giải pháp tồi, nhưng dù sao đây cũng là một bản phác thảo chưa hoàn chỉnh. Về nguyên tắc bạn có thể viết một chương trình để thực hiện phép tính, nhưng đặc tả sẽ khó hiểu.

Xác suất chúng tôi muốn tính toán là Sự kiện bên trong xác suất ở phía bên phải là sự kết hợp của các sự kiện: P ( k -tile rack chứa một từ ) = P ( x M { k -tile rack chứa  x } ) , trong đó 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}),
Mlà một từ vựng tối thiểu. Chúng tôi có thể mở rộng nó bằng cách sử dụng công thức loại trừ bao gồm. Nó liên quan đến việc xem xét tất cả các giao điểm có thể có của các sự kiện trên. Hãy biểu thị tập hợp sức mạnh của M , tức là tập hợp của tất cả các tập con có thể có của M . Sau đó 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

Sau đó

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

Quét tất cả các giá đỡ có thể

Tôi nghĩ rằng điều này là dễ dàng hơn về mặt tính toán, bởi vì có ít giá đỡ có thể hơn các tập hợp con của các từ tối thiểu có thể. Chúng tôi liên tục giảm tập có thểk-tile giá đỡ cho đến khi chúng ta có được bộ giá đỡ không chứa từ. Đối với Scrabble (hoặc Words With Friends), số lượng giá đỡ 7 ô có thể lên tới hàng chục tỷ. Việc đếm số lượng những từ không chứa một từ có thể thực hiện được với vài chục dòng mã R. Nhưng tôi nghĩ bạn sẽ có thể làm tốt hơn là chỉ liệt kê tất cả các giá đỡ có thể. Chẳng hạn, 'aa' là một từ tối thiểu. Điều đó ngay lập tức loại bỏ tất cả các giá đỡ chứa nhiều hơn một 'a'. Bạn có thể lặp lại với các từ khác. Bộ nhớ không phải là một vấn đề cho máy tính hiện đại. Giá đỡ Scrabble 7 ô cần ít hơn 7 byte dung lượng lưu trữ. Tệ nhất là chúng tôi sẽ sử dụng một vài gigabyte để lưu trữ tất cả các giá đỡ có thể, nhưng tôi cũng không nghĩ đó là một ý tưởng hay. Ai đó có thể muốn nghĩ thêm về điều này.

Chương trình 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)), ")")

Wow ... theo dõi rất tốt đẹp.
Matt Parker

Tôi hơi ngạc nhiên khi nó giảm xuống còn 201 từ. Mặc dù đối với từ đầu tiên được chơi, các quy tắc chung của chúng tôi chấp nhận 'Tôi' và 'A' là các từ, điều này có thể sẽ làm giảm thêm số lượng từ tối thiểu. Tôi đã hy vọng nhìn thấy ai đó phá vỡ phân tích loại trừ bao gồm, nó sẽ rất nhiều lông ...
shabbychef

@shabbychef There are no 1-letter words in the lexicon. Most minimal words are 2- and 3-letter words. Here is the full distribution of minimal word lengths: 2: 73, 3:86, 4:31, 5:9, 6:2. The 6-letter words are: GLYCYL and SYZYGY.
vqv

@shabbychef Tôi đã cập nhật câu trả lời của mình để bao gồm một bản phác thảo về cách tiếp cận loại trừ chính xác. Nó còn tệ hơn cả lông.
vqv

công việc tuyệt vời Tôi thích rằng câu hỏi này, có thể được đặt ra dưới dạng một câu (với những người có đủ nền tảng), đã đưa ra monte carlo, loại trừ bao gồm, DAG, tìm kiếm cây, đại số đa thức và mô phỏng của bạn được xác nhận bởi lý thuyết của @ whuber. chúc mừng
shabbychef

7

Srikant đã đúng: một nghiên cứu ở Monte Carlo là con đường để đi. Có hai lý do. Đầu tiên, câu trả lời phụ thuộc mạnh mẽ vào cấu trúc của từ điển. Hai thái cực là (1) từ điển chứa mọi từ đơn có thể có. Trong trường hợp này, cơ hội không tạo ra một từ trong một trận hòa1hoặc nhiều chữ cái bằng không. (2) Từ điển chỉ chứa các từ được tạo thành từ một chữ cái duy nhất ( ví dụ: "a", "aa", "aaa", v.v. ). Cơ hội không tạo ra một từ trong một trận hòakchữ cái dễ dàng được xác định và rõ ràng là khác không. Bất kỳ câu trả lời dạng đóng xác định nào cũng sẽ phải kết hợp toàn bộ cấu trúc từ điển và sẽ là một công thức thực sự khủng khiếp và dài.

Lý do thứ hai là MC thực sự khả thi: bạn chỉ cần làm đúng. Đoạn trước cung cấp một manh mối: không chỉ tạo ra các từ một cách ngẫu nhiên và tìm kiếm chúng; thay vào đó, hãy phân tích từ điển trước và khai thác cấu trúc của nó.

Một cách đại diện cho các từ trong từ điển như một cái cây. Cây được bắt nguồn từ biểu tượng trống và các nhánh trên mỗi chữ cái xuống; lá của nó là (tất nhiên) chính các từ. Tuy nhiên, chúng ta cũng có thể chèn tất cả các hoán vị không cần thiết của mỗi từ vào cây (tối đak!-1của họ cho mỗi từ). Điều này có thể được thực hiện một cách hiệu quả bởi vì người ta không phải lưu trữ tất cả các hoán vị đó; chỉ các cạnh trong cây cần được thêm vào. Lá vẫn như cũ. Trong thực tế, điều này có thể được đơn giản hóa hơn nữa bằng cách nhấn mạnh rằng cây được theo sau theo thứ tự bảng chữ cái .

Nói cách khác, để xác định xem có nhiều kcác ký tự có trong từ điển, đầu tiên sắp xếp các thành phần theo thứ tự sắp xếp,sau đó tìm "từ" được sắp xếp này trong một cây được xây dựng từ các đại diện được sắp xếp của các từ trong từ điển gốc. Cái này thực sự sẽ nhỏ hơn cây ban đầu vì nó hợp nhất tất cả các bộ từ tương đương với sắp xếp, chẳng hạn như {stop, post, pot, opts, spot}. Trong thực tế, trong một từ điển tiếng Anh, lớp từ này sẽ không bao giờ đạt được bởi vì "vì vậy" sẽ được tìm thấy đầu tiên. Chúng ta hãy xem điều này trong hành động. Multiset được sắp xếp là "opst"; "o" sẽ phân nhánh cho tất cả các từ chỉ chứa các chữ cái {o, p, ..., z}, "p" sẽ phân nhánh cho tất cả các từ chỉ chứa {o, p, ..., z} và tối đa một "o", và cuối cùng "s" sẽ phân nhánh thành lá "vậy"! (Tôi đã giả định rằng không có ứng cử viên hợp lý nào "o", "op", "

Một sửa đổi là cần thiết để xử lý các ký tự đại diện: Tôi sẽ để các lập trình viên trong số các bạn nghĩ về điều đó. Nó sẽ không tăng kích thước từ điển (trên thực tế nên giảm nó); nó sẽ làm chậm tốc độ di chuyển của cây, nhưng không thay đổi nó theo bất kỳ cách cơ bản nào. Trong bất kỳ từ điển nào có chứa một từ đơn, như tiếng Anh ("a", "i"), không có sự phức tạp: sự hiện diện của ký tự đại diện có nghĩa là bạn có thể tạo thành một từ! (Điều này gợi ý rằng câu hỏi ban đầu có thể không thú vị như âm thanh.)

Kết quả cuối cùng là một tra cứu từ điển duy nhất yêu cầu (a) sắp xếp một k-letter multiset và (b) di chuyển ngang không quá kcác cạnh của cây. Thời gian chạy làÔi(kđăng nhập(k)). Nếu bạn khéo léo tạo ra nhiều trang ngẫu nhiên theo thứ tự được sắp xếp (tôi có thể nghĩ ra một số cách hiệu quả để làm điều này), thời gian chạy sẽ giảm xuốngÔi(k). Nhân số này với số lần lặp để có tổng thời gian chạy.

Tôi cá là bạn có thể thực hiện nghiên cứu này với một bộ Scrabble thực sự và một triệu lần lặp lại trong vài giây.


@whuber Cây là một ý tưởng gọn gàng (upvote cho ý tưởng đó) nhưng nó sẽ không đòi hỏi nhiều bộ nhớ? Tôi đoán nó phụ thuộc vào mức độ đa dạng của từ điển nhưng tôi đoán một từ điển đa dạng hợp lý sẽ cần nhiều cây. Ví dụ, cây 'b' sẽ bắt đầu bằng chữ 'b' thay vì 'a' cho tất cả những từ không có 'a' trong đó. Tương tự, cây 'c' sẽ bắt đầu bằng chữ 'c' cho những từ không có 'a' và 'b' nhưng có 'c'. Cách tiếp cận trực tiếp được đề xuất của tôi có vẻ đơn giản hơn vì nó đòi hỏi phải duyệt một lần tất cả các từ trong từ điển, phải không?

1
@Srikant: Cây có thể sẽ cần ít RAM hơn nhiều so với bộ nhớ đệm toàn bộ từ điển để bắt đầu. Bạn có thực sự lo lắng về một vài megabyte RAM không? BTW, chỉ có một cây, không nhiều: tất cả đều bắt nguồn từ từ trống. Cách tiếp cận của bạn, như tôi đã hiểu, yêu cầu nhiều tìm kiếm từ điển (tối đa 7!) Trong mỗi lần lặp , làm cho nó không thể thực hiện được vì sợ @shabbychef. Sẽ rất hữu ích nếu bạn có thể giải thích về thuật toán mà bạn có trong đầu khi bạn viết "xem bạn có thể tạo thành một từ" hay không: ẩn giấu rất nhiều chi tiết quan trọng!
whuber

@whuber: Tôi nhận ra thực tế là chỉ có một cây sau khi tôi đăng bình luận của mình. Theo cách tiếp cận của tôi - Tôi đồng ý rằng đề xuất monte carlo của tôi mờ nhạt và câu trả lời của bạn làm sáng tỏ cách người ta thực sự có thể thực hiện monte carlo trong cài đặt này. Tôi thực sự có nghĩa là cách tiếp cận trực tiếp (xem câu trả lời của tôi) thực sự có thể đơn giản hơn vì cách tiếp cận đó đòi hỏi một thao tác một lần trên từ điển không giống như một bài thơ monte đòi hỏi hàng ngàn lần lặp trên cây. Chỉ cần tự hỏi về giá trị tương đối của các phương pháp.

@Srikant Tôi không chịu bình luận về cách tiếp cận trực tiếp của bạn bởi vì tôi nghi ngờ rằng nó nhận được câu trả lời sai. Nó không xuất hiện để cấu trúc từ điển: đó là mối quan hệ tập hợp con giữa các từ. Chẳng hạn, công thức của bạn có nhận được câu trả lời đúng bằng 0 cho tất cả các từ điển có chứa tất cả các từ một chữ cái có thể không?
whuber

@whuber hmmm điểm tốt. Có lẽ, tôi đang trả lời sai câu hỏi!

2

Phương pháp tiếp cận Monte Carlo

Cách tiếp cận nhanh và bẩn là thực hiện một nghiên cứu monte carlo. Vẽ tranhk gạch m thời gian và cho mỗi lần rút kgạch xem nếu bạn có thể tạo thành một từ. Biểu thị số lần bạn có thể tạo thành một từmw. Xác suất mong muốn sẽ là:

1-mwm

Tiếp cận trực tiếp

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

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.