产生不重复随机数的问题

BEN1978 2005-11-18 07:12:21
Dim i As Integer
For i = 1 To 125
Randomize Timer
rndNum(i) = Int((250 * Rnd) + 1)
Text1.Text = Text1.Text & rndNum(i) & vbCrLf
Next i

生成 1 到 250 的125个随机数,要求无重复数。
上面的代码生成的有重复。

请问大家要如何解决?谢谢了
...全文
455 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
KiteGirl 2005-11-19
  • 打赏
  • 举报
回复
嘿嘿!不是学名,是个叫做KiteGirl的家伙瞎取的绰号。
最初上CSDN的时候就发过这个代码,有年头了。因为算法是将第i个元素与随机位置的元素交换,好象跳蚤一样跳来跳去的。因此叫它跳蚤算法。
我想不会是那个叫KiteGirl的最早发现这个算法,世界上比她聪明的人很多,应该有个学名。
KiteGirl最初发现这个算法是在QB时代,灵感来自QB下的SWAP命令。跳蚤算法属于一种用空间换速度的算法,这种算法当初叫做“摆地摊式算法”(莫菲定理说:如果一个笨方法有效,它就不是一个笨方法)。灵感来自PAL电路,因为PAL电路用真值表的方式实现逻辑电路。当时觉得PAL电路这种做法相当有趣。
蒋晟 2005-11-19
  • 打赏
  • 举报
回复
You can shuffle an array of natural numbers between 1 and 250; however, you don't need to complete the shuffling since you merely need 125 numbers.

In a computer, shuffling is equivalent to generating a random permutation of the cards. There are two basic algorithms for doing this, both popularized by Donald Knuth. The first is simply to assign a random number to each card, and then to sort the cards in order of their random numbers. This will generate a random permutation, unless two of the random numbers generated are the same. This can be eliminated either by retrying these cases, or reduced to an arbitrarily low probability by choosing a sufficiently wide range of random number choices.

The second, generally known as the Knuth shuffle or Fisher-Yates shuffle[1], is a linear-time algorithm (as opposed to the previous O(n log n) algorithm if using efficient sorting such as mergesort or heapsort), which involves moving through the pack from top to bottom, swapping each card in turn with another card from a random position in the part of the pack that has not yet been passed through (including itself). Providing that the random numbers are unbiased, this will always generate a random permutation.

Notice that great care needs to be taken in implementing the Knuth shuffle; even slight deviations from the correct algorithm will produce biased shuffles. For example, working your way through the pack swapping each card in turn with a random card from any part of the pack is an algorithm with nn different possible execution paths, yet there are only n! permutations. A counting argument based on the pigeonhole principle will clearly show that this algorithm cannot produce an unbiased shuffle, unlike the true Knuth shuffle, which has n! execution paths which match up one-to-one with the possible permutations.

Whichever algorithm is chosen, it is important that a source of truly random numbers is used as the input to the shuffling algorithm. If a biased or pseudo-random source of random numbers is used, the output shuffles may be non-random in a way that is hard to detect, but easy to exploit by someone who knows the characteristics of the "random" number source.

References
D. Aldous and P. Diaconis, "Shuffling cards and stopping times", American Mathematical Monthly 93 (1986), 333–348
Trefethen, L. N. and Trefethen, L. M. "How many shuffles to randomize a deck of cards?" Proceedings of the Royal Society London A 456, 2561–2568 (2000)

http://www.math.washington.edu/~chartier/Shuffle/
http://www2.toki.or.id/book/AlgDesignManual/BOOK/BOOK4/NODE151.HTM
WM_JAWIN 2005-11-18
  • 打赏
  • 举报
回复
原来这个乱序代码叫做跳蚤算法啊?会写,不会叫,郁闷
KiteGirl 2005-11-18
  • 打赏
  • 举报
回复
如果你要用“跳蚤”的话,下面是这个算法的一个比较完善的函数。函数写这么麻烦是因为它有个更复杂的用途。

测试代码:

Dim rndNum() As Long
ReDim rndNum(250)
也可以:ReDim rndNum(1 to 250)
'扫描域 1-125
'交换域 1-250
FleaRandom rndNum(),True,True,1,125,1,250
需要注意的是:扫描域小于交换域的情况是一种快速算法,但是它与正常算法的结果从概率角度分析是否效果一样还有待研究。曾经有人对这个快速算法提出过疑问。
这个函数的真正用途是多段用法,是相当有趣的一个东西。如果你需要给教育机构编写试卷随机生成,我可以教你怎么用。

下面是函数:

'FleaRandom Module
'KiteGirl 2005

Public Sub FleaRandom(ByRef pList() As Long, Optional ByVal pSet_Scan As Boolean = False, Optional ByVal pSet_Swap As Boolean = False, Optional ByVal pScan_Start As Long = 0, Optional ByVal pScan_End As Long = 0, Optional ByVal pSwap_Start As Long = 0, Optional pSwap_End As Long = 0)
'FleaRandom函数
'语法:FleaRandom(pList() ,[pSet_Scan,] [pSet_Swap,] [pScan_Start,] [pScan_End,] [pSwap_Start,] [pSwap_End] )
'说明:以“跳蚤算法”对序列进行乱序处理。
'参数: long pList() 必要参数。作为序列容器的数组。
' boolean pSet_Scan 可选参数。扫描域设置开关。使其为true则用户设置的扫描域参数有效。
' boolean pSet_Swap 可选参数。交换域设置开关。使其为true则用户设置的交换域参数有效。
' long pScan_Start 可选参数。扫描域开始。
' long pScan_End 可选参数。扫描域结束。
' long pSwap_Start 可选参数。交换域开始。
' long pSwap_End 可选参数。交换域结束。

'交换设置导入

Dim tSwap_Start As Long '交换域开始
Dim tSwap_End As Long '交换域结束

If pSet_Swap Then
tSwap_Start = pSwap_Start
tSwap_End = pSwap_End
Else
tSwap_Start = LBound(pList())
tSwap_End = UBound(pList())
End If

'交换范围

Dim tSwap_Count As Long '交换域元素数

tSwap_Count = (tSwap_End - tSwap_Start) + 1

'{ tSwap_End - tSwap_Start <= 2147483646 }

'交换补偿

Dim tSwap_Rep As Long '交换补偿

tSwap_Rep = tSwap_Start

'扫描设置导入

Dim tScan_Start As Long '扫描开始
Dim tScan_End As Long '扫描结束

If pSet_Scan Then
tScan_Start = pScan_Start
tScan_End = pScan_End
ElseIf (Not pSet_Scan) And pSet_Swap Then
tScan_Start = tSwap_Start
tScan_End = tSwap_End
Else
tScan_Start = LBound(pList())
tScan_End = UBound(pList())
End If

'序列扰乱

Dim tList_Index As Long '序列索引

Dim tList_Index_Sur As Long '序列索引_源
Dim tList_Index_Des As Long '序列索引_目的

For tList_Index = tScan_Start To tScan_End

tList_Index_Sur = tList_Index
tList_Index_Des = Int(Rnd * tSwap_Count) + tSwap_Rep

'交换pList(tList_Index_Sur)和pList(tList_Index_Des)

FleaRandom_ValueSwap pList(tList_Index_Sur), pList(tList_Index_Des)

Next

End Sub

Private Sub FleaRandom_ValueSwap(ByRef pA As Long, ByRef pB As Long)
'FleaRandom_ValueSwap过程
'语法:FleaRandom_ValueSwap pA, pB

Dim tTemp As Long

tTemp = pA: pA = pB: pB = tTemp

End Sub
KiteGirl 2005-11-18
  • 打赏
  • 举报
回复
呵呵!又是跳蚤算法。
northwolves 2005-11-18
  • 打赏
  • 举报
回复
Sub finds(ByVal max As Integer, ByVal num As Integer)
Dim a() As String, i As Integer, temp As Long, x As String
ReDim a(1 To max)
For i = 1 To max
a(i) = i
Next

For i = 1 To num
Randomize
temp = i + Int((max - i) * Rnd)
x = a(temp)
a(temp) = a(i)
a(i) = x
Next

ReDim Preserve a(1 To num)
MsgBox Join(a, ",")
End Sub

Private Sub Command1_Click()
finds 250, 125
End Sub
province_ 2005-11-18
  • 打赏
  • 举报
回复
dim data(249) as integer
dim i as integer,j as integer,tmp as integer

for i=0 to 249
data(i)=i+1
next

Randomize

for i=0 to 124
j=Int(250 * Rnd)
tmp=data(i)
data(i)=data(j)
data(j)=tmp
next
'循环结束则DATA(0)到DATA(124)这125个元素就是无重复随机数
rainstormmaster 2005-11-18
  • 打赏
  • 举报
回复
http://www.china-askpro.com/msg22/qa79.shtml
vbman2003 2005-11-18
  • 打赏
  • 举报
回复
探索一下论坛,这类问题特多,解决方法也多。
用集合的方法:
  Dim iCol As Collection
Dim i As Integer, index As Integer
Dim Nums

Set iCol = New Collection
For i = 1 To 125
iCol.Add i
Next

For i = 1 To iCol.Count
Randomize
index = CInt(Rnd * (iCol.Count - 1)) + 1
Nums = iCol.Item(index)
Print Nums
iCol.Remove index
Next
Set iCol = Nothing
faysky2 2005-11-18
  • 打赏
  • 举报
回复
Dim i As Integer
For i = 1 To 125
Randomize Timer
rndnum(i) = Int((250 * Rnd) + 1)
If InStr(Text1.Text, rndnum(i)) <> 0 Then
i = i - 1
Else
Text1.Text = Text1.Text & rndnum(i) & vbCrLf
End If
Next i

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧