Private Sub Command1_Click()    Dim i As Integer
    For i = 1 To 1000
        Randomize
        ITEM(i) = Int(Rnd * 1000) + 1
        List1.AddItem ITEM(i)
    NextEnd Sub上面代码产生的随机数会重复,
为什么用了Randomize还会重复?

解决方案 »

  1.   

    Private Sub Command1_Click()    Dim i As Integer
        For i = 1 To 1000
            doevents
            Randomize
            ITEM(i) = Int(Rnd * 1000) + 1
            List1.AddItem ITEM(i)
            Randomize
        NextEnd Sub
      

  2.   

    Private Sub Command1_Click()
    Dim a(1000) As Integer, i As Integer, temp As Integer
        For i = 1 To 1000
        a(i) = i
        Next
        For i = 1000 To 1 Step -1
            Randomize
            temp = Int(Rnd * i) + 1
            List1.AddItem a(temp)
            a(temp) = a(i)
        Next
    End Sub
      

  3.   

    也可以用集合实现:
    Private Sub Command1_Click()
    Dim temp As New Collection, i As Long, tempi As Long
    For i = 1 To 1000
    temp.Add i
    Next
    Randomize
    For i = 1 To 1000
    tempi = Int(Rnd * temp.Count) + 1
    List1.AddItem temp(tempi)
    temp.Remove tempi
    Next
    Set temp = Nothing
    End Sub
      

  4.   

    上面代码产生的随机数会重复,
    为什么用了Randomize还会重复?
    ====================
    你想要的是不是乱序排列1~1000这一千个数?如果是则不应该用你的方法一个简单例子:
    Private Sub Command1_Click()
     Randomize
     Dim i As Integer
     Dim k As Integer
     Dim temp As Integer
     Dim a(1 To 1000) As Integer
     For i = 1 To 1000
         a(i) = i
     Next For j = 1 To 1000
        k = Int(Rnd * 1000) + 1
        temp = a(j)
        a(j) = a(k)
        a(k) = temp
      Next  For m = 1 To 1000
      List1.AddItem a(m)
      Next
    End Sub
      

  5.   

    正解:Randomize后面还要加上Timer,就是Randomize Timer
      

  6.   

    我的意见:
    Private Sub Command1_Click()
        Dim i As Integer
        For i = 1 To 1000
            Randomize Timer
            ITEM(i) = Int(Rnd * 1000) + 1
            List1.AddItem ITEM(i)
        NextEnd Sub
      

  7.   

    apple_001(天堂里的狼) 
    种子之类的可以提高随机的几率
    ----------------------------
    具体怎么提高呀?
      

  8.   

    haohaohappy() 
    向你提一个问题:为什么有了“Randomize Timer”就没有重复项了呢?
      

  9.   

    老兄,不是这样用的:1、Timer不是这样用的:这是错的:For I=1 To 1000
      Randomize Timer '这样的话,种子会随时间推移。
      R=Int(Rnd*1000)+1
    Next应该这样:Randomize Timer '之所以这样会增加随即性是因为入口时间随机。
    For I=1 To 1000
      R=Int(Rnd*1000)+1
    Next2、如果你想要随机不重复数可以用我独家的“跳蚤算法”:Dim N() As LongReDim N(1 To 1000)Randomize TimerFor I=1 To 1000
      N(I)=I
    NextFor I=1 To 1000
      S=Int(rnd*1000)+1
      T=N(I):N(I)=N(S):N(S)=T '交换N(I)和N(S)
    Next这样,N(1)到N(1000)是随机不重复序列。
      

  10.   

    正确的混排算法
    For I=[last] To [start] step -1
      idx=Int(rnd()*([last]-[start]+1))+[start]
      T=N(I):N(I)=N(idx):N(idx)=T '交换N(I)和N(idx)
    Next[start]:上界
    [last]:下界
      

  11.   

    为什么用了Randomize还会重复?
    ==============================================
    rnd()是使用线性同余发生器算法生成伪随机数的
    线性同余发生器算法主要是生成在2147483647范围内的伪随机数,它能保证一个2147483647的周期(执行2147483647次重复一趟)
    VB为了通用性,将rnd函数的返回值格式化到[0,1)区间你现在为了使数字在1000的范围内,将rnd的返回值*1000了,所以精度是1/1000
    而线性同余发生器算法又可能产生一些比较接近的数字,因1/2147483647的差距是绝对小于1/1000的误差的,这就造成了重复要解决重复问题,应该使用混排算法
      

  12.   

    打错了,是:[start]:下界
    [last]:上界
      

  13.   

    哈哈!分兄真是严谨之人,学习!其实我也是偷个小懒而已。上面的算法是“冷”的,现在来个“热”的。St = 开始
    Se = 结束
    Sl = Se - St '取相对范围
    Ng = 输出数Dim Nv() As Long    '数值
    Dim Nr() As Boolean 'Ready表ReDim Nv(0 To Sl)
    ReDim Nr(0 To Sl)Randomize TimerFor Is=0 To Ng-1
      Id=Int(rnd * Sl)  If Not Nr(Is) Then Nv(Is) = Is + St : Nr(Is) = True
      If Not Nr(Id) Then Nv(Id) = Id + St : Nr(Id) = True  Vt=Nv(Is):Nv(Is)=Nv(Id):Nv(Id)=Vt '交换N(Is)和N(Id)
    NextNv(0 To Ng-1)是随机排列。
      

  14.   

    首先,取Sl可以避免问题的复杂化。当(Ng-1) < Sl情况下,不是所有的Nv都能被访问到。所以我改进了混排方式。只将前Ng个元素做交换,这样仅保证前Ng个元素排列是随机的。在访问Nv通过Nr断定这个Nv是不是已经被初始化过值,如果没有则先初始化。这样,改进后的混排叫做“热”法。原来那个方法戏称“冷”法。两个方法缺点在于:如果St到Se范围太宽,则数组可能装不下。如果这样的话,我还有一个“虚拟数组”方法解决。可以在任意数值范围内取N个随机不重复排列(前提是N是内存可以接受的)。
      

  15.   

    小仙妹!
    好久不见了
    你好像一直是只管算法的贴子啊
    ==========================
    昏倒,又有一个打错了For I=[last] To [start] step -1
      idx=Int(rnd()*(Idx-[start]+1))+[start]
      T=N(I):N(I)=N(idx):N(idx)=T '交换N(I)和N(idx)
    Next[start]:下界
    [last]:上界“idx=Int(rnd()*(Idx-[start]+1))+[start]”的意义是在[start,idx]的范围内产生索引,这样可以在一定程度避免重复问题刚才KiteGirl(小仙妹)贴的“热”法通过设置标志数组彻底解决了重复问题。缺点是多占了点内存
      

  16.   

    我是来学习的,算法啊,USACO上面的题目都不大会做了,今天花了30分钟才搞定一道简单的!的题目……廉颇老矣!
      

  17.   

    严重感谢各位,我调试了一下.正确的答案分为两个步骤是:
    1.首先用一个for循环,将1到1000的值赋给一个数组Item()
    2.然后,再用一个For循环,每次循环产生一个随机数t=int(rnd*1000)+1,让此随机数作为 
      Item()数组的下标,并与Item(i)交换即可产生不重复的1000个随机数.也就是说,让随机数产生一个下标,随机交换这1000个数的两个数,打乱1000个数的顺序.
    因为交换位置的还是这1000个数,所以不会产生重复.Private Sub command1_click1()
       dim i as integer, t as integer, k as integer
       dim Item(1 to 1000) as integer
       for i=1 to 1000
          Item(i)=i
       next
       for i=1 to 1000
          t=int(rnd*1000)+1
          k=Item(i)
          Item(i)=Item(t)
          Item(j)=k
       next
    End Sub
      

  18.   

    你可以尝试我的“热”法,Private Sub command1_click1()
       dim i as integer, t as integer, k as integer
       dim Item(1 to 1000) as integer
       dim ItemReady(1 to 1000) as Boolean
       for i=1 to 100 '假设你只取100个数字,如果是1000个则写为1000。
          t=int(rnd*1000)
          if Not ItemReady(t) Then Item(t)=t : ItemReady(t)=true
          if Not ItemReady(i) Then Item(i)=i + 1 : ItemReady(i)=true
          k=Item(i)
          Item(i)=Item(t)
          Item(j)=k
       next
    End Sub
      

  19.   

    热法的要点是:以ItemReady数组来表示Item每个元素的初始化情况。在使用前判断它是否被初始化过,如果没有,则初始化为访问下标。这样就省略了初始化的步骤,如果你是在1000个元素里取1000个数则没有优势,但如果你是在100000个元素里取10个数,那么优势就很明显了。
      

  20.   

    伪随机数算法就这个毛病。
    初始值都是默认的同一个数所以算出来的序列都一样。
    要不停的变种子,就是那个Timer
    它返回从午夜到现在经过的秒数
    自然每一时刻都不一样了
    带进去做为初始值才可以得到真正的随机数PS:学QB时看到的
    ====生成不重复的随机数====================================================
    Const nMax = 150
    Dim a(nMax) As Integer  Randomize Timer  For i = 1 To nMax
        reCount = False
        k = Int(Rnd * nMax)
       
        For j = 1 To i - 1
          If k = a(j) Then reCount = True:   Exit For
        Next j
        
        If reCount = True Then
          i = i - 1
        Else
          a(i) = k
          'Any other you want to do.
        End If
        
      Next i就是觉得效率有点低,大家评价一下。
      

  21.   

    Private Sub Command1_Click()
      Dim tLongs() As Long
      
      tLongs = LongsSeries(1, 1000, 10) '取10个1到1000以内的不重复随机数。
      
      Text1.Text = ""
      
      For tIndex = LBound(tLongs) To UBound(tLongs)
        Text1.Text = tLongs(tIndex) & " " & Text1.Text
      Next
    End SubFunction LongsSeries(ByVal pLower As Long, ByVal pUpper As Long, Optional ByVal pGetCount As Long = 0) As Long()
      'pLower 下限
      'pUpper 上限
      'pGetCount 获取数字的数量(默认为0,取全部数列)  Dim tOutLongs() As Long
      Dim tOutLongs_Readys() As Boolean
      
      Dim tAbsLength As Long
      Dim tAbsCount As Long
      
      tAbsLength = pUpper - pLower
      tAbsCount = tAbsLength + 1
      
      ReDim tOutLongs(tAbsLength)
      ReDim tOutLongs_Readys(tAbsLength)
      
      Dim tSurIndex As Long
      Dim tDesIndex As Long
      Dim tGetCount As Long
      Dim tTempValue As Long
      
      If pGetCount Then
        tGetCount = pGetCount - 1
      End If
      If (tGetCount > tAbsLength) Or (Not CBool(pGetCount)) Then tGetCount = tAbsLength
      
      Randomize Timer
      
      For tSurIndex = 0 To tGetCount
      
        tDesIndex = Int(Rnd * tAbsCount)
        
        If Not tOutLongs_Readys(tSurIndex) Then
          tOutLongs(tSurIndex) = tSurIndex + pLower
          tOutLongs_Readys(tSurIndex) = True
        End If
        
        If Not tOutLongs_Readys(tDesIndex) Then
          tOutLongs(tDesIndex) = tDesIndex + pLower
          tOutLongs_Readys(tDesIndex) = True
        End If
        
        tTempValue = tOutLongs(tSurIndex)
        tOutLongs(tSurIndex) = tOutLongs(tDesIndex)
        tOutLongs(tDesIndex) = tTempValue
      
      Next
      
      ReDim Preserve tOutLongs(tGetCount)
      
      LongsSeries = tOutLongs()
    End Function
      

  22.   

    楼上的一大堆算法我懒得看了,不过可以告诉楼主,vb提供的随机函数也是根据当前时间
    来确定的,所以在for中时间难以改变,随机数也是一样的办法就是等待一段时间得到不同的时间才行,我记得以前用C写过的就是退出函数得到一个
    随机数,然后再调用函数得到一个