找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 9611|回复: 7

关于一个随机数生成算法的研究

[复制链接]
发表于 2016-1-22 23:47:19 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
按照“某书”上的一道题,使用一个简单的二次函数进行反复迭代,便可生成一组随机数。
书上的公式如下:
y:=-ax^2+ax
该函数性质一目了然:对称轴 x=1/2,图像与x轴交与0,1两点。
若我们令a:=2,则:
1.jpg
函数y:=2x(1-x)
这时候,我们取x初值为0.2,代入等式,求得y后再将y的值保留
然后,将上述值作为x再次带入等式……一直循环往复进行迭代
那么我们观察所有y的值:

0.320000 0.435200 0.491602 0.499859 0.500000
0.500000 0.500000 0.500000 0.500000 0.500000
0.500000 0.500000 0.500000 0.500000 0.500000
0.500000 0.500000 0.500000 0.500000 0.500000
0.500000 0.500000 0.500000 0.500000 0.500000
......

最终值停在0.5上。
我们令a:=3.2,此时函数为:y:=3.2*x(1-x) 再次进行迭代求值:

0.512000 0.799539 0.512884 0.799469 0.513019
0.799458 0.513041 0.799456 0.513044 0.799456
0.513044 0.799456 0.513044 0.799456 0.513044
0.799456 0.513044 0.799456 0.513044 0.799456
0.513044 0.799456 0.513044 0.799456 0.513044
0.799456 0.513044 0.799456 0.513044 0.799456
......

然后我们发现,数字出现再次呈现规律:在0.513044 0.799456
这两个数字上不断出现循环。
然后a:=3.5时,y:=3.5*x*(x-1)

0.560000 0.862400 0.415332 0.849909 0.446472
0.864972 0.408785 0.845879 0.456286 0.868312
0.400212 0.840148 0.470047 0.871860 0.391021
0.833433 0.485880 0.874302 0.384643 0.828424
0.497481 0.874978 0.382871 0.826983 0.500788
0.874998 0.382818 0.826940 0.500887 0.874997
0.382820 0.826941 0.500884 0.874997 0.382820
0.826941 0.500884 0.874997 0.382820 0.826941
0.500884 0.874997 0.382820 0.826941 0.500884
0.874997 0.382820 0.826941 0.500884 0.874997
0.382820 0.826941 0.500884 0.874997 0.382820
0.826941 0.500884 0.874997 0.382820 0.826941
......

循环停在0.382820 0.826941 0.500884 0.874997
当a持续增大,一组循环数字个数增加为8、16.
但是a的值超过3.57后,则再也不会出现循环现象。
我们得到了伪随机数列。
我写一下a:=3.58时的大约200个数据:

0.572800 0.876027 0.388803 0.850734 0.454609
0.887624 0.357096 0.821891 0.524062 0.892927
0.342278 0.805943 0.559909 0.882151 0.372179
0.836509 0.489606 0.894613 0.337524 0.800493
0.571740 0.876575 0.387324 0.849549 0.457580
0.888558 0.354501 0.819212 0.530211 0.891732
0.345634 0.809692 0.551645 0.885451 0.363110
0.827914 0.510050 0.894638 0.337453 0.800411
0.571918 0.876484 0.387571 0.849748 0.457082
0.888406 0.354924 0.819652 0.529205 0.891947
0.345033 0.809027 0.553118 0.884899 0.364634
0.829400 0.506555 0.894846 0.336866 0.799726
0.573388 0.875719 0.389631 0.851390 0.452959
0.887078 0.358611 0.823433 0.520500 0.893496
0.340677 0.804127 0.563875 0.880393 0.376977
0.840818 0.479158 0.893445 0.340820 0.804289
0.563521 0.880555 0.376537 0.840430 0.480105
0.893583 0.340431 0.803845 0.564487 0.880112
0.377743 0.841491 0.477515 0.893190 0.341537
0.805105 0.561742 0.881353 0.374360 0.838488
0.484824 0.894175 0.338760 0.801926 0.568649
0.878128 0.383128 0.846100 0.466168 0.890902
0.347959 0.812243 0.545965 0.887436 0.357617
0.822423 0.522835 0.893133 0.341697 0.805286
0.561345 0.881528 0.373883 0.838059 0.485865
0.894285 0.338452 0.801570 0.569419 0.877748
0.384157 0.846958 0.464040 0.890371 0.349447
0.813854 0.542353 0.888578 0.354445 0.819153
0.530346 0.891703 0.345715 0.809782 0.551445
0.885525 0.362906 0.827715 0.510519 0.894604
0.337550 0.800524 0.571673 0.876609 0.387232
0.849474 0.457766 0.888614 0.354344 0.819048
0.530585 0.891651 0.345862 0.809944 0.551085
0.885657 0.362541 0.827356 0.511359 0.894538
0.337736 0.800740 0.571208 0.876847 0.386591
0.848955 0.459064 0.889001 0.353268 0.817922
0.533154 0.891065 0.347504 0.811747 0.547073
0.887067 0.358641 0.823463 0.520430 0.893506
0.340649 0.804094 0.563947 0.880361 0.377066
0.840897 0.478966 0.893416 0.340901 0.804381

貌似已经是随机的了。
而此现象的数学原理为:非线性系统的内在随机性
好了至此我们得到了自己的随机数发生器,
老C写了一下它的C语言描述代码:

  1. #include <stdlib.h>
  2. #include <time.h>
  3. //If you need call stdlib rand functions and initialize random seed by current time
  4. //you must include above two lines.However if not and either not calling printf.
  5. //you just can dont include any header files.
  6. #include <stdio.h>

  7. #define MAGICAL_NUMBER 3.58f
  8. float Coef = MAGICAL_NUMBER;
  9. float fIterationSeed = 0.2f;

  10. float RandProducer(float a, float x);
  11. float A5Randomize(float init);
  12. float A5Srand(float seed);
  13. float A5Rand(void);

  14. int main()
  15. {
  16.     int i, s;
  17.     srand((int)time(NULL));
  18.     goto Lbl_Choose;
  19. Lbl_StdRand:
  20.     puts("Here are 1000 random numbers form stdlib rand. Each of them is between 0 and 1.\n");
  21.     for (i = 1; i <= 1000; i++)
  22.     {
  23.         printf("%f ", rand() / (float)RAND_MAX);
  24.         if (i % 5 == 0)
  25.             puts("\n");
  26.     }
  27. Lbl_Choose:
  28.     printf("1: A5Rand 2: StdRand 0: Exit ?"); scanf("%d", &s);
  29.     if (s == 1)
  30.         goto Lbl_A5Rand;
  31.     else if (s == 2)
  32.         goto Lbl_StdRand;
  33.     return 0;
  34. Lbl_A5Rand:
  35.     puts("Here are 1000 random numbers form A5Rand. Each of them is between 0 and 1.\n");
  36.     for (i = 1; i <= 1000; i++)
  37.     {
  38.         printf("%f ", A5Rand());
  39.         if (i % 5 == 0)
  40.             puts("\n");
  41.     }
  42.     goto Lbl_Choose;
  43.     return 0;
  44. }

  45. //Function achievements.
  46. float A5Rand(void)
  47. {
  48.     return fIterationSeed = RandProducer(Coef, fIterationSeed);
  49. }

  50. float A5Srand(float seed)
  51. {
  52.     fIterationSeed = seed < 0 ? -seed : seed;
  53.     return fIterationSeed = seed > 1 ? 1 / seed : seed;
  54. }

  55. float A5Randomize(float init)
  56. {
  57.     return Coef = init + MAGICAL_NUMBER;
  58. }

  59. inline float RandProducer(float a, float x)
  60. {
  61.     return a * x - a * x * x;
  62. }
复制代码

我们的随机数发生器函数被命名为:A5Rand。
接下来我们生成200组数据。每组5个。也就是1000个数据。
我们来测试在a值为3.58的时候生成的随机数的质量。
我们用C语言stdlib库自带的随机数发生器作为比较来看看结果:
这里为了观察随机数的质量,我们使用VisualBasic6.0
编写了一款程序。其大致原理为将每个随机数按奇偶绘出其值,观察成像。
VB6源代码如下:

  1. VERSION 5.00
  2. Begin VB.Form Form1
  3.    AutoRedraw      =   -1  'True
  4.    BackColor       =   &H00FFFFFF&
  5.    BorderStyle     =   1  'Fixed Single
  6.    Caption         =   "Visual Randoperf Grapher - (C)0xAA55.com"
  7.    ClientHeight    =   1515
  8.    ClientLeft      =   45
  9.    ClientTop       =   435
  10.    ClientWidth     =   7515
  11.    BeginProperty Font
  12.       Name            =   "MS Sans Serif"
  13.       Size            =   8.25
  14.       Charset         =   0
  15.       Weight          =   700
  16.       Underline       =   0   'False
  17.       Italic          =   0   'False
  18.       Strikethrough   =   0   'False
  19.    EndProperty
  20.    ForeColor       =   &H00000000&
  21.    LinkTopic       =   "Form1"
  22.    MaxButton       =   0   'False
  23.    ScaleHeight     =   101
  24.    ScaleMode       =   3  'Pixel
  25.    ScaleWidth      =   501
  26.    StartUpPosition =   3  'Windows Default
  27. End
  28. Attribute VB_Name = "Form1"
  29. Attribute VB_GlobalNameSpace = False
  30. Attribute VB_Creatable = False
  31. Attribute VB_PredeclaredId = True
  32. Attribute VB_Exposed = False
  33. Option Explicit
  34. Dim idxLocate As Integer
  35. Dim szTemp As String
  36. Dim fso, f As Object

  37. Private Sub Form_DblClick()
  38.     On Error GoTo Lbl_ErrH:
  39.     Dim Max As Single, Min As Single
  40.     Dim DataArray() As String
  41.     Dim szFileName As String
  42.     Dim Sum As Double
  43.     Dim i As Integer
  44.     szTemp = ""
  45.     Sum = 0#
  46.     Max = 0#
  47.     Min = 1#
  48.     szFileName = App.Path & "\data" & CStr(idxLocate) & ".txt"
  49.     Set f = fso.OpenTextFile(szFileName, 1, False)
  50.     DataArray = Split(Replace(Replace(f.ReadAll, vbCr, ""), vbLf, ""), " ")
  51.     Me.Cls
  52.     Me.ForeColor = &H0&
  53.     Me.Line (0, 0)-(500, 100), vbBlack, B
  54.     For i = 0 To 499 Step 2
  55.         Me.Line (i + 1, 100)-(i, 100 - Val(DataArray(i + 1)) * 100), vbBlue
  56.         Me.Line (i, 100)-(i, 100 - Val(DataArray(i)) * 100), vbRed
  57.         Sum = Sum + Val(DataArray(i + 1)) + Val(DataArray(i))
  58.         Max = IIf(Val(DataArray(i + 1)) > Max, Val(DataArray(i + 1)), Max)
  59.         Max = IIf(Val(DataArray(i)) > Max, Val(DataArray(i)), Max)
  60.         Min = IIf(Val(DataArray(i + 1)) < Min, Val(DataArray(i + 1)), Min)
  61.         Min = IIf(Val(DataArray(i)) < Min, Val(DataArray(i)), Min)
  62.     Next
  63.     Me.CurrentY = 0
  64.     Me.CurrentX = Me.ScaleWidth = Me.TextWidth(szFileName)
  65.     Me.Print "Fn:" & szFileName
  66.     Me.CurrentX = 0
  67.    
  68.     szTemp = Format(Sum, "0.000000") & " " & _
  69.              Format(Sum / 1000#, "0.000000") & " " & _
  70.              Format(Max, "0.000000") & " " & _
  71.              Format(Min, "0.000000")
  72.     Print "SUM:" & vbTab & Format(Sum, "0.000000")
  73.     Print "AVG:" & vbTab & Format(Sum / 1000#, "0.000000")
  74.     Print "MAX:" & vbTab & Format(Max, "0.000000")
  75.     Print "MIN:" & vbTab & Format(Min, "0.000000")
  76.     Exit Sub
  77. Lbl_ErrH:
  78.     MsgBox Err.Number & ":" & Err.Description, 16, "Error!"
  79. End Sub

  80. Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)
  81.     On Error GoTo Lbl_ErrH:
  82.     Select Case KeyCode
  83.     Case 189
  84.         If idxLocate > 0 Then idxLocate = idxLocate - 1
  85.         If Not fso.FileExists(App.Path & "\data" & CStr(idxLocate) & ".txt") Then
  86.             idxLocate = idxLocate + 1
  87.             ShowMessage ("File Not Found." & idxLocate & " Press <F5> to reload.")
  88.         Else
  89.             Form_DblClick
  90.         End If
  91.     Case 187
  92.         idxLocate = idxLocate + 1
  93.         If Not fso.FileExists(App.Path & "\data" & CStr(idxLocate) & ".txt") Then
  94.             idxLocate = idxLocate - 1
  95.             ShowMessage ("File Not Found." & idxLocate & " Press <F5> to reload.")
  96.         Else
  97.             Form_DblClick
  98.         End If
  99.     Case 191
  100.         MsgBox "STRAT:" & vbTab & "F5" & vbCrLf & _
  101.                "SAVE:" & vbTab & "F3" & vbCrLf & _
  102.                "SWITCH:" & vbTab & "<-|+>" & vbCrLf & _
  103.                "BATCH" & vbTab & "F7" & vbCrLf & _
  104.                "HELP" & vbTab & "/|?" & vbCrLf & _
  105.                "(C) 2016 CYY @ 0xAA55.com" _
  106.                , 0, "Help"
  107.     Case 116
  108.         Form_DblClick
  109.     Case 114
  110.         SavePicture Me.Image, App.Path & "\data" & CStr(idxLocate) & ".bmp"
  111.         MsgBox "File saved!", 48, "Done"
  112.     Case 118
  113.         BatchFiles
  114.     End Select
  115.     Exit Sub
  116. Lbl_ErrH:
  117.     MsgBox Err.Number & ":" & Err.Description, 16, "Error!"
  118. End Sub

  119. Private Sub Form_Load()
  120.     Dim szDisplay As String
  121.     Set fso = CreateObject("Scripting.FileSystemObject")
  122.     szDisplay = "START: Double-Click/F5; BATCH: F7; SWITCH:<-|+>; HELP: ?/"
  123.     Me.Line (0, 0)-(Me.ScaleWidth, Me.ScaleHeight), vbBlack, BF
  124.     Me.CurrentX = Me.ScaleWidth / 2 - Me.TextWidth(szDisplay) / 2
  125.     Me.CurrentY = Me.ScaleHeight / 2 - Me.TextHeight(szDisplay) / 2
  126.     Me.ForeColor = &HFFFFFF
  127.     Me.Print szDisplay
  128.     idxLocate = 0
  129. End Sub

  130. Sub ShowMessage(szDisplay As String, Optional ColorFore As Long = &HFFFFFF)
  131.     Me.Line (0, 0)-(Me.ScaleWidth, Me.ScaleHeight), vbBlack, BF
  132.     Me.CurrentX = Me.ScaleWidth / 2 - Me.TextWidth(szDisplay) / 2
  133.     Me.CurrentY = Me.ScaleHeight / 2 - Me.TextHeight(szDisplay) / 2
  134.     Me.ForeColor = ColorFore
  135.     Me.Print szDisplay
  136. End Sub

  137. Sub BatchFiles()
  138.     On Error Resume Next
  139.     Static szFileContent As String
  140.     Dim iErrorCtr As Integer
  141.     Dim iFileCtr As Integer
  142.     szFileContent = vbNullString
  143.     While fso.FileExists(App.Path & "\data" & CStr(idxLocate) & ".txt")
  144.         Form_DblClick
  145.         szFileContent = szFileContent & szTemp & vbCrLf
  146.         SavePicture Me.Image, App.Path & "\data" & CStr(idxLocate) & ".bmp"
  147.         If Err <> 0 Then
  148.             iErrorCtr = iErrorCtr + 1
  149.             Err.Clear
  150.         End If
  151.         iFileCtr = iFileCtr + 1
  152.         idxLocate = idxLocate + 1
  153.     Wend
  154.     idxLocate = idxLocate - 1
  155.     ShowMessage "HANDLED:" & iFileCtr & "," & _
  156.                 "ERROR:" & iErrorCtr & "," & _
  157.                 "SUCCESSED:" & iFileCtr - iErrorCtr, _
  158.                 IIf(iFileCtr - iErrorCtr <= 0, vbRed, vbYellow)
  159.     Err.Clear
  160.     Set f = fso.OpenTextFile(App.Path & "\dtreport.txt", 2, True)
  161.     f.Write szFileContent
  162.     If Err <> 0 Then MsgBox Err.Number & ":" & Err.Description, 16, "Error!"
  163. End Sub
复制代码


程序运行效果:
2.jpg
这个程序读入自身目录下的data0.txt文件(文件格式与C语言输出格式一致)
的1000个数据并分析制图,制图结果按下F3键会按照txt文件名保存至当前目录。
我们先来看stdlib rand的结果:
data0.bmp
我们再来看A5Rand的结果:
data0.bmp

效果已经显现,stdlib rand非常不错,A5Rand虽然数据随机,但是分布过于均匀。
1月21号我对A5Rand(a值等于3.58)和stdlib rand进行了“暴力测试”。
这次样本容量相当大。我对stdlib rand与A5Rand 分别生成10组矩阵,每组1000个随机数。
效果报告太大,顾节选部分。(rar压缩包就4M多)
这次我对10个矩阵分别进行了 数值和,平均数,最大,最小数的统计
A5Rand统计结果如下:

SUM        AVG      MAX      MIN
323.919580 0.323920 0.894984 0.336477
323.862921 0.323863 0.894985 0.336473
323.846480 0.323846 0.894999 0.336433
323.815000 0.323815 0.894999 0.336434
323.826478 0.323826 0.894999 0.336434
323.815000 0.323815 0.894999 0.336434
323.826478 0.323826 0.894999 0.336434
323.815000 0.323815 0.894999 0.336434
323.826478 0.323826 0.894999 0.336434
323.815000 0.323815 0.894999 0.336434

而这是stdlib rand的统计结果:

SUM        AVG      MAX      MIN
249.412740 0.249413 0.998529 0.000136
247.160952 0.247161 0.999388 0.001050
251.454442 0.251454 0.999395 0.003241
244.582801 0.244583 0.996929 0.000884
248.742623 0.248743 0.999873 0.002175
250.106113 0.250106 0.997334 0.000467
261.062332 0.261062 0.998823 0.000000
263.112599 0.263113 0.999694 0.006322
259.486934 0.259487 0.999951 0.001819
241.423291 0.241423 0.998722 0.000324

接着我又无聊地对2w个数据分别作出现频率统计。
ps:我用的是n年前自己写的字/词频分析。
然后因该软件实现技术,算法上的重大缺陷。跑1w个数据耗时10分钟。
光是打开文件就花费1分多钟。(渣渣)
Parallels 图片 3.jpg

好在效果出来了,在此分享一下节选片段:
A5Rand(大量重复!):

7.  词句: 0.894908 出现次数为: 19 出现频率为: 0.0019
8.  词句: 0.894985 出现次数为: 19 出现频率为: 0.0019
9.  词句: 0.894999 出现次数为: 19 出现频率为: 0.0019
10. 词句: 0.337423 出现次数为: 18 出现频率为: 0.0018
11. 词句: 0.800376 出现次数为: 18 出现频率为: 0.0018
12. 词句: 0.571993 出现次数为: 18 出现频率为: 0.0018
13. 词句: 0.876445 出现次数为: 18 出现频率为: 0.0018
14. 词句: 0.387675 出现次数为: 18 出现频率为: 0.0018
15. 词句: 0.849832 出现次数为: 18 出现频率为: 0.0018
16. 词句: 0.456872 出现次数为: 18 出现频率为: 0.0018
17. 词句: 0.888341 出现次数为: 18 出现频率为: 0.0018
18. 词句: 0.355105 出现次数为: 18 出现频率为: 0.0018
19. 词句: 0.819839 出现次数为: 18 出现频率为: 0.0018
20. 词句: 0.528776 出现次数为: 18 出现频率为: 0.0018
21. 词句: 0.892035 出现次数为: 18 出现频率为: 0.0018
22. 词句: 0.344783 出现次数为: 18 出现频率为: 0.0018
23. 词句: 0.808750 出现次数为: 18 出现频率为: 0.0018

stdlib rand:

23. 词句: 0.743599 出现次数为: 2 出现频率为: 0.0002
24. 词句: 0.568461 出现次数为: 2 出现频率为: 0.0002
25. 词句: 0.087062 出现次数为: 2 出现频率为: 0.0002
26. 词句: 0.874452 出现次数为: 2 出现频率为: 0.0002
27. 词句: 0.977495 出现次数为: 2 出现频率为: 0.0002
28. 词句: 0.177088 出现次数为: 2 出现频率为: 0.0002
29. 词句: 0.505303 出现次数为: 2 出现频率为: 0.0002
30. 词句: 0.769167 出现次数为: 2 出现频率为: 0.0002
31. 词句: 0.856239 出现次数为: 2 出现频率为: 0.0002
32. 词句: 0.725977 出现次数为: 2 出现频率为: 0.0002
33. 词句: 0.376608 出现次数为: 2 出现频率为: 0.0002
34. 词句: 0.861518 出现次数为: 2 出现频率为: 0.0002
35. 词句: 0.107373 出现次数为: 2 出现频率为: 0.0002
36. 词句: 0.929944 出现次数为: 2 出现频率为: 0.0002
37. 词句: 0.374588 出现次数为: 2 出现频率为: 0.0002
38. 词句: 0.607417 出现次数为: 2 出现频率为: 0.0002
39. 词句: 0.179999 出现次数为: 2 出现频率为: 0.0002
40. 词句: 0.744827 出现次数为: 2 出现频率为: 0.0002
41. 词句: 0.623363 出现次数为: 2 出现频率为: 0.0002
42. 词句: 0.998426 出现次数为: 2 出现频率为: 0.0002
43. 词句: 0.210764 出现次数为: 2 出现频率为: 0.0002
44. 词句: 0.584360 出现次数为: 2 出现频率为: 0.0002
45. 词句: 0.126537 出现次数为: 2 出现频率为: 0.0002
46. 词句: 0.295641 出现次数为: 2 出现频率为: 0.0002
47. 词句: 0.093876 出现次数为: 2 出现频率为: 0.0002
48. 词句: 0.401310 出现次数为: 2 出现频率为: 0.0002
49. 词句: 0.729049 出现次数为: 2 出现频率为: 0.0002
50. 词句: 0.412082 出现次数为: 2 出现频率为: 0.0002
51. 词句: 0.233230 出现次数为: 2 出现频率为: 0.0002
52. 词句: 0.520887 出现次数为: 2 出现频率为: 0.0002
53. 词句: 0.932117 出现次数为: 2 出现频率为: 0.0002
54. 词句: 0.439312 出现次数为: 2 出现频率为: 0.0002
55. 词句: 0.384457 出现次数为: 2 出现频率为: 0.0002
56. 词句: 0.838543 出现次数为: 2 出现频率为: 0.0002
57. 词句: 0.386779 出现次数为: 2 出现频率为: 0.0002
58. 词句: 0.969157 出现次数为: 2 出现频率为: 0.0002
59. 词句: 0.407021 出现次数为: 2 出现频率为: 0.0002
60. 词句: 0.914250 出现次数为: 2 出现频率为: 0.0002
61. 词句: 0.571047 出现次数为: 2 出现频率为: 0.0002
62. 词句: 0.789341 出现次数为: 2 出现频率为: 0.0002
63. 词句: 0.003714 出现次数为: 2 出现频率为: 0.0002
64. 词句: 0.932136 出现次数为: 2 出现频率为: 0.0002
65. 词句: 0.076419 出现次数为: 2 出现频率为: 0.0002
66. 词句: 0.101964 出现次数为: 2 出现频率为: 0.0002
67. 词句: 0.915684 出现次数为: 2 出现频率为: 0.0002
68. 词句: 0.575908 出现次数为: 2 出现频率为: 0.0002
69. 词句: 0.471095 出现次数为: 2 出现频率为: 0.0002
70. 词句: 0.219661 出现次数为: 2 出现频率为: 0.0002
71. 词句: 0.097873 出现次数为: 2 出现频率为: 0.0002
72. 词句: 0.917924 出现次数为: 2 出现频率为: 0.0002
73. 词句: 0.221586 出现次数为: 2 出现频率为: 0.0002
74. 词句: 0.711277 出现次数为: 1 出现频率为: 0.0001
75. 词句: 0.437822 出现次数为: 1 出现频率为: 0.0001
76. 词句: 0.472661 出现次数为: 1 出现频率为: 0.0001
77. 词句: 0.016471 出现次数为: 1 出现频率为: 0.0001
78. 词句: 0.825967 出现次数为: 1 出现频率为: 0.0001
79. 词句: 0.028305 出现次数为: 1 出现频率为: 0.0001
80. 词句: 0.714593 出现次数为: 1 出现频率为: 0.0001
81. 词句: 0.169405 出现次数为: 1 出现频率为: 0.0001
82. 词句: 0.193566 出现次数为: 1 出现频率为: 0.0001
83. 词句: 0.271427 出现次数为: 1 出现频率为: 0.0001
84. 词句: 0.874044 出现次数为: 1 出现频率为: 0.0001
85. 词句: 0.058684 出现次数为: 1 出现频率为: 0.0001
86. 词句: 0.299395 出现次数为: 1 出现频率为: 0.0001

可以说A5Rand在a值为3.58时生成的随机数相当不理想!
接下来,我将a值增加值4.0
那么在C代码中将 MAGICAL_NUMBER 魔数宏改至4.0
#define MAGICAL_NUMBER 4.0f
也就是说迭代式为 4*x*(1-x)
4.jpg
事实上,4是我们用该迭代公式求0~1的随机数的极值了。
再大抛物线顶端y值将超过1.
效果好得难以置信啊!
5.png
这是A5Rand函数,a值等于4.0,迭代初始值(随机数种子)等于2.0 时候的图象。
这里发现了一个问题。因为a值取4.0,加之函数图象交于x轴 (0,0)点和 (1,0)点,
所以0和1的出现频率陡增。
我们将魔数a改为3.99试试:
函数: y:=3.99*x(1-x)
k.png
效果简直不能再赞!拔群!拔群啊!
我们放一张stdlib rand的图进行对比!
6.png
至此我们应该得到了一个并不是最高效的http://www.0xaa55.com/thread-785-1-1.html
实用的伪随机数生成算法!

好了,最后我们应该选用一个无限接近4,而又不能等于4的值(看我怎样实现!)

  1. #include <stdio.h>

  2. static float fIterationSeed = 0.2f;

  3. float RandProducer(float x)
  4. {
  5.     float a;
  6.     *(int*)&a = 0x407FFFFF; //What'd Fucking number is this? I wont tell you.
  7.     return a * x - a * x * x;
  8. }
  9. float A5Srand(float seed)
  10. {
  11.     fIterationSeed = seed < 0 ? -seed : seed;
  12.     return fIterationSeed = seed > 1 ? 1 / seed : seed;
  13. }

  14. float A5Rand(void)
  15. {
  16.     return fIterationSeed = RandProducer(fIterationSeed);
  17. }

  18. //All code we need to use A5Rand machine is above this comment.

  19. //Also we can drop the following code.
  20. //Main function? hehe! it doesn't metter.
  21. #include <stdlib.h>
  22. #include <time.h>

  23. int main()
  24. {
  25.     int i, s;
  26.     srand((int)time(NULL));
  27.     goto Lbl_Choose;
  28. Lbl_StdRand:
  29.     puts("Here are 1000 random numbers form stdlib rand. Each of them is between 0 and 1.\n");
  30.     for (i = 1; i <= 1000; i++)
  31.     {
  32.         printf("%f ", rand() / (float)RAND_MAX);
  33.         if (i % 5 == 0)
  34.             puts("\n");
  35.     }
  36. Lbl_Choose:
  37.     printf("1: A5Rand 2: StdRand 0: Exit ?"); scanf("%d", &s);
  38.     if (s == 1)
  39.         goto Lbl_A5Rand;
  40.     else if (s == 2)
  41.         goto Lbl_StdRand;
  42.     return 0;
  43. Lbl_A5Rand:
  44.     puts("Here are 1000 random numbers form A5Rand. Each of them is between 0 and 1.\n");
  45.     for (i = 1; i <= 1000; i++)
  46.     {
  47.         printf("%f ", A5Rand());
  48.         if (i % 5 == 0)
  49.             puts("\n");
  50.     }
  51.     goto Lbl_Choose;
  52.     return 0;
  53. }
复制代码

ps:我会往后新开一帖讲述the fucking number。敬请期待。
然后后面老C没有时间做大量测试了。
估计也没有人像老C一样闲的蛋疼做这些测试。
就这样吧。完。01 22 2015 cyycoish
回复

使用道具 举报

发表于 2016-1-23 14:37:18 | 显示全部楼层
……效果没那么好啊,数字也不是十分随机。
跑完随机数生成一个“样本数组”以后,用快速傅里叶变换(FFT)统计频率试试。我估计0.9以上的数字基本很少。
回复 赞! 靠!

使用道具 举报

发表于 2016-2-2 15:30:42 | 显示全部楼层
用公式生成的随机数怎么是随机的呢
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2016-3-23 13:28:09 | 显示全部楼层
略游 发表于 2016-2-2 15:30
用公式生成的随机数怎么是随机的呢

那要怎么生成随机数呢?给每台计算机安装射线管,或者放射性元素?
A5亲自测试过VS的随机数生成算法,我的帖子里边链接你都没看。
所以说这些都是Psuedo随机数,真正的随机数还是自己统计每天降雨量为好。
回复 赞! 靠!

使用道具 举报

发表于 2017-11-8 08:46:44 | 显示全部楼层
计算机的随机,叫做 偶然 数。不是真正的随机。
回复 赞! 靠!

使用道具 举报

发表于 2019-6-2 03:08:58 | 显示全部楼层
回楼上:公式生成本来就不是真随机,所以才叫伪随机数啊,pseudo random number
然后话说我觉得测试的时候加个方差什么的会不会好一点呢,毕竟方差或者标准差本身就是用来检验数据分布情况的,还有伪随机数要求对于解空间中一共n个元素,每个元素的出现概率统计上要等于1/n,不知道这点满不满足
回复 赞! 靠!

使用道具 举报

发表于 2020-3-20 12:00:42 | 显示全部楼层
复杂啊。
回复

使用道具 举报

发表于 2022-11-23 22:12:23 | 显示全部楼层
生成伪随机数就非常不容易了
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-21 18:10 , Processed in 0.035476 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表