Sto creando un'applicazione wxWidget con C++, dove all'inizio del programma che voglio la finestra dell'applicazione per contenere pixel con colori casuali come questo:Chiamare una funzione membro numero casuale generando non produce numeri del tutto casuali
Nell'applicazione sopra ci sono 3600 pixel (60 x 60) e che hanno dato ogni pixel di un colore RGB casuale utilizzando uniform_int_distribution
i colori dei pixel nell'immagine sopra sono generati al momento utilizzando la seguente funzione nel mio codice:
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);
}
}
}
Lo faccio dando a questa funzione una tabella con dimensioni 3600 x 3 e questa funzione inserirà i valori per i colori.
In questo modo, tuttavia, non è quello che voglio. Quello che voglio è creare una classe chiamata somNode
dove ogni oggetto somNode
rappresenta un pixel nell'immagine (con valori RGB come attributo matrice membro). In questa classe somNode
ho una funzione membro che usa uniform_int_distribution
per dare quando viene costruito ogni somNode
proprio colore RGB casuale. Questa è la funzione che crea il colore casuale per ogni 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);
}
}
matrice membro rappresenta il RGB valore del somNode
. Ora, quando ho creare questa immagine "som-grid" quello che ho nell'immagine sopra (i 3600 pixel corrispondenti a 3600 somNode
s) Io uso il seguente codice (date un'occhiata alla SOM-costruttore):
#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()
{
}
Quindi ho uno vector<somNode> somGrid
dove spingo tutti questi 3600 somNode
quando li costruisco. Quando viene creato ciascun nodo, viene chiamata la funzione membro che crea il valore RGB.
Quando però a implementare questo codice al posto di quello che ho usato in un primo momento ho ottenere questo risultato:
Si può vedere che c'è un modello chiaro in modo da qualcosa sta andando male qui. La mia domanda è: cosa sta succedendo nella generazione di numeri casuali quando vengono creati i somNodes? Perché non produce lo stesso risultato del codice che ho usato sopra?
P.S. qui è la 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);
}
}
Chiama 'random_colors' o' rand_node_colour' più volte? Se lo fai rapidamente, più chiamate potrebbero utilizzare lo stesso valore di inizializzazione. –
Salve @JoachimPileborg si, ogni volta che viene costruito un 'somNode', chiamo' rand_node_colour'. Dai un'occhiata al costruttore 'somNode'. La mia idea era di creare in ogni costruzione un colore casuale per il nodo. Capisco ... come posso risolvere questo problema? :) – jjepsuomi
Sementi il gen. solo una volta alla costruzione, preferibilmente usando un 'std :: random_device'. Vedi un semplice esempio [qui] (http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution). – vsoftco