PDA

View Full Version : مولد اعداد تصادفی



Mahdi Fahmideh
دوشنبه 07 شهریور 1384, 01:03 صبح
من یک مولد اعداد تصادفی بصورت زیر ساختم. (برای استخراج تصادفی روز و ساعت هفته)
اما وقتی این کد داخل یک حلقه قرار میگیره اعداد تقریبا یکسانی تولید میکنه در حالی بازه داده تقریبا بزرگه ولی در یک سیکل تولید اعداد تکراری می افتد. مشکل چیه:

کد:
Random rndRandomGenerator=new Random();
ساخت مولد بیرون تابع انجام میشه و فقط یکبار

my func()
{

i = rndRandomGenerator.Next(0,intNumberOfDay);//Day
j = rndRandomGenerator.Next(0,intNumberOfHoure);//Houre

}

Panje Tala
دوشنبه 07 شهریور 1384, 08:18 صبح
باسلام
مشکل از اینجا ناشی می شود که سیستم برای تولید اعداد تصادفی از تایمر استفاده می کند و چون در یک حلقه فرامین با سرعت بسیار زیادی اجرا می شوند تقریبا مبنای زمانی برای الگوریتم تولید عدد random یکسان است. بنابراین اعداد یکسانی تولید می شود.
حل مشکل:
می بایست بین هر بار تولید عدد Random یک فاصله زمانی ایجاد کنید تا Seed تابع Random که از زمان سیستم گرفته می شود تغییر کند.
فکر می کنم دستور ایجاد فاصله زمانی
thread.sleep(100); می باشد. بااین عمل بین هر بار ایجاد عدد random ، یک فاصله زمانی 100میلی ثانیه ایجاد می شود و اعداد تولید شده متفاوت خواهند بود.

someCoder
دوشنبه 07 شهریور 1384, 15:38 عصر
باسلام
مشکل از اینجا ناشی می شود که سیستم برای تولید اعداد تصادفی از تایمر استفاده می کند و چون در یک حلقه فرامین با سرعت بسیار زیادی اجرا می شوند تقریبا مبنای زمانی برای الگوریتم تولید عدد random یکسان است. بنابراین اعداد یکسانی تولید می شود.
حل مشکل:
می بایست بین هر بار تولید عدد Random یک فاصله زمانی ایجاد کنید تا Seed تابع Random که از زمان سیستم گرفته می شود تغییر کند.
فکر می کنم دستور ایجاد فاصله زمانی
thread.sleep(100); می باشد. بااین عمل بین هر بار ایجاد عدد random ، یک فاصله زمانی 100میلی ثانیه ایجاد می شود و اعداد تولید شده متفاوت خواهند بود.
seed فقط یکبار موقع شروع مقدار دهی میشه و از اون به بعد ربطی به تایمر نداره!

Mahdi Fahmideh
سه شنبه 08 شهریور 1384, 00:32 صبح
اگر گفته شما درست هم باشد من نمیخوام از یک وقفه حتی 100 میلی ثانیه استفاده کنم.
چون با توجه به کاری که من دارم انجام میدم مجموع این تاخیرها overhead بالایی روی برنامه من
میگذارد . راه دیگه ای وجود داره؟

Panje Tala
سه شنبه 08 شهریور 1384, 10:03 صبح
باسلام
بهتر است راجع به گفته دیگران قبل از اظهار نظر تحقیق کنید.
در مورد seed منظور تابع random با استفاده از پارامتر seed نمی باشد بلکه seed بمعنی بذر درواقع یک مقدار است که به الگوریتم random داده می شود تا عدد random تولید گردد حال اگر این مقدار ساعت سیستم باشد درواقع ساعت سیستم یک نوع seed برای الگوریتم random می باشد. فکر کنم مشکل شما
با مطالعه مطلب زیر حل شود:

http://weblogs.asp.net/erobillard/archive/2004/05/06/127374.aspx

someCoder
سه شنبه 08 شهریور 1384, 23:20 عصر
باسلام
بهتر است راجع به گفته دیگران قبل از اظهار نظر تحقیق کنید.
در مورد seed منظور تابع random با استفاده از پارامتر seed نمی باشد بلکه seed بمعنی بذر درواقع یک مقدار است که به الگوریتم random داده می شود تا عدد random تولید گردد حال اگر این مقدار ساعت سیستم باشد درواقع ساعت سیستم یک نوع seed برای الگوریتم random می باشد. فکر کنم مشکل شما
با مطالعه مطلب زیر حل شود:

http://weblogs.asp.net/erobillard/archive/2004/05/06/127374.aspx

شما کلا متوجه نشدید که من چی گفتم! همونطور که مقاله خودتون هم حتی متوجه نشدید!!! من از همین مقاله ای که بهم لینکشو دادین پاراگراف دومش رو براتون مینویسم. ببینید نظرتون چیه:

Random number algorithms are good at generating a series of
numbers which appear random.
All start with a seed value n, where n is really random number #1. n
then becomes the seed for the next number in the series (random number #2),
or n.Next. Start two or more generators with the same seed, and each will
generate the same series of numbers.

اگرم من منظورمو بد گفتم یه بار دیگه میگم! seed ( که نمیدونم چرا برام معنیش کردین!!! ) فقط اول کار از تایمر گرفته میشه! از اونجا به بعد دیگه تایمر بی تایمر!!!

Panje Tala
شنبه 12 شهریور 1384, 08:51 صبح
باسلام
ای کاش مقاله را بطور کامل مطالعه می کردید .
ضمنا
در این مقاله اشاره شده است که تولید اعداد رندم با استفاده از یک سری از اعداد انجام می شود که عدد رندم بر اساس Seed تعیین شده بدست می اید و اگر seed تغییر نکند عدد حاصل شده همان عدد قبلی خواهد بود و مقدار آن تفاوتی نمی کند. در این مقاله اشاره شده که به دو روش می توان seed را تعیین کرد یکی بصورت نرم افزاری و با مقدار دادن به پارامتر seed که اگر این seed یکسان باشد عدد حاصل شده فرقی نمی کند. از آنجاییکه برای تولید اعداد رندم احتیج به seed های متفاوتی است راه ساده تر استفاده از سخت افزار برای تولید seed است که در این مقاله به کریستال سیستم که همان تولید کننده ساعت سیستم می باشد اشاره شده است و گفته که اگراز ساعت سیستم بعنوان seed استفاده شود بدلیل تفاوت آن با گذشت زمان خروجی تابع اعداد رندم متفاوت خواهد بود.


Random number generators based in hardware (e.g. on a PCI card) use natural phenomenon like EMF noise from a crystal. Where atomic clocks measure time by measuring events from materials with regular, predictable properties of decay or emission, hardware number generators just use materials which would make for awful clocks; the unpredictability of the material makes it a good random number generator.

در ادامه مقاله اشاره شده است با توجه به اینکه سرعت پردازنده ها امروزه افزایش یافته و در کسری از زمان اعمال انجام می شود. ممکن است در دو بار پیاپی فراخوانی تابع Random هنوز زمان سیستم که بعنوان seed استفاده شده است تغییر نکرده باشدو باز مشکل یکسان بودن اعداد تولید شده پیش می آید که در ادامه مقاله به رفع مشکل پرداخته شده است.


Using the system clock as a seed value is fine -- numbers will appear random to you -- until you create two Random objects during the same clock tick. That didn't happen a few years ago, but today machines work fast enough that this is an issue.

someCoder
یک شنبه 13 شهریور 1384, 00:37 صبح
اولا که این مقاله چندان مقاله معتبری نیست که بخوایم سرش با هم بحث کنیم! من اگر میخواستم در این مورد مقاله بنویسم از این کامل تر میشد! :لبخند:
ثانا ظاهرا شما متوجه منظورم نشدید!!!

Random number algorithms are good at generating a series of
numbers which appear random.
All start with a seed value n, where n is really random number #1. n
then becomes the seed for the next number in the series (random number #2),
or n.Next. Start two or more generators with the same seed, and each will
generate the same series of numbers.

و تاکید میکنم روی این جمله:
All start with a seed value n, where n is really random number #1. n
then becomes the seed for the next number in the series (random number #2)
یعنی طبق گفته همین مقاله که چندان اعتباری هم بهش نیست مقدار seed دفعه دوم از روی خروجی مرحله قبل ساخته میشه! اگرم تایمری این وسط میبینین منم خبر کنین!!!!

ضمنا اگر مقاله در مورد اعداد تصادفی میخواین اینو بخونین:
http://en.wikipedia.org/wiki/Pseudorandom_number_generator

و برای یه نمونه درست و حسابی از اعداد تصادفی اینو بخون تا بفهمی جادوگری در کار نیست!!!
http://en.wikipedia.org/wiki/Blum_Blum_Shub

.مهدی فهمیده غلامی.
دوشنبه 21 شهریور 1384, 20:22 عصر
با تشکر از توضیحاتون
....

someCoder
سه شنبه 22 شهریور 1384, 22:06 عصر
خواهش! فقط فکر میکنم مشکل اینه که نتونستم کمکی بهت بکنم!

fmehrvarzi
چهارشنبه 09 بهمن 1392, 06:59 صبح
اگر از تابع رندم استفاده میکنید حتماً باید آن شی کلاس رندم را به صورت "استاتیک سراسری" تعریف کنید و گرنه نتایج تکراری نشون میدهد.

یعنی به این صورت:
static Random _r = new Random();

و در نتیجه تو نحوه استفاده از فرمول این دستور دیگر نیازی نیست:
System.Threading.Thread.Sleep(164);

منبع:http://www.dotnetperls.com/random