PDA

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



m.4.r.m
یک شنبه 22 دی 1392, 23:31 عصر
خسته نباشید ... !!!
می خوام ایده های دوستان رو درباره تولید اعداد تصادفی بدون تکرار بدونم !
تولید اعداد تصادفی که تعداد تکرارشون از 20 درصد کمتر باشه ، حالا هر ایده ای داشته باشین با جان و دل میپذریم ، البته اگه ایده پردازیتون خوب باشه می تونیم با همکاری همدیگه به صورت مقاله انگلیسی ارسال کنیم . من یه روشی داشتم که تا 16% تولید می کرد و از الگوریتم ژنتیک هم تو اون استفاده کرده بودم .
منظور از ایده اینه که از چه راهی عدد تولید کنیم ؟ مثلا یه روش اینه از کد اسکی حروف بعلاوه میلی ثانیه ساعت در هر لحظه یک عدد تصادفی تولید میشه و.... منتظر ایده های قشنگ هستم .

محمد فدوی
دوشنبه 23 دی 1392, 00:03 صبح
پروژه ی جالبیه... حتماً روش فکر میکنم.
بهتر نیست از زبونای قوی تری مثل ++C چنین پروژه ای رو شروع کنی؟ فکر میکنم اونجا آزادی عمل بیشتر باشه...

یه فکرهم الان به نظرم رسید نمیدونم چقدر کمک کنه.
به نظرم Hash کردن یه GUID خیلی تصادف بالایی رو ایجاد کنه (درصدش رو نمیدونم البته!)

محمد فدوی
دوشنبه 23 دی 1392, 00:27 صبح
اینو ببین:


Option Explicit

Private Type Guid
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type

Private Declare Sub CoCreateGuid Lib "ole32.dll" (ByRef pguid As Guid)
Private Declare Function StringFromGUID2 Lib "ole32.dll" (ByVal rguid As Long, ByVal lpsz As Long, ByVal cchMax As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, src As Any, ByVal bytes As Long)

Private Function GetGUID() As String
Dim MyGUID As Guid
Dim GUIDByte() As Byte
Dim GuidLen As Long

CoCreateGuid MyGUID

ReDim GUIDByte(80)
GuidLen = StringFromGUID2(VarPtr(MyGUID.Data1), VarPtr(GUIDByte(0)), UBound(GUIDByte))

GetGUID = Left(GUIDByte, GuidLen)
End Function

Private Function HashCode(Key As String) As Long
On Error GoTo ErrorGoTo

Dim lastEl As Long, i As Long
lastEl = (Len(Key) - 1) \ 4
ReDim codes(lastEl) As Long
CopyMemory codes(0), ByVal Key, Len(Key)

For i = 0 To lastEl - 1
HashCode = HashCode Xor codes(i)
Next

ErrorGoTo:
Exit Function
End Function

Private Function LongRand() As Long
LongRand = HashCode(GetGUID())
End Function

Private Function DoubleRand() As Double
DoubleRand = LongRand() / 2147483648#
End Function

Private Sub Form_Initialize()
MsgBox "Long Random: " & LongRand() & vbNewLine & _
"Double Random: " & DoubleRand()
End Sub

m.4.r.m
دوشنبه 23 دی 1392, 00:32 صبح
مرسی داداش خوشحالم که بچه ها استقبال می کنن تست می کنم بازم ایده داشته باشی خیلی خوبه ، منظور از ایده مثلا حرکت قورباغه رو در نظر بگیر هر بار یک جا می پره میشه اینو شبیه سازی کرد و حرکت قورباغه رو عدد تصادفی کرد این یک مثال از این نوع ایده ها داشته باشین خیلی بهتر میشه کار رو جلو برد

در ضمن زبان مهم نیست مهم تولید عدد

محمد فدوی
دوشنبه 23 دی 1392, 00:40 صبح
من خودم به شخصه موافق استفاده از الگوریتم های هوش نیستم... اعداد Long توی VB6 چهار بایتی هستن و در بهترین حالت عددی تولید میشه که احتمال تکرارشون (32- ^ 2) میشه. الگوریتم ژنتیک دقیقاً %0 خطا رو فراهم میکنه ولی محدودیت ما تعداد اعداده! شاید بهتر باشه که انتظارمون بجای تولید عدد، تولید ماتریسی از بایت ها باشه. در اون صورت با استفاده از AI موافقم.

m.4.r.m
دوشنبه 23 دی 1392, 00:48 صبح
الگوریتم های AI رو موقعی در برنامه اضافه می کنیم که از روش هایی که گفتم استفاده کرده باشیم و برای تعمیم و بهینه سازی تعداد تکرارمون ازش استفاده می کنیم .

talent1
دوشنبه 23 دی 1392, 09:19 صبح
منم یه ایده بدم
ثانیه +دقیقه +ساعت + روز + ماه +سال +یه متغیر از پیش ساخته که هر 1 ثانیه صفر میشه رو
از سیستم بگیریم در کنار هم بدون (/ یا : ) قرار بدیم عددی بدست میاد که خیلی کم ممکنه تکراری باشه. :چشمک:
(یه بار تو ویروس ازش استفاده کردم) :لبخند:

m.4.r.m
دوشنبه 23 دی 1392, 15:02 عصر
ببین شما اینو در نظر بگیر : برای اینه بفهمی تعداد تکرار شما چقدر هست باید رنج اعداد تصادفی شما معلوم باشه ، مثلا سه رقمی خوب برای اعداد 3 رقمی باید 1000 تا عدد تولید کنی از 0-999 حالا شما بیا 12000 تا عدد سه رقمی تولید کن خب به مراتب بعد از 1000 تا تعداد تکرار میره بالا اگه درصد تکرار کمتر از 20% بود الگوریتم بهینه است . تعداد تکرار تقسیم بر تعداد کل ضرب در 100 اینم درصد تکرار .

vbhamed
شنبه 28 دی 1392, 15:44 عصر
سلام
فرض كنيد قراره از بين اعداد 5 ميليون تا 10 ميليون 100 هزار شماره غير تكراري تصادفي توليد بشه
نمونه كد زير روي دستگاه من در عرض حدود 7 ثانيه اعداد رو انتخاب و در يك ليست باكس 9 ستوني قرار ميده
البته اگر قرار نباشه اعداد در ليست نمايش داده بشه فقط حدود 3 ثانيه زمان نياز هست
يك تابع Random نوشته شده و يك دكمه هم كه فراخواني تابع رو انجام ميده
Private Function Random(ByVal Count@, ByVal Low@, ByVal high@, num@()) As Boolean

Dim x@(), z@, n@, i&, temp@

If high - Low - 1 < Count Then
MsgBox "تعداد اعداد تصادفي درخواستي بيشتر از محدوده اعداد است"
Exit Function
End If

If Low > high Then temp = Low: Low = high: high = temp
n = high - Low

ReDim x(n)
ReDim num(Count - 1)

For i = 0 To n
x(i) = i + Low
Next

Randomize Timer
For i = 0 To n
z = Int(Rnd * n) + 1
temp = x(i): x(i) = x(z): x(z) = temp
Next

For i = 0 To Count - 1
num(i) = x(i)
Next
Random = 1

End Function

Private Sub Command1_Click()

Dim n@(), i&, tedad@, temp@, t!

'List1.Clear
Me.MousePointer = vbHourglass: DoEvents
tedad = 100000
t = Timer
If Random(tedad, 5000000, 10000000, n) Then
For i = 0 To tedad - 1
'List1.AddItem Format$(n(i), "#,#")
Next
End If
Me.Caption = "Time : " & Timer - t
Me.MousePointer = 0: DoEvents

End Sub
در اين روش احتمال توليد عدد تكراري اصلا وجود نداره، فرض مي‌كنيم قراره اعداد در بازه 0 تا 1000000 باشه، با اين تابع اونها رو در يك آرايه قرار مي‌ديم، جاهاشون رو در همون آرايه به صورت تصادفي عوض مي‌كنيم و نتيجه رو نمايش مي‌ديم، اينكار باعث ميشه ترتيب اعداد در آرايه به هم بريزه ولي هيچ عدد تكراري نداشته باشيم

اگر مثلا قراره 100 هزار عدد در بازه 4 ميليون تا 5 ميليون توليد بشه تابع، عدد نهايي رو با 4000000 جمع مي‌كنه و باز هم طبق تابع اگر قراره 100 هزار عدد از بازه 0 تا 30 ميليون توليد بشه كافيه بعد از جابجايي اعداد، 1 ميليون عدد اول رو استفاده كنيم

پارامتر اول تابع تعداد عدد تصادفي درخواستي، پارامتر دوم كمترين عدد پارامتر سوم بيشترين عدد و پارامتر چهارم آرايه‌اي است كه اعداد توليد شده در اون قرار مي‌گيره ضمنا خروجي خود تابع مشخص مي‌كنه كه كار تابع به درستي انجام شده يا نه

m.4.r.m
یک شنبه 29 دی 1392, 00:01 صبح
آقا حامد شما در این روش وقتی عددی تولید میشه میتونید حدس بزنید عدد بعدی چنده ؟

vbhamed
یک شنبه 29 دی 1392, 09:25 صبح
سلام
نه نميشه حدس زد

m.4.r.m
یک شنبه 29 دی 1392, 14:26 عصر
خوب پس روش خوبی میتونه باشه ام مشکل اینجاست از 0 تا 6000000 میلیون عدد درست نیست مثلا باید اینطوری باشه 6000000 میلیون عدد تولید بشه همشون تو یک رنج مثلا 6 رقمی باشن

vbhamed
یک شنبه 29 دی 1392, 15:52 عصر
سلام
نحوه استفاده ديگه به خودتون بستگي داره
شايد كسي نياز داشته باشه در بازه 0 تا 6 ميليون، اعداد تصادفي رو توليد كنه، البته عدد 6 رقمي كه 899999 بيشتر نداريم ولي فكر مي‌كنم شما مثال زدين
اما در هر حال اين تابع هر رنجي كه بخواين بهتون ميده، مثلا اگر بخواين مي‌تونيد از تابع بخواين 10 هزار عدد بين 100000 تا 999999 توليد كنه كه همشون 6 رقمي ميشه
اگر براي بدست آوردن رنج خاصي مشكل داريد بفرماييد

m.4.r.m
یک شنبه 29 دی 1392, 15:57 عصر
نه مشکلی ندارم با رنج خاص این نوع تولید اعداد تصادفی که من میگم باید به این روش تخمین زده بشه ، حساب کنید از 0 تا 999 عدد می خوایم تولید کنیم حالا از 0 تا 999 باید هر عدد سه رقمی باشه نمی تونه تک رقم باشه که به این روش میگن نرمال سازی بعد وقتی بخوایم 15000 هزار تا عدد تصادفی تولید کنیم در رنج 3 رقمی بعد از 999 تکرار ما شروع میشه یعنی ما باید جوری الگوریتم رو بهینه کنیم که در 15000 عدد تصادفی 3 رقمی تکرار ما به حداقل برسه .

که در تابع شما به این خط میرسه
MsgBox "تعداد اعداد تصادفي درخواستي بيشتر از محدوده اعداد است"

vbhamed
دوشنبه 30 دی 1392, 09:10 صبح
سلام
خب اين كه كاري نداره، شما كافيه تابع رو چند بار اجرا كنيد مثلا براي محدوده 0 تا 999 ما 900 تا عدد سه رقمي داريم و كافيه شما در تابع حد پايين رو 100 و حد بالا رو 999 و تعداد عدد رو 900 در نظر بگيريد، اينطوري هر بار 900 تا عدد تصادفي غير تكراري از 100 تا 999 بدست مياد و اگر تابع رو 16 بار اجرا كنيد 14400 تا از اعداد تصادفي توليد ميشه و براي بار هفدهم هم تابع رو اجرا كنيد ولي اينبار 600 تا عدد توليد كنيد كه در نهايت 15000 عددتون بدست بياد و چون مطمئن هستيد در هر بار اجرا، عدد تكراري توليد نشده پس در نهايت هم كمترين تعداد تكرار رو هم داريم

فقط تغيير كوچكي در قسمت كنترل محدوده دادم كه از همون پست شماره 9 برداريد