문제

필요를 생성하는 임의의 정수 1n(n 은 긍정적 인 전체 수)사용에 대한 단위 테스트입니다.난 필요 없어요 무언가가 지나치게 복잡을 위해 진정한 랜덤-그 옛날 무료로 액세스 할 수 있습니다.

어떻게 되나요?

도움이 되었습니까?

해결책

을 얻을 임의의 사이의 정수 값 1N(포함)다음을 사용할 수 있습니다.

CInt(Math.Ceiling(Rnd() * n)) + 1

다른 팁

으로 지적되었다 많은 시간,제안 코드를 작성하는 같은 이로 인해 문제가 발생합니다:

Public Function GetRandom(ByVal Min As Integer, ByVal Max As Integer) As Integer
    Dim Generator As System.Random = New System.Random()
    Return Generator.Next(Min, Max)
End Function

그 이유는 이에 대해 생성자 Random 클래스가 제공하는 기본값은 씨앗에 기반한 시스템 시계입니다.대부분의 시스템에서,이것은 제한된 단위--어딘가에 근처의 20ms.그래서 만약 당신이 다음과 같은 코드를 작성,당신을 얻을 것 같은 수의 무리는 연속 시간:

Dim randoms(1000) As Integer
For i As Integer = 0 to randoms.Length - 1
    randoms(i) = GetRandom(1, 100)
Next

다음 코드는 이러한 문제를 해결합니:

Public Function GetRandom(ByVal Min As Integer, ByVal Max As Integer) As Integer
    ' by making Generator static, we preserve the same instance '
    ' (i.e., do not create new instances with the same seed over and over) '
    ' between calls '
    Static Generator As System.Random = New System.Random()
    Return Generator.Next(Min, Max)
End Function

졌고 함께 간단한 프로그램을 모두 사용하는 방법을 생성하는 25 사이의 임의의 정수 1and100.여기에 출력:

Non-static: 70 Static: 70
Non-static: 70 Static: 46
Non-static: 70 Static: 58
Non-static: 70 Static: 19
Non-static: 70 Static: 79
Non-static: 70 Static: 24
Non-static: 70 Static: 14
Non-static: 70 Static: 46
Non-static: 70 Static: 82
Non-static: 70 Static: 31
Non-static: 70 Static: 25
Non-static: 70 Static: 8
Non-static: 70 Static: 76
Non-static: 70 Static: 74
Non-static: 70 Static: 84
Non-static: 70 Static: 39
Non-static: 70 Static: 30
Non-static: 70 Static: 55
Non-static: 70 Static: 49
Non-static: 70 Static: 21
Non-static: 70 Static: 99
Non-static: 70 Static: 15
Non-static: 70 Static: 83
Non-static: 70 Static: 26
Non-static: 70 Static: 16
Non-static: 70 Static: 75

시스템입니다.Random:

Dim MyMin As Integer = 1, MyMax As Integer = 5, My1stRandomNumber As Integer, My2ndRandomNumber As Integer

' Create a random number generator
Dim Generator As System.Random = New System.Random()

' Get a random number >= MyMin and <= MyMax
My1stRandomNumber = Generator.Next(MyMin, MyMax + 1) ' Note: Next function returns numbers _less than_ max, so pass in max + 1 to include max as a possible value

' Get another random number (don't create a new generator, use the same one)
My2ndRandomNumber = Generator.Next(MyMin, MyMax + 1)

모든 답변이 지금까지 문제 또는 버그(복수,단지 하나의).설명할 것입니다.하지만 먼저 내가 원하는 칭찬 Tao Dan 통찰력을 사용하여 정적 변수를 기억하는 발전기 변수 그래서 그것을 여러 번 반복되지 않습니다 동#고,플러스 그는 아주 좋은 설명이 있습니다.하지만 그의 코드를 겪었 같은 결함이 있는 대부분의 다른 사람에,내가 지금 설명하.

MS 들은 다음()메소드는 오히려 이상한.Min 매개 변수를 포함한 최소 하나로서 기대하는 것이지만,Max 매개변수 최대 하나로서 기대하지 않을 것이다.다른 말로 하면,당신이 통과 분=1max=5 다음의 임의의 숫자는 모든 1,2,3,4,그러나 그것은 결코 포함 5.이것은 첫 번째 두 개의 잠재적 버그에서 모든 코드를 사용하여 Microsoft 의 랜덤입니다.다음()메소드가 있습니다.

답변(하지만 여전히 가능하지만 다른 희귀 문제)그럼 당신이 사용할 필요가:

Private Function GenRandomInt(min As Int32, max As Int32) As Int32
    Static staticRandomGenerator As New System.Random
    Return staticRandomGenerator.Next(min, max + 1)
End Function

(나 Int32Integer 기 때문에 그것이 더 많은 명확한이 얼마나 큰 int 은,플러스 그것은 짧은 형식이지만,자신에 맞게.)

나는 두 개의 잠재적인 문제는 이 방법으로만 될 것입니다 적절한(및 정확한)대부분의 사용합니다.그래서 만약 당신이 원 솔루션이 올바른 것입니다.

만 2 이 기능:1:때 Max=Int32.MaxValue 도 추가 1 만듭니다 숫자 오버플로우가 발생합니다.사이 희소하고,그것은 여전히 가능성이다.2:할 때 분>최대+1 입니다.최소=10max=5 다음 함수는 오류가 발생합니다.이 될 수 있습니다.하지만 그것을 할 수 없다.을 고려할 때 분=5max=4.을 추가해서 1,5 전달한 다음 방법이지만,그것은 오류는 발생하지 않습니다,할 때 그것은 정말 오류가 있지만,Microsoft.순 코드는 내가 테스트를 반환합 5.그래서 그것은 정말 아는'특별한'max 때 max=min.하지만 최대 < 최 무작위입니다.다음()함수,다음 그것을 던져 ArgumentOutOfRangeException.그래서 Microsoft 의 구현은 정말 일치하지 않고도 이와 관련하여.

할 수 있는 단순히 번호를 교환할 때 분>최대 그래서 오류가 발생하지 않습니다,하지만 그것은 완전히 무엇에 따라 달라집니다.당신이 원하는 경우에 오류가 잘못된 값,그것은 아마 더 나은 또한 던져 오류를 때 마이크로소프트의 독점적 인 최대(max+1)에서 우리의 코드 같 최소 MS 실패에 오류가 이 경우입니다.

처리에 대한 때 max=Int32.MaxValue 은 작은 불편하지만,제가 기대하는 게시물에 대한 철저한 기능을 모두 처리한 이러한 상황입니다.고 당신이 원하는 경우 다른 행동을 보다 어떻게 코딩,그것에 맞게 자신입니다.하지만 이 2 개의 문제입니다.

행복한 코딩!

편집:그래서 나는 데 필요한 임의의 정수 발전기,그리고 내가 결정하는 코드'권리'.그래서 누군가가 원하는 기능을,여기에는 하나 실제로 작동합니다.(그러나 그것은 승리를 하지 않는 가장 간단한 상품으로 2 줄의 코드입니다.하지만 그것이 정말로 복잡하다.)

''' <summary>
''' Generates a random Integer with any (inclusive) minimum or (inclusive) maximum values, with full range of Int32 values.
''' </summary>
''' <param name="inMin">Inclusive Minimum value. Lowest possible return value.</param>
''' <param name="inMax">Inclusive Maximum value. Highest possible return value.</param>
''' <returns></returns>
''' <remarks></remarks>
Private Function GenRandomInt(inMin As Int32, inMax As Int32) As Int32
    Static staticRandomGenerator As New System.Random
    If inMin > inMax Then Dim t = inMin : inMin = inMax : inMax = t
    If inMax < Int32.MaxValue Then Return staticRandomGenerator.Next(inMin, inMax + 1)
    ' now max = Int32.MaxValue, so we need to work around Microsoft's quirk of an exclusive max parameter.
    If inMin > Int32.MinValue Then Return staticRandomGenerator.Next(inMin - 1, inMax) + 1 ' okay, this was the easy one.
    ' now min and max give full range of integer, but Random.Next() does not give us an option for the full range of integer.
    ' so we need to use Random.NextBytes() to give us 4 random bytes, then convert that to our random int.
    Dim bytes(3) As Byte ' 4 bytes, 0 to 3
    staticRandomGenerator.NextBytes(bytes) ' 4 random bytes
    Return BitConverter.ToInt32(bytes, 0) ' return bytes converted to a random Int32
End Function
Public Function RandomNumber(ByVal n As Integer) As Integer
    'initialize random number generator
    Dim r As New Random(System.DateTime.Now.Millisecond)
    Return r.Next(1, n)
End Function

Microsoft 예 Rnd 기능

https://msdn.microsoft.com/en-us/library/f7s023d2%28v=vs.90%29.aspx

1-임의의 초기화 번호 생성기입니다.

Randomize()

2-생성하는 임의의 값은 1~6.

Dim value As Integer = CInt(Int((6 * Rnd()) + 1))

를 사용하는 경우 요셉의 대답은 훌륭한 대답하고,당신을 실행한 다시 다시 다음과 같다:

dim i = GetRandom(1, 1715)
dim o = GetRandom(1, 1715)

그 결과 다시 올 수 있습과정을 처리하기 때문에 이 호출됩니다.이되지 않았을 수 있습 문제에서'08 지만,이후 프로세서는 훨씬 빠르게 오늘날 기능을 허용하지 않는 시스템 시계가 충분한 시간을 변경 하기 전에 두 번째 호출합니다.

이 시스템입니다.Random()함수에 기반한 시스템 시계가 필요할 수 있는 시간을 충분히 확보하는 그것을 변경하기 전에 다음 호출합니다.조건을 만족하는 방법은 이 일시 중지 현재 스레드가 1 밀리세컨드.아래 내용을 살펴보세요:

Public Function GetRandom(ByVal min as Integer, ByVal max as Integer) as Integer
    Static staticRandomGenerator As New System.Random
    max += 1
    Return staticRandomGenerator.Next(If(min > max, max, min), If(min > max, min, max))
End Function

을 만들어야 합니다 의사 난수 발전기 한 번만:

Dim Generator As System.Random = New System.Random()

그러면 정수기에 충분의 요구에 대한 사용할 수 있습니다:

Public Function GetRandom(myGenerator As System.Random, ByVal Min As Integer, ByVal Max As Integer) As Integer
'min is inclusive, max is exclusive (dah!)
Return myGenerator.Next(Min, Max + 1)
End Function

으로 많은 수 있습니다.를 사용하는 래퍼 기능은 정당화된 때문에 최대 값을 독점-나가 알고 있는 임의의 숫자는 이러한 방식으로 작동하지만 정니다.다음입니다.

을 만드는 발전기에 필요한 모든 시간을 당신 수은 내 생각에 잘못된;회사-임의의 숫자 작동하지 않는 이 방법입니다.

첫째,당신이 얻는 문제를 초기화 된 논의에서 다른 대답.면 초기화 한 번,당신은 이러한 문제를 가지고 있지 않습니다.

두 번째,내가지는 것을 저는 확신을 얻을 올바른 순서의 임의의 숫자를;오히려 당신의 첫 번째 숫자는 여러 개의 서로 다른 시퀀스는 씨를 뿌리에 따라 자동으로 컴퓨터 시간입니다.나는 특정하지 않는 이 번호를 전달하는 테스트를 확인 임의의 시퀀스입니다.

Dim rnd As Random = New Random
rnd.Next(n)

그냥 참고,VB,.NET 기능에 대한 정의 RND 고 무작위(을 제공해야 하는 같은 결과를 기초(1980 년)및 이후 모든 버전입니다:

Public NotInheritable Class VBMath
    ' Methods
    Private Shared Function GetTimer() As Single
        Dim now As DateTime = DateTime.Now
        Return CSng((((((60 * now.Hour) + now.Minute) * 60) + now.Second) + (CDbl(now.Millisecond) / 1000)))
    End Function

    Public Shared Sub Randomize()
        Dim timer As Single = VBMath.GetTimer
        Dim projectData As ProjectData = ProjectData.GetProjectData
        Dim rndSeed As Integer = projectData.m_rndSeed
        Dim num3 As Integer = BitConverter.ToInt32(BitConverter.GetBytes(timer), 0)
        num3 = (((num3 And &HFFFF) Xor (num3 >> &H10)) << 8)
        rndSeed = ((rndSeed And -16776961) Or num3)
        projectData.m_rndSeed = rndSeed
    End Sub

    Public Shared Sub Randomize(ByVal Number As Double)
        Dim num2 As Integer
        Dim projectData As ProjectData = ProjectData.GetProjectData
        Dim rndSeed As Integer = projectData.m_rndSeed
        If BitConverter.IsLittleEndian Then
            num2 = BitConverter.ToInt32(BitConverter.GetBytes(Number), 4)
        Else
            num2 = BitConverter.ToInt32(BitConverter.GetBytes(Number), 0)
        End If
        num2 = (((num2 And &HFFFF) Xor (num2 >> &H10)) << 8)
        rndSeed = ((rndSeed And -16776961) Or num2)
        projectData.m_rndSeed = rndSeed
    End Sub

    Public Shared Function Rnd() As Single
        Return VBMath.Rnd(1!)
    End Function

    Public Shared Function Rnd(ByVal Number As Single) As Single
        Dim projectData As ProjectData = ProjectData.GetProjectData
        Dim rndSeed As Integer = projectData.m_rndSeed
        If (Number <> 0) Then
            If (Number < 0) Then
                Dim num1 As UInt64 = (BitConverter.ToInt32(BitConverter.GetBytes(Number), 0) And &HFFFFFFFF)
                rndSeed = CInt(((num1 + (num1 >> &H18)) And CULng(&HFFFFFF)))
            End If
            rndSeed = CInt((((rndSeed * &H43FD43FD) + &HC39EC3) And &HFFFFFF))
        End If
        projectData.m_rndSeed = rndSeed
        Return (CSng(rndSeed) / 1.677722E+07!)
    End Function

End Class

동 Random 클래스:

Public Class Random
    ' Methods
    <__DynamicallyInvokable> _
    Public Sub New()
        Me.New(Environment.TickCount)
    End Sub

    <__DynamicallyInvokable> _
    Public Sub New(ByVal Seed As Integer)
        Me.SeedArray = New Integer(&H38  - 1) {}
        Dim num4 As Integer = If((Seed = -2147483648), &H7FFFFFFF, Math.Abs(Seed))
        Dim num2 As Integer = (&H9A4EC86 - num4)
        Me.SeedArray(&H37) = num2
        Dim num3 As Integer = 1
        Dim i As Integer
        For i = 1 To &H37 - 1
            Dim index As Integer = ((&H15 * i) Mod &H37)
            Me.SeedArray(index) = num3
            num3 = (num2 - num3)
            If (num3 < 0) Then
                num3 = (num3 + &H7FFFFFFF)
            End If
            num2 = Me.SeedArray(index)
        Next i
        Dim j As Integer
        For j = 1 To 5 - 1
            Dim k As Integer
            For k = 1 To &H38 - 1
                Me.SeedArray(k) = (Me.SeedArray(k) - Me.SeedArray((1 + ((k + 30) Mod &H37))))
                If (Me.SeedArray(k) < 0) Then
                    Me.SeedArray(k) = (Me.SeedArray(k) + &H7FFFFFFF)
                End If
            Next k
        Next j
        Me.inext = 0
        Me.inextp = &H15
        Seed = 1
    End Sub

    Private Function GetSampleForLargeRange() As Double
        Dim num As Integer = Me.InternalSample
        If ((Me.InternalSample Mod 2) = 0) Then
            num = -num
        End If
        Dim num2 As Double = num
        num2 = (num2 + 2147483646)
        Return (num2 / 4294967293)
    End Function

    Private Function InternalSample() As Integer
        Dim inext As Integer = Me.inext
        Dim inextp As Integer = Me.inextp
        If (++inext >= &H38) Then
            inext = 1
        End If
        If (++inextp >= &H38) Then
            inextp = 1
        End If
        Dim num As Integer = (Me.SeedArray(inext) - Me.SeedArray(inextp))
        If (num = &H7FFFFFFF) Then
            num -= 1
        End If
        If (num < 0) Then
            num = (num + &H7FFFFFFF)
        End If
        Me.SeedArray(inext) = num
        Me.inext = inext
        Me.inextp = inextp
        Return num
    End Function

    <__DynamicallyInvokable> _
    Public Overridable Function [Next]() As Integer
        Return Me.InternalSample
    End Function

    <__DynamicallyInvokable> _
    Public Overridable Function [Next](ByVal maxValue As Integer) As Integer
        If (maxValue < 0) Then
            Dim values As Object() = New Object() { "maxValue" }
            Throw New ArgumentOutOfRangeException("maxValue", Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", values))
        End If
        Return CInt((Me.Sample * maxValue))
    End Function

    <__DynamicallyInvokable> _
    Public Overridable Function [Next](ByVal minValue As Integer, ByVal maxValue As Integer) As Integer
        If (minValue > maxValue) Then
            Dim values As Object() = New Object() { "minValue", "maxValue" }
            Throw New ArgumentOutOfRangeException("minValue", Environment.GetResourceString("Argument_MinMaxValue", values))
        End If
        Dim num As Long = (maxValue - minValue)
        If (num <= &H7FFFFFFF) Then
            Return (CInt((Me.Sample * num)) + minValue)
        End If
        Return (CInt(CLng((Me.GetSampleForLargeRange * num))) + minValue)
    End Function

    <__DynamicallyInvokable> _
    Public Overridable Sub NextBytes(ByVal buffer As Byte())
        If (buffer Is Nothing) Then
            Throw New ArgumentNullException("buffer")
        End If
        Dim i As Integer
        For i = 0 To buffer.Length - 1
            buffer(i) = CByte((Me.InternalSample Mod &H100))
        Next i
    End Sub

    <__DynamicallyInvokable> _
    Public Overridable Function NextDouble() As Double
        Return Me.Sample
    End Function

    <__DynamicallyInvokable> _
    Protected Overridable Function Sample() As Double
        Return (Me.InternalSample * 4.6566128752457969E-10)
    End Function


    ' Fields
    Private inext As Integer
    Private inextp As Integer
    Private Const MBIG As Integer = &H7FFFFFFF
    Private Const MSEED As Integer = &H9A4EC86
    Private Const MZ As Integer = 0
    Private SeedArray As Integer()
End Class
Function xrand() As Long
        Dim r1 As Long = Now.Day & Now.Month & Now.Year & Now.Hour & Now.Minute & Now.Second & Now.Millisecond
        Dim RAND As Long = Math.Max(r1, r1 * 2)
        Return RAND
End Function

[BBOYSE] 이것이 최선의 방법에서 스크래치:P

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top