[英]Calling a random number generating member function doesn't produce entirely random numbers
我正在使用C ++創建一個wxWidget應用程序,在程序開始時我希望應用程序窗口包含具有隨機顏色的像素,如下所示:
在上面的應用程序中有3600像素(60 x 60),我通過使用uniform_int_distribution
給每個像素一個隨機的RGB顏色
使用我的代碼中的以下函數生成上圖中像素的顏色:
void random_colors(int ctable[][3], int n)
{
// construct a trivial random generator engine from a time-based seed:
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator (seed);
std::uniform_int_distribution<int> distribution(0,255);
for(int i=0; i<n; i++)
{
for(int j=0; j<3; j++)
{
ctable[i][j] = distribution(generator);
}
}
}
我這樣做的方法是給這個函數一個尺寸為3600 x 3的表,這個函數將填充顏色的值。
然而這種方式不是我想要的。 我想要的是創建一個名為somNode
的類,其中每個somNode
代表圖片中的一個像素(RGB值作為成員數組屬性)。 在這個somNode
-class中,我有一個使用uniform_int_distribution
的成員函數來給每個somNode
構造它自己的隨機RGB顏色。 這是為每個somNode
創建隨機顏色的somNode
:
void rand_node_colour(int nodeWeights[])
{
// construct a trivial random generator engine from a time-based seed:
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator (seed);
std::uniform_int_distribution<int> distribution(0,255);
for(int i=0; i<3; i++)
{
nodeWeights[i] = distribution(generator);
}
}
所述nodeWeights
構件陣列表示的RGB值somNode
。 現在,當我創建這個“som-grid”時,我在上面的圖片(對應於3600 somNode
的3600像素)中使用以下代碼(看一下som構造函數):
#include "somNode.h"
#include <vector>
class som
{
public:
double learning_rate;
std::vector<somNode> somGrid;
public:
som(double lrate);
void epoch();
void trainOnce();
};
/*
* Initialize the som grid
*/
som::som(double lrate)
{
learning_rate = lrate;
// Create the som grid
for(int i=0; i<60; i++)
{
for(int j=0; j<60; j++)
{
int xL = j*10;
int xR = (j+1)*10;
int yT = i*10;
int yB = (i+1)*10;
somGrid.push_back(somNode(xL, xR, yB, yT));
}
}
}
// Train som by one epoch
void som::epoch()
{
}
// Train som by one color
void som::trainOnce()
{
}
所以我有一個vector<somNode> somGrid
,我在構建它們時將所有這3600個somNode
推somNode
其中。 構造每個節點時, somNode
成員函數rand_node_colour
,它創建RGB值。
然而,當我實現此代碼而不是我最初使用的代碼時,我得到了這個結果:
你可以看到有一個明確的模式,所以這里出了問題。 我的問題是:創建somNode時隨機數生成會發生什么? 為什么它不會產生與我上面使用的代碼相同的結果?
PS這里是somNode.cpp
:
#include <random>
#include <iostream>
#include <chrono>
#include<cmath>
void rand_node_colour(int nodeWeights[]);
/*
* This class represent a node in the som-grid
*/
class somNode
{
public:
// Weight of the node representing the color
int nodeWeights[3];
// Position in the grid
double X, Y;
// corner coorinates for drawing the node on the grid
int x_Left, x_Right, y_Bottom, y_Top;
public:
// Constructor
somNode(int xL, int xR, int yB, int yT);
void editWeights(int r, int g, int b);
double getDistance(int r, int g, int b);
};
somNode::somNode(int xL, int xR, int yB, int yT)
{
// Set the corner points
x_Left = xL;
x_Right = xR;
y_Bottom = yB;
y_Top = yT;
// Initialize random weights for node
rand_node_colour(nodeWeights);
// Calculate the node's position (center coordinate)
X = x_Left + (double)((x_Right - x_Left)/double(2));
Y = y_Bottom + (double)((y_Top - y_Bottom)/double(2));
}
void somNode::editWeights(int r, int g, int b)
{
nodeWeights[0] = r;
nodeWeights[1] = g;
nodeWeights[2] = b;
}
double somNode::getDistance(int r, int g, int b)
{
return sqrt(pow(nodeWeights[0]-r, 2) + pow(nodeWeights[1]-g, 2) + pow(nodeWeights[2]-b, 2));
}
void rand_node_colour(int nodeWeights[])
{
// construct a trivial random generator engine from a time-based seed:
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator (seed);
std::uniform_int_distribution<int> distribution(0,255);
for(int i=0; i<3; i++)
{
nodeWeights[i] = distribution(generator);
}
}
這里的問題是你不斷在rand_node_colour
重建和播種隨機數生成器。 你可以在一個緊密循環中調用它,這樣你就可以獲得相同的時間,這意味着種子將是相同的,這意味着生成的隨機數將是相同的。
您需要做的是將生成器播種一次,然后繼續使用其隨機輸出。 修復代碼的一種簡單方法是在函數sos中使其static
,它只被初始化一次,並且對函數的每次后續調用都將繼續,而不是全部啟動生成器。 如果我們這樣做,代碼就變成了
void rand_node_colour(int nodeWeights[])
{
// construct a trivial random generator engine from a time-based seed:
static std::default_random_engine generator (std::chrono::system_clock::now().time_since_epoch().count());
std::uniform_int_distribution<int> distribution(0,255);
for(int i=0; i<3; i++)
{
nodeWeights[i] = distribution(generator);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.