我正在尝试创建制作数独的程序。但是,当我尝试让程序将数字随机放置时,它并不会使用每个位置。
我尝试将rand();
与srand(time(0));
一起使用
和<random>
中的随机数生成器。
在构造函数中,我使用以下代码:
mt19937_64 randomGeneratorTmp(time(0));
randomGenerator = randomGeneratorTmp;
uniform_int_distribution<int> numGetterTmp(0, 8);
numGetter = numGetterTmp;
虽然我有randomGenerator
和numGetter
变量,所以我可以在数独对象的另一个函数中使用它们。
这是我使用随机数的功能:
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
仅显示程序尝试放置的位置。
并且大多数领域都经过了数百万次尝试,而其他领域则没有尝试过
我认为随机数在使用每个数字组合之前都会重复出现,但是我不知道自己在做什么错。
答案 0 :(得分:0)
不要期望随机数在矩阵上具有均匀分布-无法保证它们会如此。这就像有一个例程从卡组中随机生成卡,然后等到看到所有52个值-您可能要等待很长时间才能获取每张卡。
尤其如此,因为“随机”数实际上是由伪随机数生成器生成的,伪生成器通常利用将非常大的数相乘并添加任意常数的方法。取决于算法,这可能会以无法预料的方式聚集。
如果我可以提一个建议:创建一个所有可能的矩阵位置的数组,然后重新排列该数组。这样,纸牌混洗算法便可以确保您覆盖了纸牌中的所有卡,这就是您遇到的相同问题。
对于随机播放,请在数组中生成两个随机位置并交换值-重复多次以获得适当的随机结果。 (由于您的数组限制为9x9,因此我可能会改组一个整数0..80的数组:为每个int提取列和行,并分别带有/ 9和%9)。
答案 1 :(得分:0)
我编写了一个简单的程序,该程序应该与您的代码等效,并且可以正常运行:
#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次尝试,这是统计平均值。
您很可能在代码中存在错误。我不确定在哪里,因为您不会显示所有代码。