[英]How to get multiple solutions for a crossword?
我已經看過論壇和不同的問題。
但我想問一些不同的問題。 我有兩個不同單詞的單詞列表和一個由 0 和 1 指定的網格。我將不得不從單詞列表 1 中的 select 單詞中獲取行和 2 中的列。
主要問題是我必須在給定的時間限制內找到多個解決方案。 有人可以為此建議我一些好的算法。 我沒有得到我應該采取什么樣的算法方法。
另一件事,我有兩種語言選擇。 c++ 或 java 會更好地實施。
謝謝你
我找到了一個可以滿足您需求的解決方案。 可悲的是,我不能把它歸功於它:)
這是一個例子。 你給它一個模式文件,比如pattern1
:
## ##
# #
# #
#
### ### ##
# # #
# #
# #
# #
# # #
## ### ###
#
# #
# #
## ##
您在其上調用程序,例如:
./cword pattern1 /etc/dictionaries-common/words
output 是
SODS##HOG##AMPS
APIA#RADON#LAUE
TESS#ALONE#ERNA
ENCHANTRESS#GYM
###ADS###TUTU##
#PAYDAY#ESPIES#
REV#SCALD#SCRIP
ARON#KNOWS#SITE
MCCOY#KNITS#TET
#HARASS#NAPPED#
##TACT###DIE###
MCI#COORDINATES
ELOY#AMARU#ROLL
SINE#TARIM#LIMA
SOSA##REP##SLOT
或者,再次運行:
PAWN##HOT##BEST
OLEO#SURYA#OMAR
LOAN#AGAPE#ABLE
SELFISHNESS#RTE
###ASH###OKAY##
#KATMAI#EPILOG#
INN#SYNOD#MULES
SETH#SCHWA#MONA
MEIER#AMIDS#GEM
#SPLATS#NOWAYS#
##APSE###RAY###
WIS#PATRONYMICS
ALTA#CHOKE#AREA
SLOP#HEARD#ROBS
PSST##ERA##ANUS
當然,對於較大的模式或較小的單詞表,您的里程可能會有所不同(非常大)。 我能夠在 Q9550 處理器上在 26.5 秒內完成 1000 代,使用
time for a in $(seq 1 200)
do
for a in 1 2 3 4 5
do
./cword pattern1 /etc/dictionaries-common/words | md5sum&
done
wait
done | sort | uniq -c | sort -n | tee >(wc -l)
output 證實這些實際上是 1000 個獨特的解決方案。 不壞,如果你問我。 (時間包括計算每個解決方案的 md5sums 的時間)
您也許可以使用稱為Dancing Links 或 DLX算法的東西。 這是解決精確覆蓋問題的一種非常有效的算法。
有幾個程序可以使用它來解決數獨難題。
老實說,我對確切的封面問題知之甚少,無法說這肯定會滿足您的需求,但值得一看。
在做填字游戲時,通常會發現自己在尋找一個特定長度的單詞,其中包含某個 position 處的某個字母。 因此,您可能會想要這樣的 function:
List<String> findWord(int ofLength, char withLetter, int atIndex) {/*implementation*/}
這可能會使用一組預先構建的 HashMap 來快速生成一組候選對象。 (您可能還希望能夠跟蹤該單詞當前是否已在填字游戲中使用……假設不允許重復)
人們做的另一件事是使用提示進行猜測。 我認為您可能不是在尋找強大的 AI,因此留下了蠻力算法……在這種情況下,請嘗試首先從最大的單詞開始填寫填字游戲,因為那里的可能性通常較小。
骨架算法:
private void checkPuzzleOn(Row row, SolutionSet s) {
List<Row> crossingRows = row.getCrossingRows();
if(allAlreadyFilled(crossingRows)) {
//This part of the crossword works; store info in solution set.
return;
}
crossingRows.sortBiggestToSmallest();
foreach(Row crossing in crossingRows) {
int index = row.getIndexOfIntersectionWith(crossing);
char c = row.charAt(index);
List<String> candidates = findWords(crossing.length, c, index);
foreach(String candidate in candidates) {
verifyAgainstPresentWords(crossing, candidate); //check that using this word won't collide with others; important because of cycles.
}
if(candidates.isEmpty()) {
//This part of the crossword won't match! store info in solution set.
return;
}
foreach(String candidate in candidates) {
crossing.setWord(candidate);
checkPuzzleOn(crossing, s);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.