আমি উপরের আমার মন্তব্যে যেমন উল্লেখ করেছি, আপনার কোডকে অতিরিক্ত জটিলতার আগে আপনাকে প্রোফাইল দেওয়ার পরামর্শ দিচ্ছি। for
জটিল গণিতের সূত্রগুলি এবং টেবিল-বিল্ডিং / অনুসন্ধানের চেয়ে দ্রুত লুপের সামিং ডাইস বোঝা ও সংশোধন করা অনেক সহজ। আপনি গুরুত্বপূর্ণ সমস্যাগুলি সমাধান করছেন তা নিশ্চিত করতে সর্বদা প্রথমে প্রোফাইল দিন। ;)
এটি বলেছে যে, একটি ঝরে যাওয়ার মধ্যে অত্যাধুনিক সম্ভাবনা বিতরণের নমুনার দুটি প্রধান উপায় রয়েছে:
1. সংশ্লেষ সম্ভাবনা বন্টন
আছে একটি ঝরঝরে কৌতুক একটানা সম্ভাব্যতা ডিস্ট্রিবিউশন থেকে নমুনা শুধুমাত্র একটি একক অভিন্ন র্যান্ডম ইনপুট ব্যবহার দ্বারা । এটি ক্রমবর্ধমান বিতরণ , ফাংশনটির সাথে সম্পর্কিত যা " x এর চেয়ে বেশি মূল্য পাওয়ার সম্ভাবনা কী ?"
এই ফাংশনটি হ্রাস পাচ্ছে না, 0 থেকে শুরু হয়ে এর ডোমেনের উপরে 1 এ বাড়ছে। দুটি ছয়-পার্শ্বযুক্ত পাশ্বের যোগফলের উদাহরণ নীচে দেখানো হয়েছে:
যদি আপনার ক্রমবর্ধমান বিতরণ ফাংশনটিতে সুবিধাজনক-থেকে-গণনা বিপরীতমুখী থাকে (বা আপনি এটি বাজিয়ার কার্ভগুলির মতো টুকরোজ ফাংশনগুলির সাথে আনুমানিক করতে পারেন), আপনি এটি মূল সম্ভাব্যতা ফাংশন থেকে নমুনা হিসাবে ব্যবহার করতে পারেন।
বিপরীতমুখী ফাংশনটি 0 থেকে 1 এর মধ্যে ডোমেনটিকে অন্তর অন্তর অন্তর্ভুক্ত করে মূল র্যান্ডম প্রক্রিয়াটির প্রতিটি আউটপুটে ম্যাপ করা হয়, যার প্রতিটিটির আঞ্চলিক সম্ভাবনার সাথে মিল থাকে। (অবিচ্ছিন্ন বিতরণের জন্য এটি অসীম সত্য d ডাইস রোলসের মতো বিচ্ছিন্ন বিতরণের জন্য আমাদের সতর্কতার সাথে বৃত্তাকার প্রয়োগ করতে হবে)
2d6 অনুকরণ করতে এটি ব্যবহারের উদাহরণ এখানে:
int SimRoll2d6()
{
// Get a random input in the half-open interval [0, 1).
float t = Random.Range(0f, 1f);
float v;
// Piecewise inverse calculated by hand. ;)
if(t <= 0.5f)
{
v = (1f + sqrt(1f + 288f * t)) * 0.5f;
}
else
{
v = (25f - sqrt(289f - 288f * t)) * 0.5f;
}
return floor(v + 1);
}
এর সাথে তুলনা করুন:
int NaiveRollNd6(int n)
{
int sum = 0;
for(int i = 0; i < n; i++)
sum += Random.Range(1, 7); // I'm used to Range never returning its max
return sum;
}
কোডের স্বচ্ছতা এবং নমনীয়তার পার্থক্য সম্পর্কে আমি কী বুঝি? নিষ্পাপ উপায়টি এর লুপগুলির সাথে নিখুঁত হতে পারে তবে এটি সংক্ষিপ্ত এবং সহজ, এটি কী করে তা অবিলম্বে সুস্পষ্ট এবং বিভিন্ন ডাই আকার এবং সংখ্যায় স্কেল করা সহজ। ক্রমবর্ধমান ডিস্ট্রিবিউশন কোডে পরিবর্তন আনার জন্য কিছু অ-তুচ্ছ গণিতের প্রয়োজন হয়, এবং কোনও স্পষ্ট ভুল ছাড়াই এটি ভাঙ্গা এবং অপ্রত্যাশিত ফলাফল আনতে সহজ হবে। (যা আমি আশা করি আমি উপরে তৈরি করিনি)
সুতরাং, আপনি পরিষ্কার লুপটি সরিয়ে নেওয়ার আগে একেবারে নিশ্চিত হয়ে নিন যে এই ধরণের ত্যাগের মূল্যবান একটি কার্যত সমস্যা।
২.আলিয়াস পদ্ধতি
যখন আপনি একটি সাধারণ গণিতের প্রকাশ হিসাবে ক্রমবর্ধমান বিতরণ ফাংশনের বিপরীতটি প্রকাশ করতে পারেন তখন संचयी বিতরণ পদ্ধতিটি ভালভাবে কাজ করে তবে এটি সর্বদা সহজ বা এমনকি সম্ভব নয়। বিযুক্ত ডিস্ট্রিবিউশন জন্য একটি নির্ভরযোগ্য বিকল্প কিছু বলা হয় ওরফে পদ্ধতি ।
এটি আপনাকে কেবল দুটি স্বতন্ত্র, অভিন্ন বিতরণ করা এলোমেলো ইনপুট ব্যবহার করে যেকোন স্বেচ্ছাসেবী বিচ্ছিন্ন সম্ভাবনা বিতরণ থেকে নমুনা দেয়।
এটি বাম দিকে নীচের মত একটি বিতরণ নিয়ে কাজ করে (যে ক্ষেত্রগুলি / ওজনগুলি 1 এর সমান হয় না তা ভেবে দেখবেন না ) যে তুলনামূলকভাবে ওজন সম্পর্কে আমাদের যত্নশীল এলিয়াস পদ্ধতির জন্য ) এবং এটির মতো একটি টেবিলে রূপান্তরিত করে ঠিক যেখানে:
- প্রতিটি ফলাফলের জন্য একটি কলাম রয়েছে।
- প্রতিটি কলামটি মূল ফলাফলগুলির একটির সাথে যুক্ত, প্রায় দুটি অংশে বিভক্ত।
- প্রতিটি ফলাফলের আপেক্ষিক ক্ষেত্র / ওজন সংরক্ষণ করা হয়।
( নমুনা পদ্ধতিতে এই নিবন্ধটি চিত্রের উপর ভিত্তি করে চিত্র )
কোডে, আমরা প্রতিটি কলাম থেকে বিকল্প ফলাফল বেছে নেওয়ার সম্ভাবনা এবং সেই বিকল্প ফলাফলের পরিচয় (বা "উপনাম") উপস্থাপন করে দুটি টেবিল (বা দুটি বৈশিষ্ট্যযুক্ত বস্তুর একটি টেবিল) সহ এটি উপস্থাপন করি। তারপরে আমরা বিতরণ থেকে যেমন নমুনা করতে পারি:
int SampleFromTables(float[] probabiltyTable, int[] aliasTable)
{
int column = Random.Range(0, probabilityTable.Length);
float p = Random.Range(0f, 1f);
if(p < probabilityTable[column])
{
return column;
}
else
{
return aliasTable[column];
}
}
এতে কিছুটা সেটআপ জড়িত:
প্রতিটি সম্ভাব্য ফলাফলের আপেক্ষিক সম্ভাবনাগুলি গণনা করুন (সুতরাং আপনি যদি 1000d6 ঘূর্ণায়মান হন তবে প্রতি 1000 থেকে 6000 পর্যন্ত পাওয়ার পরিমাণগুলি আমাদের গণনা করতে হবে)
প্রতিটি ফলাফলের জন্য একটি এন্ট্রি সহ এক জোড়া টেবিল তৈরি করুন। সম্পূর্ণ পদ্ধতিটি এই উত্তরের ক্ষেত্র ছাড়িয়ে গেছে, তাই আমি উচ্চারণ পদ্ধতি অ্যালগরিদমের এই ব্যাখ্যাটি উল্লেখ করার পরামর্শ দিচ্ছি ।
এই টেবিলগুলি সংরক্ষণ করুন এবং প্রতিবার আপনার এই বিতরণ থেকে একটি নতুন এলোমেলো ডাই রোলের প্রয়োজন হলে তাদের আবার উল্লেখ করুন।
এটি একটি স্পেস-টাইম ট্রেড অফ । পূর্ববর্তী পদক্ষেপটি কিছুটা পরিস্ফুট এবং আমাদের যে ফলাফলের সংখ্যা রয়েছে তার সমানুপাতিক মেমরি আলাদা করে রাখতে হবে (যদিও 1000 ডি 6 এর জন্য আমরা একক-অঙ্কের কিলোবাইট ব্যবহার করছি, তাই ঘুম হারানোর কিছুই নেই), তবে আমাদের নমুনার বিনিময়ে আমাদের বিতরণ যত জটিল হতে পারে তা স্থির সময়-
আমি আশা করি methods পদ্ধতিগুলির মধ্যে একটি বা অন্য কিছু কার্যকর হতে পারে (বা আমি আপনাকে বোঝাতে পেরেছি যে নিষ্পাপ পদ্ধতির সরলতাটি লুপ করতে সময় লাগবে);)