2016-06-08 14 views
7

मैं सी के साथ एक wxWidget आवेदन बना रहा हूं उत्पादन नहीं करता है ++ जहां कार्यक्रम के शुरू में मैं अनुप्रयोग विंडो इस तरह यादृच्छिक रंग के साथ पिक्सल शामिल करना चाहते हैं:कॉलिंग एक यादृच्छिक संख्या उत्पन्न सदस्य समारोह पूरी तरह से यादृच्छिक संख्या

Random coloured pixels

ऊपर आवेदन में वहाँ 3600 पिक्सल (60 x 60) हैं और मैं छवि में पिक्सेल से ऊपर पल में उत्पन्न कर रहे हैं के लिए 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 -object तस्वीर में एक पिक्सेल का प्रतिनिधित्व करता है (आरजीबी मानों के साथ सदस्य सरणी विशेषता के रूप में)। इस somNode -class में प्रत्येक somNode अपने स्वयं के यादृच्छिक आरजीबी रंग का निर्माण करते समय uniform_int_distribution का उपयोग करके मेरे पास एक सदस्य फ़ंक्शन है। इस समारोह जो प्रत्येक 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); 
    } 
} 

सदस्य सरणी somNode की आरजीबी-मूल्य का प्रतिनिधित्व करता। अब जब मैं इस "som ग्रिड" बनाने कि मैं क्या (3600 पिक्सल 3600 somNode रों के अनुरूप) मैं निम्नलिखित कोड का उपयोग ऊपर छवि में है (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 सदस्य फ़ंक्शन rand_node_colour कहा जाता है जिसे आरजीबी-मान बनाता है।

जब हालांकि मैं बजाय एक मैं पर इस्तेमाल के लिए इस कोड को लागू पहले मैं इस परिणाम मिलता है:

enter image description here

आप देख सकते हैं एक स्पष्ट पैटर्न है कि वहाँ तो कुछ गलत यहाँ जा रहा है। मेरा सवाल है: यादृच्छिक संख्या पीढ़ी में क्या हो रहा है जब somNodes बनाए जाते हैं? यह ऊपर दिए गए कोड के समान परिणाम क्यों नहीं उत्पन्न करता है?

पीएस यहाँ 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); 
    } 
} 
+0

क्या आप 'random_colors' या' rand_node_colour' कई बार कॉल करते हैं? यदि आप इसे जल्दी से करते हैं तो एकाधिक कॉल समान बीज मान का उपयोग कर सकते हैं। –

+0

हाय @ जोचिमपिलबोर्ग हाँ, हर बार जब 'somNode' बनाया जाता है तो मैं' rand_node_colour' कहता हूं। 'SomNode' कन्स्ट्रक्टर पर एक नज़र डालें। मेरा विचार था कि प्रत्येक निर्माण में नोड के लिए यादृच्छिक रंग बनाएं। मैं देखता हूं ... मैं इसे कैसे ठीक कर सकता हूं? :) – jjepsuomi

+0

जीन बीज। निर्माण पर केवल एक बार, अधिमानतः 'std :: random_device' का उपयोग कर। एक साधारण उदाहरण देखें [यहां] (http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution)। – vsoftco

उत्तर

6

यहां मुद्दा यह है कि आप लगातार पुन: बनाने और rand_node_colour में यादृच्छिक संख्या जनरेटर बीज है। आप इसे एक तंग पाश में बुलाते हैं ताकि आप एक ही समय प्राप्त कर सकें जिसका अर्थ है कि बीज समान होगा और इसका मतलब है कि उत्पन्न यादृच्छिक संख्या समान होगी।

आपको एक बार जेनरेटर बीज करना है और उसके यादृच्छिक आउटपुट का उपयोग करना जारी रखना है। आपको कोड को ठीक करने का एक आसान तरीका यह है कि इसे 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); 
    } 
} 
+0

बढ़िया! उसने ऐसा किया और अब मैं समझता हूं क्यों। धन्यवाद =) – jjepsuomi

+0

@jjepsuomi कोई समस्या नहीं। मदद करने में खुशी। – NathanOliver

+0

इसके अलावा, मुझे यह ध्यान रखना होगा कि 'default_random_engine' विभिन्न प्लेटफार्मों पर अलग-अलग जेनरेटर के लिए जा रहा है और एलसीजी जैसे कुछ उपपर जनरेटर होने की संभावना है। स्पष्ट रूप से कुछ ठोस जनरेटर का उपयोग करने के इरादे से स्पष्ट करना बेहतर है। –

संबंधित मुद्दे