Вызов случайного числа, генерирующего функцию-член, не производит полностью случайных чисел
Я создаю приложение wxWidget с C++, где в начале программы я хочу, чтобы окно приложения содержало пиксели со случайными цветами, такими как:
в приведенном выше приложении есть 3600 пикселей (60 x 60), и я дал каждому пикселю случайный цвет RGB с помощью uniform_int_distribution
цвета для пикселей на изображении выше генерируются в данный момент с помощью следующей функции в моем коде:
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
- класс у меня есть функция-член с помощью uniform_int_distribution
давать при построении каждого somNode
свой собственный случайный цвет RGB. Это функция, которая создает случайный цвет для каждого 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);
}
}
the nodeWeights
массив элементов представляет RGB-значение somNode
. Теперь, когда я создаю эту "сом-сетку", что у меня есть на изображении выше (3600 пикселей, соответствующих 3600 somNode
s) Я использую следующий код (взгляните на 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
s, когда я их построить. Когда каждый узел построен somNode
функции-члена rand_node_colour
вызывается, который создает RGB-значение.
когда, Однако, я реализую этот код вместо того, который я использовал сначала, я получаю этот результат:
вы можете видеть, что есть четкая картина, так что что-то здесь не так. Мой вопрос: что происходит в генерации случайных чисел, когда создаются сомноды? Почему он не дает того же результата, что и код, который я использовал выше?
P. S. Вот это 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);
}
}
1 ответов
проблема здесь в том, что вы постоянно воссоздаете и сеете генератор случайных чисел в rand_node_colour
. Вы называете это в узкой петле, так что вы можете получить то же самое время, что означает, что семя будет таким же, и это означает, что случайные числа будут одинаковыми.
что вам нужно сделать, это семя генератор один раз, а затем продолжать использовать его случайный выход. Простой способ исправить код - сделать его static
в функции sos он инициализируется только один раз и каждый последующий вызов к функции будет продолжаться дальше вместо того, чтобы запускать генератор во всем. Если мы это сделаем, код станет
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);
}
}