數獨的隨機終盤生成函式設計

2021-08-18 21:22:55 字數 1207 閱讀 9661

首先,我採用的策略是隨機生成終盤,而不是由乙個終盤排列組合出100w個;

所以我又得滿足隨機性與時間的要求了。

在動手前,我去網上搜了一些數獨終盤的生成函式,發現大體上有兩種演算法:

1.每格都在可能的數中隨機生成,如果碰見沒數可填的地方,就把該行或者是更多的指定的格仔刪除,再隨機的跑一遍。每格地方都設定次數上限,如果達到了這個上限,就全部推倒重來;

2.直接採用遞迴,每格格子都用dfs求解;

簡單分析一下兩種的利弊:第一種方法確實保證了隨機性,但是生成成功乙個終盤還是很大程度上靠概率的。可能是他們在寫隨機生成數獨的時候已經透徹的分析了這樣做的成功率才這樣做的,不然這種方法太不穩定;第二種方法很穩定,每次一定都能成功生成終盤,但是這個時間和隨機性都無法保證,尤其是如果每次dfs的搜尋都按123456789來的話。

所以我最終採用了兩者折中的方法,在保證能生成成功的基礎下,多隨機生成一些數,然後用dfs去搜尋剩下的點,找到乙個可行解。當然,最終這個找到可行解的概率也要保證盡可能的大。

這個函式的設計其實是全憑個人的喜好的,所以我大概說一下我的設計過程:

首先我選擇了每次生成棋盤中的所有的乙個數的做法(比如第一次,生成9個1,當然這些1都是放在滿足數獨規則的位置上的)。在經過許多測試後,我發現這個方法不太穩定,在生成第四個數的時候就有失敗的概率,大於五的概率就已經很低了,後面用dfs搜尋終盤的成功率也不高;

接著我就選擇了逐行生成。首先,第一行是可以完全隨機的,但在第二行,如果簡單的用取乙個能填的隨機數的方法失敗率有接近50%。在分析過後發現,只有把第一行的789三個數全部放入第二行的前6個格仔中才會成功,而如果全部隨機的化,成功率只有52.5%(通過概率算出來的)。所以我手動的把這789三個數放入了第二行的前六個格中(為了保證成功率)。在第三行時,可以發現,取完全隨機的成功率為100%,這個也不難分析,在第三行時,123,456,789列都相當於只受九宮格的影響,所以隨機的取,必定成功。

本來我覺得隨機生成前三行已經夠了,但轉念一想,我已經發現了第一行到第二行得手動放789三個數的規律,為何不按相同的規則生成123列呢?道理相同,我按照上面的方法又寫了生成4,7號九宮格的**。

接下來的4個九宮格,我嘗試了生成其中乙個九宮格(它們四個是等價的),但是在生成後搜尋成功率只有80%,生成過程不搜尋也很麻煩,所以我就放棄了。

最終我的生成策略為:隨機生成前三行和前三列(也就是12347號九宮格),剩下的4個九宮格用dfs搜尋得到可行解。

這樣做我用10w組做過測試,生成的成功率為100%。

求助 生成乙個16 16數獨終盤

我想在一秒內生成乙個16 16數獨的終盤。終盤就是16 16都填滿了,又符合每行每列每宮包含1,2,16這些數 當然是隨機生成,如果構造乙個我1ms就能造乙個,還能造一堆。就是說隨機生成乙個終盤 這裡不作嚴格要求 生成的那乙個終盤是理論上有可能的任乙個 不需要如此嚴格的要求。只要1m內能生成乙個隨機...

數獨中的隨機打亂函式

首先,對於數獨的隨機生成終盤,是肯定會用到隨機函式的,我的基礎隨機數的取法,採用了基本的線性同餘法,取一次種。我在本文中想分析的是乙個隨機打亂函式。在寫隨機生成數獨終盤的時候,有乙個不可避免的問題 如何隨機的生成乙個1 9的排列,或者如何將n個數隨機打亂形成新的序列 隨機性越強越好,速度越快越好 首...

利用隨機函式生成隨機數

給定乙個rand 可以產生從0到rand max的隨機數,其中 rand max 很大 常見值 16位int能表示的最大整數32767 寫出利用rand 生成 a,b 中任意整數的函式,其中a 0,b rand max,且b a 分析 這是在程式設計工作最常見的隨機函式的應用,在這裡做乙個起點再合適...