মার্ক এর সমাধান (গৃহীত সমাধান) প্রায় নিখুঁত।
int x;
do {
x = rand();
} while (x >= (RAND_MAX - RAND_MAX % n));
x %= n;
23 মার্চ 25 '16 এ সম্পাদিত
এমেরি 39 কে 21170211 চিহ্নিত করুন
তবে এটির একটি সতর্কতা রয়েছে যা কোনও অবস্থাতেই RAND_MAX
( RM
1) একাধিক N
(যেখানে N
= সম্ভাব্য বৈধ ফলাফলের সংখ্যা) এর চেয়ে 1 কম ফলাফলের 1 বৈধ ফলাফলের ফলাফলকে বাতিল করে দেয় ।
অর্থাত্, যখন 'বাতিল হওয়া মানের গণনা' ( D
) সমান হয় N
, তখন সেগুলি আসলে একটি বৈধ সেট ( V)
, কোনও অবৈধ সেট নয় I
)।
এটি কী কারণে ঘটে তা এক পর্যায়ে মার্ক N
এবং এর মধ্যে পার্থক্যের দৃষ্টি হারায় Rand_Max
।
N
এমন একটি সেট যা বৈধ সদস্যদের মধ্যে কেবল ধনাত্মক পূর্ণসংখ্যার সমন্বিত থাকে, কারণ এতে প্রতিক্রিয়াগুলির একটি সংখ্যা রয়েছে যা বৈধ হবে। (যেমন: সেট N
= {1, 2, 3, ... n }
)
Rand_max
তবে এমন একটি সেট যা (আমাদের উদ্দেশ্য হিসাবে সংজ্ঞায়িত করা হয়েছে) এতে নন-নেতিবাচক পূর্ণসংখ্যার সংখ্যা অন্তর্ভুক্ত রয়েছে।
এটি সর্বাধিক জেনেরিক ফর্মের মধ্যে যা এখানে সংজ্ঞাযুক্ত তা হ'ল Rand Max
সমস্ত বৈধ ফলাফলের সেট, যা তাত্ত্বিকভাবে নেতিবাচক সংখ্যা বা অ-সংখ্যাগত মান অন্তর্ভুক্ত করতে পারে।
সুতরাং Rand_Max
"সম্ভাব্য প্রতিক্রিয়াগুলি" এর সেট হিসাবে আরও ভালভাবে সংজ্ঞায়িত করা হয়েছে।
তবে N
বৈধ প্রতিক্রিয়াগুলির সেটের মধ্যে মানগুলির গণনার বিরুদ্ধে পরিচালিত হয়, সুতরাং আমাদের নির্দিষ্ট ক্ষেত্রে যেমন সংজ্ঞায়িত Rand_Max
করা হয় তবে এটি মোট সংখ্যার চেয়ে কম মান হবে।
মার্কের সমাধানটি ব্যবহার করে, মানগুলি বাতিল করা হয় যখন: এক্স => আরএম - আরএম% এন
EG:
Ran Max Value (RM) = 255
Valid Outcome (N) = 4
When X => 252, Discarded values for X are: 252, 253, 254, 255
So, if Random Value Selected (X) = {252, 253, 254, 255}
Number of discarded Values (I) = RM % N + 1 == N
IE:
I = RM % N + 1
I = 255 % 4 + 1
I = 3 + 1
I = 4
X => ( RM - RM % N )
255 => (255 - 255 % 4)
255 => (255 - 3)
255 => (252)
Discard Returns $True
উপরের উদাহরণে আপনি দেখতে পাচ্ছেন যে এক্স এর মান যখন আমরা (প্রাথমিক ফাংশন থেকে প্রাপ্ত এলোমেলো সংখ্যা) 252, 253, 254 বা 255 হয় তখনও আমরা এটিকে বাতিল করব যদিও এই চারটি মান প্রত্যাবর্তিত মানগুলির একটি বৈধ সেটকে অন্তর্ভুক্ত করে ।
IE: যখন প্রত্যাখ্যান করা মূল্যগুলির গণনা (I) = N (বৈধ ফলাফলের সংখ্যা) তখন প্রত্যাবর্তনের মানগুলির একটি বৈধ সেটটি মূল ফাংশন দ্বারা বাতিল করা হবে।
যদি আমরা ডি হিসাবে N এবং RM মানগুলির মধ্যে পার্থক্য বর্ণনা করি, যেমন:
D = (RM - N)
তারপরে ডিটির মান আরও ছোট হওয়ার সাথে সাথে এই পদ্ধতির কারণে অবিযুক্ত পুনরায় রোলসের শতাংশ প্রতিটি প্রাকৃতিক গুণায় বৃদ্ধি পায়। (যখন RAND_MAX একটি প্রধান সংখ্যার সমান নয় এটি বৈধ উদ্বেগের বিষয়)
উদাহরণ:
RM=255 , N=2 Then: D = 253, Lost percentage = 0.78125%
RM=255 , N=4 Then: D = 251, Lost percentage = 1.5625%
RM=255 , N=8 Then: D = 247, Lost percentage = 3.125%
RM=255 , N=16 Then: D = 239, Lost percentage = 6.25%
RM=255 , N=32 Then: D = 223, Lost percentage = 12.5%
RM=255 , N=64 Then: D = 191, Lost percentage = 25%
RM=255 , N= 128 Then D = 127, Lost percentage = 50%
যেহেতু প্রয়োজনীয় রেরোলসের শতাংশ এনএম-এর কাছাকাছি পৌঁছেছে, তাই তার কোড চলমান সিস্টেমের সীমাবদ্ধতা এবং যে মানগুলি অনুসন্ধান করা হচ্ছে তার উপর নির্ভর করে এটি বিভিন্ন ধরণের মূল্যবোধে বৈধ উদ্বেগের বিষয় হতে পারে।
এটি এড়াতে আমরা এখানে একটি সাধারণ সংশোধন করতে পারি:
int x;
do {
x = rand();
} while (x > (RAND_MAX - ( ( ( RAND_MAX % n ) + 1 ) % n) );
x %= n;
এটি সূত্রটির আরও সাধারণ সংস্করণ সরবরাহ করে যা আপনার সর্বাধিক মানগুলি সংজ্ঞায়িত করতে মডুলাস ব্যবহারের অতিরিক্ত অদ্ভুততার জন্য দায়ী।
RAND_MAX এর জন্য একটি ছোট মান ব্যবহারের উদাহরণ যা এন এর গুণক is
মার্ক'রিজিনাল সংস্করণ:
RAND_MAX = 3, n = 2, Values in RAND_MAX = 0,1,2,3, Valid Sets = 0,1 and 2,3.
When X >= (RAND_MAX - ( RAND_MAX % n ) )
When X >= 2 the value will be discarded, even though the set is valid.
সাধারণ সংস্করণ 1:
RAND_MAX = 3, n = 2, Values in RAND_MAX = 0,1,2,3, Valid Sets = 0,1 and 2,3.
When X > (RAND_MAX - ( ( RAND_MAX % n ) + 1 ) % n )
When X > 3 the value would be discarded, but this is not a vlue in the set RAND_MAX so there will be no discard.
অতিরিক্ত হিসাবে, যে ক্ষেত্রে RA এর মান RA এর মধ্যে নম্বর হওয়া উচিত END_BOLD; এই ক্ষেত্রে, আপনি RA =MAND_MAX = INT_MAX ব্যতীত N = RAND_MAX +1 সেট করতে পারেন।
লুপ-ওয়াইজ আপনি কেবল এন = 1 ব্যবহার করতে পারেন, এবং এক্স এর কোনও মান গ্রহণ করা হবে তবে আপনার চূড়ান্ত গুণকটির জন্য একটি আইএফ বিবৃতি দেবে। তবে আপনার কাছে এমন কোড রয়েছে যা ফাংশনটিকে এন = 1 দিয়ে ডাকা হলে একটি 1 ফেরত দেওয়ার বৈধ কারণ থাকতে পারে ...
সুতরাং 0 ব্যবহার করা ভাল, যা সাধারণত ডিভ 0 ত্রুটি সরবরাহ করে, যখন আপনি এন = RAND_MAX + 1 রাখতে চান
সাধারণ সংস্করণ 2:
int x;
if n != 0 {
do {
x = rand();
} while (x > (RAND_MAX - ( ( ( RAND_MAX % n ) + 1 ) % n) );
x %= n;
} else {
x = rand();
}
এই উভয় সমাধানই অযথা বাতিল হওয়া বৈধ ফলাফল নিয়ে সমস্যাটি সমাধান করে যা যখন আরএম + 1 এন এর পণ্য হয় তখনই ঘটবে।
দ্বিতীয় সংস্করণে প্রান্তের কেস দৃশ্যাবলীটিও কভার করা হয় যখন আপনাকে RAND_MAX এর মধ্যে থাকা সম্ভাব্য মানগুলির মোট সম্ভাব্য সেটটি সমান করতে প্রয়োজন হয়।
উভয় মধ্যে পরিবর্তিত পদ্ধতির একই এবং বৈধ এলোমেলো সংখ্যা প্রদান এবং বাতিল করা মানগুলি হ্রাস করার প্রয়োজনের আরও সাধারণ সমাধানের অনুমতি দেয়।
পুনরাবৃত্তি করতে:
বেসিক জেনারেল সলিউশন যা চিহ্নের উদাহরণকে প্রসারিত করে:
// Assumes:
// RAND_MAX is a globally defined constant, returned from the environment.
// int n; // User input, or externally defined, number of valid choices.
int x;
do {
x = rand();
} while (x > (RAND_MAX - ( ( ( RAND_MAX % n ) + 1 ) % n) ) );
x %= n;
বর্ধিত সাধারণ সমাধান যা RAND_MAX + 1 = n এর একটি অতিরিক্ত দৃশ্যের মঞ্জুরি দেয়:
// Assumes:
// RAND_MAX is a globally defined constant, returned from the environment.
// int n; // User input, or externally defined, number of valid choices.
int x;
if n != 0 {
do {
x = rand();
} while (x > (RAND_MAX - ( ( ( RAND_MAX % n ) + 1 ) % n) ) );
x %= n;
} else {
x = rand();
}
কিছু ভাষায় (বিশেষত বর্ণিত ভাষাগুলি) তুলনায় অপারেশনের গণনার সময়কারীর বাইরে শর্তগুলি দ্রুত ফলাফলের দিকে নিয়ে যেতে পারে কারণ এটি এক-সময় গণনা যতই পুনরায় চেষ্টা করার প্রয়োজন হয় না। YMMV!
// Assumes:
// RAND_MAX is a globally defined constant, returned from the environment.
// int n; // User input, or externally defined, number of valid choices.
int x; // Resulting random number
int y; // One-time calculation of the compare value for x
if n != 0 {
y = RAND_MAX - ( ( ( RAND_MAX % n ) + 1 ) % n)
do {
x = rand();
} while (x > y);
x %= n;
} else {
x = rand();
}
RAND_MAX%n == n - 1
__ সম্পর্কে ভাবনার আরেকটি উপায়(RAND_MAX + 1) % n == 0
। কোড পড়ার সময়, আমি% something == 0
এটি গণনার অন্যান্য পদ্ধতির চেয়ে আরও সহজেই "সমানভাবে বিভাজক" হিসাবে বুঝতে আগ্রহী । অবশ্যই, আপনার সি ++ stdlib হয়েছে থাকেRAND_MAX
হিসাবে একই মান হিসাবেINT_MAX
,(RAND_MAX + 1)
নিশ্চয় কাজ করবে না; সুতরাং মার্কের গণনাটি নিরাপদ বাস্তবায়ন থেকে যায়।