সি বা সি ++ এ সাধারণ বিতরণের পরে আমি কীভাবে সহজেই এলোমেলো সংখ্যা তৈরি করতে পারি?
আমি বুস্টের কোনও ব্যবহার চাই না।
আমি জানি যে নথ দৈর্ঘ্যে এ সম্পর্কে কথা বলছেন তবে এখনই তাঁর হাতে বই নেই।
সি বা সি ++ এ সাধারণ বিতরণের পরে আমি কীভাবে সহজেই এলোমেলো সংখ্যা তৈরি করতে পারি?
আমি বুস্টের কোনও ব্যবহার চাই না।
আমি জানি যে নথ দৈর্ঘ্যে এ সম্পর্কে কথা বলছেন তবে এখনই তাঁর হাতে বই নেই।
উত্তর:
নিয়মিত আরএনজি থেকে গাউসিয়ান-বিতরণ করা সংখ্যাগুলি উত্পন্ন করার জন্য অনেকগুলি পদ্ধতি রয়েছে ।
বক্স-মুলার রুপান্তর সাধারণভাবে ব্যবহার করা হয়। এটি সঠিকভাবে একটি সাধারণ বিতরণ সহ মানগুলি উত্পাদন করে। গণিত সহজ। আপনি দুটি (অভিন্ন) এলোমেলো সংখ্যা তৈরি করেন এবং সেগুলিতে একটি সূত্র প্রয়োগ করে আপনি দুটি সাধারণভাবে বিতরণ করা এলোমেলো নম্বর পান। একটিটি ফিরে আসুন এবং অন্যটিকে এলোমেলো সংখ্যার জন্য পরবর্তী অনুরোধের জন্য সংরক্ষণ করুন।
std::normal_distribution
যা গাণিতিক বিবরণ না নিয়ে আপনি যা চান ঠিক তা করে।
সি ++ 11 অফার std::normal_distribution
, যা আজ আমি যাব।
আরোহী জটিলতার জন্য এখানে কয়েকটি সমাধান রয়েছে:
0 থেকে 1 পর্যন্ত 12 টি অভিন্ন এলোমেলো সংখ্যার যোগ করুন এবং 6টি বিয়োগ করুন mean এটি একটি সাধারণ ভেরিয়েবলের গড় এবং মান বিচ্যুতির সাথে মেলে। একটি সুস্পষ্ট ত্রুটিটি হ'ল পরিসীমাটি to 6 এর মধ্যে সীমাবদ্ধ - সত্যিকারের সাধারণ বিতরণের মতো নয়।
বক্স-মুলার রূপান্তর। এটি উপরে তালিকাভুক্ত, এবং প্রয়োগ করা তুলনামূলকভাবে সহজ। তবে আপনার যদি খুব সুনির্দিষ্ট নমুনার প্রয়োজন হয় তবে সচেতন হন যে কিছু ইউনিফর্ম জেনারেটরগুলির সাথে মিলিত বক্স-মুলার রূপান্তরটি নেভ এফেক্ট 1 নামক একটি অনিয়মিততায় ভুগছে ।
সর্বোত্তম নির্ভুলতার জন্য, আমি ইউনিফর্মগুলি আঁকতে এবং সাধারণভাবে বিতরণ করা বৈকল্পিকগুলিতে পৌঁছানোর জন্য বিপরীতমুখী সাধারণ বন্টন প্রয়োগ করার পরামর্শ দিই। বিপরীত संचयी সাধারণ বিতরণের জন্য এখানে একটি খুব ভাল অ্যালগরিদম।
১. এইচআর ন্যাভ, "বহুগঠিত সংশ্লেষযুক্ত সিউডোর্যান্ডম সংখ্যার জেনারেটরগুলির সাথে বক্স-মুলার রূপান্তর ব্যবহার করার সময়," প্রয়োগিত পরিসংখ্যান, 22, 92-97, 1973
একটি দ্রুত এবং সহজ পদ্ধতি হ'ল কেবল সমানভাবে বিতরণ করা এলোমেলো সংখ্যার সংখ্যার যোগফল এবং তাদের গড় নেওয়া। কেন এটি কাজ করে তার পূর্ণ ব্যাখ্যার জন্য কেন্দ্রীয় সীমাবদ্ধ তত্ত্বটি দেখুন ।
আমি সৃষ্টি স্বাভাবিকভাবে বিতরণ র্যান্ডম সংখ্যা প্রজন্মের বেঞ্চমার্ক জন্য সি ++ ওপেন সোর্স প্রকল্প ।
এটি সহ বেশ কয়েকটি অ্যালগরিদমের সাথে তুলনা করে
cpp11random
সি ++ 11 এর std::normal_distribution
সাথে ব্যবহার করে std::minstd_rand
(এটি আসলে বাক্সে মুলার বক্স-মুলার রূপান্তরিত)।float
IMac Corei5-3330S@2.70GHz, ঝাঁকুনি 6.1, 64-বিটে একক-নির্ভুলতা ( ) সংস্করণের ফলাফল :
নির্ভুলতার জন্য, প্রোগ্রামটি নমুনাগুলির গড়, আদর্শ বিচ্যুতি, স্কিউনেস এবং কুরটোসিস যাচাই করে। দেখা গেছে যে 4, 8 বা 16 ইউনিফর্ম সংখ্যার যোগ করে সিএলটি পদ্ধতিতে অন্যান্য পদ্ধতিগুলির মতো ভাল কার্টোসিস নেই।
জিগগারেট অ্যালগরিদমের অন্যদের চেয়ে ভাল পারফরম্যান্স রয়েছে। তবে এটি সিমড সমান্তরালতার পক্ষে উপযুক্ত নয় কারণ এটিতে সারণী প্রদর্শন এবং শাখা দরকার। এসইএসই 2 / এভিএক্স নির্দেশিকা সেট সহ বক্স-মুলার জিগগারেট অ্যালগরিদমের সিমড নন সংস্করণের চেয়ে অনেক দ্রুত (x1.79, x2.99)।
অতএব, আমি সিমড নির্দেশাবলী সেটগুলির সাথে আর্কিটেকচারের জন্য বক্স-মুলার ব্যবহার করার পরামর্শ দেব এবং অন্যথায় জিগগ্র্যাট হতে পারে।
পিএস বেঞ্চমার্ক ইউনিফর্ম বিতরণ এলোমেলো সংখ্যা তৈরির জন্য একটি সহজ এলসিজি পিআরএনজি ব্যবহার করে। সুতরাং এটি কিছু অ্যাপ্লিকেশনগুলির জন্য পর্যাপ্ত নাও হতে পারে। তবে পারফরম্যান্সের তুলনাটি ন্যায়সঙ্গত হওয়া উচিত কারণ সমস্ত বাস্তবায়ন একই পিআরএনজি ব্যবহার করে, সুতরাং মানদণ্ডটি মূলত রূপান্তরের কার্যকারিতা পরীক্ষা করে।
এখানে কয়েকটি সিফারেন্সের ভিত্তিতে সি ++ উদাহরণ দেওয়া আছে। এটি দ্রুত এবং নোংরা, আপনি পুনরায় উদ্ভাবন এবং বুস্ট লাইব্রেরি ব্যবহার না করাই ভাল।
#include "math.h" // for RAND, and rand
double sampleNormal() {
double u = ((double) rand() / (RAND_MAX)) * 2 - 1;
double v = ((double) rand() / (RAND_MAX)) * 2 - 1;
double r = u * u + v * v;
if (r == 0 || r > 1) return sampleNormal();
double c = sqrt(-2 * log(r) / r);
return u * c;
}
ফলাফলগুলি পরীক্ষা করার জন্য আপনি কিউকিউ প্লট ব্যবহার করতে পারেন এবং এটি দেখতে পান যে এটি সত্যিকারের সাধারণ বিতরণকে কতটা ভাল করে তোলে (আপনার নমুনা 1..x র্যাঙ্ক করুন, সর্বমোট x এর গণনা অনুপাতগুলিতে র্যাঙ্কগুলি পরিণত করুন। কতগুলি নমুনা, জেড-মানগুলি পান এবং সেগুলি প্লট করুন Anর্ধ্বমুখী সরলরেখাই পছন্দসই ফলাফল)
ব্যবহার std::tr1::normal_distribution
।
Std :: tr1 নেমস্পেস বৃদ্ধির অংশ নয়। এটি সেই নেমস্পেস যা সি ++ টেকনিকাল রিপোর্ট 1 থেকে গ্রন্থাগার সংযোজনগুলি ধারণ করে এবং মাইক্রোসফ্ট সংকলক এবং জিসিসি, স্বাধীনভাবে উত্সাহদানের ক্ষেত্রে উপলব্ধ।
আপনি আধুনিক সি ++ সংকলকটিতে এইভাবে নমুনাগুলি তৈরি করেন।
#include <random>
...
std::mt19937 generator;
double mean = 0.0;
double stddev = 1.0;
std::normal_distribution<double> normal(mean, stddev);
cerr << "Normal: " << normal(generator) << endl;
generator
সত্যিই বীজযুক্ত দিতে হবে।
আপনি জিএসএল ব্যবহার করতে পারেন । এটি কীভাবে ব্যবহার করা যায় তা প্রদর্শনের জন্য কয়েকটি সম্পূর্ণ উদাহরণ দেওয়া হয়।
: একটি চেহারা আছে http://www.cplusplus.com/reference/random/normal_distribution/ । এটি সাধারণ বিতরণ উত্পাদন করার সবচেয়ে সহজ উপায়।
আপনি যদি সি ++ 11 ব্যবহার করেন তবে আপনি এটি ব্যবহার করতে পারেন std::normal_distribution
:
#include <random>
std::default_random_engine generator;
std::normal_distribution<double> distribution(/*mean=*/0.0, /*stddev=*/1.0);
double randomNumber = distribution(generator);
এলোমেলো সংখ্যা ইঞ্জিনের আউটপুট রূপান্তর করতে আপনি ব্যবহার করতে পারেন এমন আরও অনেক বিতরণ রয়েছে।
আমি http://www.mathworks.com/help/stats/normal-dist वितरण.html এ দেওয়া পিডিএফটির সংজ্ঞাটি অনুসরণ করেছি এবং এটি দিয়ে এসেছি:
const double DBL_EPS_COMP = 1 - DBL_EPSILON; // DBL_EPSILON is defined in <limits.h>.
inline double RandU() {
return DBL_EPSILON + ((double) rand()/RAND_MAX);
}
inline double RandN2(double mu, double sigma) {
return mu + (rand()%2 ? -1.0 : 1.0)*sigma*pow(-log(DBL_EPS_COMP*RandU()), 0.5);
}
inline double RandN() {
return RandN2(0, 1.0);
}
এটি সম্ভবত সেরা পদ্ধতির না হলেও এটি বেশ সহজ।
rand()
হওয়ায় ম্যাক্রো RANDU
একটি শূন্য প্রদান করলে ব্যর্থ হবে ।
cos(2*pi*rand/RAND_MAX)
, যেখানে আপনি গুন করেন (rand()%2 ? -1.0 : 1.0)
।
Comp.lang.c প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী তালিকা শেয়ার সহজেই তিনটি ভিন্ন উপায়ে একটি গসিয়ান ডিস্ট্রিবিউশনের সাথে র্যান্ডম সংখ্যা উৎপন্ন।
আপনি এটি একবার দেখে নিতে পারেন: http://c-faq.com/lib/ga Persian.html
বক্স-মুলার বাস্তবায়ন:
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <iostream>
using namespace std;
// return a uniformly distributed random number
double RandomGenerator()
{
return ( (double)(rand()) + 1. )/( (double)(RAND_MAX) + 1. );
}
// return a normally distributed random number
double normalRandom()
{
double y1=RandomGenerator();
double y2=RandomGenerator();
return cos(2*3.14*y2)*sqrt(-2.*log(y1));
}
int main(){
double sigma = 82.;
double Mi = 40.;
for(int i=0;i<100;i++){
double x = normalRandom()*sigma+Mi;
cout << " x = " << x << endl;
}
return 0;
}
বিপরীত संचयी স্বাভাবিক বিতরণের জন্য বিভিন্ন অ্যালগরিদম রয়েছে। পরিমাণগত অর্থের ক্ষেত্রে সর্বাধিক জনপ্রিয় http://chasethedevil.github.io/post/monte-carlo--inverse-cumulative-normal-dist वितरण/ এ পরীক্ষা করা হয়
আমার মতে, উইচুরা থেকে অ্যালগরিদম AS241 ছাড়া আর কিছু ব্যবহার করার মতো উত্সাহ নেই : এটি মেশিন যথার্থ, নির্ভরযোগ্য এবং দ্রুত। বোতলেনেকগুলি খুব কমই গাউসের এলোমেলো সংখ্যা জেনারেশনে।
তদ্ব্যতীত, এটি পদ্ধতির মতো জিগগুরাটের অপূর্ণতা দেখায়।
এখানে শীর্ষ উত্তর বক্স-মুলারের পক্ষে, আপনি সচেতন হওয়া উচিত যে এটির ঘাটতিগুলি রয়েছে। আমি উদ্ধৃত https://www.senderdirect.com/s ज्ञान/ article / pii/ S0895717710005935 :
সাহিত্যে, বক্স – মুলারকে কখনও কখনও প্রধানত দুটি কারণে কিছুটা নিকৃষ্ট বলে মনে করা হয়। প্রথমত, যদি কেউ একটি খারাপ লিনিয়ার কংগ্রেসনাল জেনারেটর থেকে সংখ্যায় বাক্স – মুলার পদ্ধতি প্রয়োগ করে তবে রূপান্তরিত নম্বরগুলি স্থানটির অত্যন্ত দরিদ্র কভারেজ সরবরাহ করে। সর্পিল লেজযুক্ত রূপান্তরিত সংখ্যার প্লটগুলি অনেকগুলি বইয়ে পাওয়া যায়, বিশেষত উল্লেখযোগ্যভাবে রিপলির ক্লাসিক বইয়ে, সম্ভবত তিনি এই পর্যবেক্ষণটি প্রথম করেছিলেন "
1) গ্রাফিকভাবে স্বজ্ঞাত উপায়ে আপনি গাউসিয়ান এলোমেলো সংখ্যা তৈরি করতে পারেন মন্টে কার্লো পদ্ধতির অনুরূপ কিছু ব্যবহার করে। আপনি সিতে আপনার সিউডো-এলোমেলো নম্বর জেনারেটরটি ব্যবহার করে গাউসিয়ান বক্ররেখার চারপাশে একটি বাক্সে একটি এলোমেলো পয়েন্ট তৈরি করতে পারবেন আপনি যদি গণনা করতে পারেন যে বিন্দুটি বিতরণের সমীকরণটি ব্যবহার করে গাউসিয়ান বিতরণটির ভিতরে বা নীচে রয়েছে। যদি সেই বিন্দুটি গাউসীয় বিতরণের মধ্যে থাকে তবে আপনি পয়েন্টটির x মান হিসাবে আপনার গাউসিয়ান এলোমেলো নম্বর পেয়েছেন।
এই পদ্ধতিটি নিখুঁত নয় কারণ প্রযুক্তিগতভাবে গাউসিয়ান বক্ররেখা অনন্তের দিকে চলে যায় এবং আপনি এমন একটি বাক্স তৈরি করতে পারেননি যা এক্স ডাইমেনশনে অনন্তের কাছে পৌঁছায়। তবে গুয়াসিয়ান বক্ররেখ খুব দ্রুত y এর মাত্রায় 0 পৌঁছেছে তাই আমি সে সম্পর্কে চিন্তা করব না। সিতে আপনার ভেরিয়েবলের আকারের সীমাবদ্ধতা আপনার নির্ভুলতার জন্য সীমাবদ্ধ কারণ হতে পারে of
২) আরেকটি উপায় হ'ল কেন্দ্রীয় সীমাবদ্ধ উপপাদ্যটি ব্যবহার করা যা এতে উল্লেখ করে যে যখন স্বাধীন র্যান্ডম ভেরিয়েবল যুক্ত হয়, তখন তারা একটি সাধারণ বিতরণ গঠন করে। এই উপপাদ্যকে মাথায় রেখে আপনি প্রচুর পরিমাণে স্বতন্ত্র এলোমেলো ভেরিয়েবল যুক্ত করে কোনও গাউসিয়ান এলোমেলো সংখ্যা আনুমানিক করতে পারেন।
এই পদ্ধতিগুলি সর্বাধিক ব্যবহারিক নয়, তবে আপনি যখন কোনও পূর্ববর্তী লাইব্রেরি ব্যবহার করতে চান না তখন তা প্রত্যাশা করা হয়। মনে রাখবেন এই উত্তরটি খুব কম বা কোনও ক্যালকুলাস বা পরিসংখ্যান অভিজ্ঞতার সাথে আসছে someone
মন্টে কার্লো পদ্ধতি
এটি করার সর্বাধিক স্বজ্ঞাত উপায় ব্যবহার করা। X, + X একটি উপযুক্ত পরিসর নিন। এক্স এর বৃহত্তর মানগুলির ফলে আরও সঠিক স্বাভাবিক বিতরণ হবে, তবে রূপান্তর করতে আরও বেশি সময় লাগে। ক। একটি র্যান্ডম নম্বর চয়ন করুন z- র এক্স বি -X মধ্যে। N(z, mean, variance)
এনটি গাউসির বিতরণ কোথায় হবে তার একটি সম্ভাব্যতার সাথে রাখুন । অন্যথায় বাদ দিন এবং পদক্ষেপে ফিরে যান (ক)।
আমি যা পেয়েছি তা একবার দেখুন।
এই গ্রন্থাগারটি জিগগারেট অ্যালগরিদম ব্যবহার করে।
কম্পিউটার হ'ল ডিটারমিনিস্টিক ডিভাইস। গণনায় কোনও এলোমেলোতা নেই। সিপিইউতে গাণিতিক ডিভাইস কিছু সংখ্যক সংখ্যক সমষ্টি সংখ্যার (সীমাবদ্ধ ক্ষেত্রে মূল্যায়ন সম্পাদন করা) এবং আসল যুক্তিযুক্ত সংখ্যার সীমাবদ্ধ সেটগুলির উপরে সমষ্টিকে মূল্যায়ন করতে পারে। এবং বিটওয়াইজ অপারেশনও করেছেন। ম্যাথ অসীম সংখ্যক পয়েন্ট সহ আরও দুর্দান্ত সেটগুলির সাথে [০.০, ১.০] নিয়ে একটি চুক্তি করে।
আপনি কিছু নিয়ামকের সাহায্যে কম্পিউটারের অভ্যন্তরে কিছু তার শুনতে পারেন, তবে এতে কি অভিন্ন বিতরণ হবে? আমি জানি না। তবে যদি ধরে নেওয়া হয় যে এটির সিগন্যালটি প্রচুর পরিমাণে স্বতন্ত্র এলোমেলো ভেরিয়েবলের মান সংগ্রহের ফলাফল হয় তবে আপনি প্রায় সাধারণ বিতরণ করা এলোমেলো ভেরিয়েবল পাবেন (এটি সম্ভাব্যতা তত্ত্বে প্রমাণিত হয়েছিল)
অ্যালগোরিদম নামে পরিচিত রয়েছে - সিউডো র্যান্ডম জেনারেটর। যেহেতু আমি সিউডো এলোমেলো জেনারেটরের উদ্দেশ্যটি এলোমেলোভাবে অনুকরণ করা। এবং গডনসের মানদণ্ডটি হ'ল: - অভিজ্ঞতাগত বিতরণকে রূপান্তরিত করা হয়েছে (কিছুটা অর্থে - পয়েন্টওয়াইজ, ইউনিফর্ম, এল 2) তাত্ত্বিক - র্যান্ডম জেনারেটরের কাছ থেকে আপনি যে মূল্যবোধগুলি পেয়েছেন তা আদর্শিক বলে মনে হয়। অবশ্যই এটি 'বাস্তব দৃষ্টিকোণ' থেকে সত্য নয়, তবে আমরা এটি সত্য বলে ধরে নিই।
জনপ্রিয় পদ্ধতিগুলির মধ্যে একটি - আপনি ইউনিফর্ম বিতরণে 12 টি আইআরভিএ সংশ্লেষ করতে পারেন .... তবে ফিউরিয়ার ট্রান্সফর্ম, টেলর সিরিজের সাহায্যে কেন্দ্রীয় সীমাবদ্ধ তাত্ত্বিকতার সময় সত্য কথা বলতে, এটি এন -> + ইনফ অনুমানগুলি কয়েকবার হওয়া প্রয়োজন। সুতরাং উদাহরণস্বরূপ তাত্ত্বিকতা - ব্যক্তিগতভাবে আমি আন্ডারস্ট্যান্ড করি না যে লোকেরা কীভাবে অভিন্ন বন্টন সহ 12 আইআরভিয়ের যোগফল সম্পাদন করে।
বিশ্ববিদ্যালয়ে আমার সম্ভাবনা তত্ত্ব ছিল theory এবং আমার জন্য বিশদ এটি কেবল একটি গণিতের প্রশ্ন। বিশ্ববিদ্যালয়ে আমি নিম্নলিখিত মডেলটি দেখেছি:
double generateUniform(double a, double b)
{
return uniformGen.generateReal(a, b);
}
double generateRelei(double sigma)
{
return sigma * sqrt(-2 * log(1.0 - uniformGen.generateReal(0.0, 1.0 -kEps)));
}
double generateNorm(double m, double sigma)
{
double y2 = generateUniform(0.0, 2 * kPi);
double y1 = generateRelei(1.0);
double x1 = y1 * cos(y2);
return sigma*x1 + m;
}
এটিকে কীভাবে টুডো করা হয়েছিল এটি কেবল একটি উদাহরণ ছিল, আমি অনুমান করি এটি কার্যকর করার আরও একটি উপায় রয়েছে।
এটি সঠিক যে প্রমাণটি এই বইটিতে পাওয়া যায় "মস্কো, বিএমএসটিইউ, 2004: XVI সম্ভাব্যতা তত্ত্ব, উদাহরণ 6.12, p.246-247" কৃষ্চেনকো আলেকজান্ডার পেট্রোভিচের আইএসবিএন 5-7038-2485-0 এর
দুর্ভাগ্যক্রমে আমি এই বইটি ইংরেজিতে অনুবাদ করার অস্তিত্ব সম্পর্কে জানি না।