首先,對於數獨的隨機生成終盤,是肯定會用到隨機函式的,我的基礎隨機數的取法,採用了基本的線性同餘法,取一次種。
我在本文中想分析的是乙個隨機打亂函式。在寫隨機生成數獨終盤的時候,有乙個不可避免的問題:如何隨機的生成乙個1~9的排列,或者如何將n個數隨機打亂形成新的序列(隨機性越強越好,速度越快越好)。
首先,最容易想到的方法莫過於直接取乙個1~n的隨機數。這時候有兩種做法:①將第乙個數放入該位置,②將該位置的數放入第乙個格仔。這兩種方法其實沒有本質上的區別(至於隨機取乙個數放入隨機的位置也沒有區別),所以在之後我都預設用第一種方法。但對於本問題來說這與平時的取隨機數不同,在第乙個數取完就會減少乙個格仔,所以在填入數的時候需要判斷該格仔是否已經有數,如果有則需要重新取隨機數再重複上述過程。
對於隨機打亂乙個已知的序列,還有這樣一種做法:每次取兩個隨機數,然後交換該位置的兩個數。這樣的方法乍一看還挺巧妙,但是仔細分析,這種方法需要大量的交換位置。而且需要足夠的交換次數才能保證隨機性。在第一種做法中,由於取到的隨機數的位置可能有數,導致失敗。所以為了保證每次都成功,由於每次減少了乙個可取位置,所以取隨機數的範圍也縮小乙個。在每次取完隨機數後n後,尋找第n個不為空的格仔將數順序的填進去。
第一種方法中,需要大量的取隨機數,所以我在考慮通過減少取隨機數的次數加快效率。最終我得到了一種只需要取乙個隨機數的方法,但是實際上又回到了上一種方法。不過我還是記錄了這種方法,因為它還是挺有趣的。
將0~n-1的數按不同的順序依次排列,一共有n!種不同的取法,所以,在0~n!-1內任取乙個數就能確定一種唯一的0~n-1的序列。在經過研究後我得到了一種方法:設最初取得的數為x,則
第一位0的位置為:[x/(n-1)!](x=0~n-1)
然後讓x=x-第一位*(n-1)!
第二位1的位置為:[x/(n-2)!](x=0~n-2)
上面的意思就是消除第一位的位權影響;將x看成乙個n位數,第一位位權為(n-1)!,第二位為(n-2)!,……,倒數第二位為1!,最後一位為0!(因為最後一位沒有選擇了)。所以第一位有n!/(n-1)!=n種選擇,第二位有(n-1)!/(n-2)!=n-1種選擇,……,倒數第二位有2!/1!=2種,最後一位有1!/0!=1種。這樣通過每一位有不同的位權,就能在n!中確定乙個唯一的序列。
以4為例:4!=24
對於第一位:0~23
0~5——0
6~11——1
12~17——2
18~23——3
對於第二位:在減去第一位*位權之後,取值範圍為0~5,下同理
0~1——0
2~3——1
4~5——2
對於第三位:0~1
0——0
1——1
對於最後一位:0
0——0(唯一的選擇)
所以假如x=19,則可得到3010的序列,轉化一下,則對於0123這四個數的排列:
第一位為3:得到***0
第二位為0:得到1xx0
第三位為1:得到1x20
第四位為0:得到1320
最終結果為1320。
所以這種方法還是如同第三種方法一樣,雖然只取了一次隨機數,但是內部過程與其完全相同,甚至轉化的過程更費時間。但是,這確實是乙個有效的由n!確定一種n個數唯一排列的方法。
在經過一些思考之後,我得到了這種方法。這種方法還是類似第三種方法,每次取乙個隨機數。但是在取完隨機數之後,便有了不同的做法。我先判斷這個隨機數的這一位是否有值,如果沒有則填入,如果有則給該值加1模9,繼續判斷下一位是否有值。通過這樣,就避免了多次取隨機數,每個隨機數都有價值,保證隨機性,接下來的雜湊過程則保證了一定能找到乙個空位置。不過後來經過測試,發現這樣的隨機性有些差,經常出現一排數從小到大有序排列。這肯定是雜湊的值為1的問題了。就在這時,我發現,9這個數有些特殊,雜湊值非常多,124578都可以。所以我一一測試,發現7的效果比較好。但這時候又碰到問題了,如果所需打亂的陣列的大小不是9呢?我當初這個函式設計出來是打算復用的。這時候我突然想到,我能不能把每個數適合的雜湊值存進陣列裡面,然後一一呼叫呢?因為本題的規模最大只可能有9或者9以下的陣列。然後又順理成章的想到,我能不能每次都用不同的雜湊值呢?我又不需要再次查詢,我只需要保證每次都找到空格子。所以這時我的最終的版本就出爐了。
int hashlist[10][7] =
;上面的陣列每行的第一位存的都是該數字的有效雜湊值個數,然後在每次找有效位址時隨機取乙個雜湊值(當然,這個值在一次查詢成功前不能變化,不能在裡面繼續取隨機,我犯過一次這樣的錯誤導致死迴圈)。
這種方法目測查詢長度是低於第三種方法的,但是沒有經過測試。
中隨機打亂序列的函式 在EXCEL中隨機函式的利用
對於資料處理而言,隨機資訊的處理是非常重要的一部分,什麼是隨機數呢?隨機數是專門的隨機試驗的結果。在統計學的不同技術中需要使用隨機數,比如在從統計總體中抽取有代表性的樣本的時候,或者在將實驗動物分配到不同的試驗組的過程中等等。產生隨機數有多種不同的方法。這些方法被稱為隨機數發生器。隨機數最重要的特性...
數獨的隨機終盤生成函式設計
首先,我採用的策略是隨機生成終盤,而不是由乙個終盤排列組合出100w個 所以我又得滿足隨機性與時間的要求了。在動手前,我去網上搜了一些數獨終盤的生成函式,發現大體上有兩種演算法 1.每格都在可能的數中隨機生成,如果碰見沒數可填的地方,就把該行或者是更多的指定的格仔刪除,再隨機的跑一遍。每格地方都設定...
python 數獨 Python中的數獨檢查器
我正在嘗試用python建立乙個數獨檢查器 ill formed 5,3,4,6,7,8,9,1,2 6,7,2,1,9,5,3,4,8 1,9,8,3,4,2,5,6,7 8,5,9,7,6,1,4,2,3 4,2,6,8,5,3,7,9 7,1,3,9,2,4,8,5,6 9,6,1,5,3,7...