簡體   English   中英

調用隨機數生成成員函數不會產生完全隨機的數字

[英]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個somNodesomNode其中。 構造每個節點時, 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.

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