문제
필요를 생성하는 임의의 정수 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
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
(나 Int32
보 Integer
기 때문에 그것이 더 많은 명확한이 얼마나 큰 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