簡體   English   中英

數字的隨機生成無法正常工作

[英]Random generating of numbers doesn't work properly

我正在嘗試創建一個制作數獨的程序。 但是當我嘗試讓程序在隨機位置放置數字時,它不會使用每個位置。

我嘗試使用rand(); srand(time(0)); 和來自<random>隨機數生成器。

在構造函數中我使用這個:

mt19937_64 randomGeneratorTmp(time(0));
randomGenerator = randomGeneratorTmp;
uniform_int_distribution<int> numGetterTmp(0, 8);
numGetter = numGetterTmp;

雖然我有randomGeneratornumGetter變量,所以我可以在數獨對象的另一個函數中使用它們。 這是我使用隨機數的函數:

bool fillInNumber(int n){
     int placedNums = 0, tries=0;
     int failedTries[9][9];
     for(int dim1=0;dim1<9;dim1++){
         for(int dim2=0;dim2<9;dim2++){
             failedTries[dim1][dim2] = 0;
         }
     }

     while(placedNums<9){
         int dim1 = numGetter(randomGenerator);
         int dim2 = numGetter(randomGenerator);
         if(nums[dim1][dim2]==0){
             if(allowedLocation(n,dim1,dim2)){
                 nums[dim1][dim2] = n;
                 placedNums++;
             } else {
                 failedTries[dim1][dim2]++;
                 tries++;
             }
         }
         if(tries>100000000){
             if(placedNums == 8){
                 cout<< "Number: " << n << endl;
                 cout<< "Placing number: " << placedNums << endl;
                 cout<< "Dim1: " << dim1 << endl;
                 cout<< "Dim2: " << dim2 << endl;
                 printArray(failedTries);
             }
             return false;
         }
     }
     return true;
}

(數組failedTries只是告訴我程序嘗試了哪些位置。大多數字段已經嘗試了數百萬次,而其他字段則沒有一次)

我認為隨機生成只是在使用每個數字組合之前重復自己,但我不知道我做錯了什么。

不要指望隨機數在您的矩陣上具有均勻分布 - 不能保證它們會。 這就像有一個例程從一副牌中隨機生成卡片,然后等到您看到所有 52 個值 - 您可能需要等待很長時間才能獲得每張卡片。

尤其如此,因為“隨機”數實際上是由偽隨機數生成器生成的,偽隨機數生成器通常利用乘以一個非常大的數字並添加一個任意常數。 根據算法的不同,這可能會以意想不到的方式聚集。

如果我可以提出建議:創建一個包含所有可能矩陣位置的數組,然后對該數組進行洗牌。 這就是牌組洗牌算法能夠保證你將牌組中的所有牌都覆蓋的方式,這與你遇到的問題相同。

對於隨機播放,在數組中生成兩個隨機位置並交換值 - 重復盡可能多的次數以獲得適當的隨機結果。 (由於您的數組限制為 9x9,我可能會打亂一個整數數組 0..80:使用 /9 和 % 9 為每個整數提取列和行)。

我編寫了一個簡單的程序,它應該與您的代碼等效,並且可以正常運行:

#include <iostream>
#include <random>
#include <vector>

using namespace std;

int main()
{
    std::default_random_engine          engine;
    std::uniform_int_distribution<int>  distr(0,80);
    std::vector<bool>              vals(81,false);

    int attempts    = 0;
    int trueCount   = 0;
    while(trueCount < 81)
    {
        int newNum = distr(engine);
        if(!vals[newNum])
        {
            vals[newNum] = true;
            trueCount++;
        }

        attempts++;
    }

    std::cout << "attempts: " << attempts;

    return 0;
}

通常它會打印大約 400 次嘗試,這是統計平均值。

您的代碼中很可能存在錯誤。 我不確定在哪里,因為您沒有顯示所有代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM