独自のソリューションで数独ボードをどのように生成しますか?私が考えたのは、ランダムなボードを初期化し、いくつかの数字を削除することでした。しかし、私の質問は、ソリューションの一意性をどのように維持するかです。
簡単:
これよりもはるかに高速なソリューションを見つけることができるとは思わない。
ここに、私自身のSuDoKuプログラムが行う方法を示します。
完全な有効なボード(81個の数字が入力されている)から始めます。
81のセル位置すべてのリストを作成し、ランダムにシャッフルします。
リストが空でない限り、リストから次の位置を取り、関連するセルから番号を削除します。
高速バックトラッキングソルバーを使用して一意性をテストします。私のソルバーは-理論上-すべてのソリューションを数えることができますが、一意性をテストするために、複数のソリューションを見つけるとすぐに停止します。
現在のボードにまだ1つのソリューションしかない場合は、手順3)に進み、繰り返します。
現在のボードに複数のソリューションがある場合は、最後の取り外しを取り消し(ステップ3)、リストの次の位置からステップ3を続行します
81のポジションすべてをテストしたら停止します。
これにより、一意のボードだけでなく、ソリューションの一意性を損なうことなくそれ以上の数字を削除できないボードが得られます。
もちろん、これはアルゴリズムの後半にすぎません。前半は最初に完全な有効なボードを見つけることです(ランダムに埋められます!)それは非常に似ていますが、「反対方向」に動作します:
空のボードから始めます。
空きセルの1つに乱数を追加します(セルはランダムに選択され、SuDoKuルールに従ってこのセルに有効な番号のリストからランダムに選択されます)。
バックトラッキングソルバーを使用して、現在のボードに少なくとも1つの有効なソリューションがあるかどうかを確認します。そうでない場合は、ステップ2を元に戻し、別の番号とセルで繰り返します。このステップは完全に有効なボードをそれ自体で生成する可能性がありますが、それらは決してランダムではありません。
ボードが数字で完全に満たされるまで繰り返します。
チートできます。解決可能な既存の数独ボードから始めて、それをいじってみましょう。
3つの3x3ブロックの任意の行を他の行と交換できます。 3つの3x3ブロックの任意の列を別の列と交換できます。各ブロック行またはブロック列内で、単一の行と単一の列を交換できます。最後に、順列がボード全体で一貫している限り、塗りつぶされた位置に異なる数字があるように、数字を並べ替えることができます。
これらの変更によって解決可能なボードが解決不能になることはありません。
P = NPでない限り、1つの解だけで一般的な数独問題を生成する多項式時間アルゴリズムはありません。
修士論文で、矢藤貴之は The Another Solution Problem (ASP)を定義しました。ここでは、問題と何らかの解決策が与えられた場合、その問題の別の解決策を見つけるか、存在しないことを示すことが目標です。次にYatoは、ASP完全性、別の解決策を見つけるのが難しい問題を定義し、SudokuがASP完全であることを示しました。彼はまた、ASP完全性がNP困難性を意味することを証明しているため、任意のサイズの数独ボードを許可する場合、生成したパズルに一意の解があるかどうかをチェックする多項式時間アルゴリズムがないことを意味します(P = NP)。
高速アルゴリズムへの期待を台無しにしてすみません!
一般的なソリューションを提供するのは簡単ではありません。特定の種類の数独を生成するには、いくつかのことを知っておく必要があります。たとえば、9個以上の空の9番号グループ(行、3x3ブロックまたは列)で数独を構築することはできません。単一ソリューションの数独の最小指定数(つまり「手がかり」)は17であると考えられていますが、この数独の数の位置は、私が間違っていなければ非常に具体的です。数独の手がかりの平均数は約26であり、定かではありませんが、26になるまで完成したグリッドの数を終了し、それらを対称的な方法で残すと、有効な数独を持つことができます。一方、完成したグリッドの数字をランダムに終了し、OKが表示されるまでCHECKERまたは他のツールでテストすることができます。
古典的な数独パズルを作成する方法は次のとおりです(数独パズルは唯一の解決策です。事前に入力された正方形は、中央の正方形R5C5を中心に対称です)。
1)完全なグリッドから始めます(グループ入力と循環シフトを使用して簡単に取得します)
2)残りの手がかりを使用してクリアされた正方形を推測できる場合、2つの対称正方形から数を削除します。
3)すべての番号がチェックされるまで(2)を繰り返します。
この方法を使用すると、プログラミングの有無にかかわらず、非常に簡単な数独パズルを作成できます。この方法を使用して、より難しい数独パズルを作成することもできます。 YouTubeで「古典的な数独を作成する」を検索して、ステップバイステップの例をご覧ください。
解決策は2つの部分に分けられます。
A。番号パターンの生成6,000億
B。マスキングパターンの生成〜7e23の組み合わせ
A)[〜#〜] no [〜#〜]バックトレースまたはテストに費やした時間で一意の組み合わせを生成できる最速の方法であるNumberパターン
ステップ1.既に存在するマトリックスを選択します。コンピューティングデバイスまたはソルバーの助けを借りずに人間が簡単に作成できるため、以下のマトリックスを選択しました。
最初の行は昇順の数字です
2番目の行も昇順ですが、4から開始してロールアラウンドします
3行目も昇順ですが、7から開始してロールアラウンドします
行4,5,6:3つのセル列を右上の列-2 5 8に置き換え、最後の列の3x3セル内でロールします
行7,8,9:3つのセル列を右上の列-3 6 9に置き換え、最後の列の3x3セル内でロールします
1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 3 1 5 6 4 8 9 7
5 6 4 8 9 7 2 3 1
8 9 7 2 3 1 5 6 4
3 1 2 6 4 5 9 7 8
6 4 5 9 7 8 3 1 2
9 7 8 3 1 2 6 4 5
ステップ2.数字をシャッフルし、他のすべてのセルに置き換えます
ステップ3.列1、2、および3をランダムに再配置します
ステップ4.列4、5、6をランダムに並べ替えます
ステップ5.列7、8、および9をランダムに再配置します
ステップ6.行1、2、3をランダムに再配置します
ステップ7.行4、5、6をランダムに再配置します
ステップ8.行7、8、および9をランダムに再配置します
ステップ9.サイズ9x3の3つの列グループにランダムに再配置します
ステップ10.サイズ3x9の3つの行グループにランダムに再配置します
出来上がり...
5 8 3 1 6 4 9 7 2
7 2 9 3 5 8 1 4 6
1 4 6 2 7 9 3 8 5
8 5 2 6 9 1 4 3 7
3 1 7 4 2 5 8 6 9
6 9 4 8 3 7 2 5 1
4 6 5 9 1 3 7 2 8
2 3 1 7 8 6 5 9 4
9 7 8 5 4 2 6 1 3
B)Masking Patternには、ソルバーアルゴリズムが必要です。すでに非常にユニークな数値グリッドがあります(これも解決されます!)これにより、ソルバーを使用する際のパフォーマンスが向上します
ステップ1:81の中から15のランダムな場所を選択することから始めます。
ステップ2:ソルバーに固有のソリューションがあるかどうかを確認します
ステップ3:ソリューションが一意でない場合は、追加の場所を選択します。ユニークなソリューションが見つかるまでステップ2と3を繰り返します
これにより、非常にユニークで高速な数独ボードが得られます。
また、一意性を明示的に確認する必要があると思います。 17未満のギブしか与えられていない場合、ユニークなソリューションは非常にありそうにありません:まだ見つかっていませんが、存在するかどうかはまだ明確ではありません。)
ただし、独自のバックトラッキングアルゴリズムを作成するのではなく、SATソルバーを使用することもできます。そうすれば、解決策を見つけるのがどれほど難しいかをある程度調整できます。SATソルバーが使用する推論規則を制限すると、パズルを簡単に解決できるかどうかを確認できます。 「SATで数独を解く」だけを検索してください。