Rowel Virgo
asked on
How to get random numbers with percent to show
Hi i'm creating a program in vb that can generate random numbers. the thing is i want to lessen the chance to appear the highest number.
for Example i have numbers from 1-10 (in ramdom)
Number 10 the chance to appear is 10%
Number 9 the chance to appear is 20%
Number 8 the chance to appear is 30%
etc..
here is my sample code.
I want 1,2,3,4,5 appears more often
and 6,7,8,9,10 has less chance to appears.
for Example i have numbers from 1-10 (in ramdom)
Number 10 the chance to appear is 10%
Number 9 the chance to appear is 20%
Number 8 the chance to appear is 30%
etc..
here is my sample code.
Dim R1 As New Random
Dim d1result1 As Integer = R1.Next(1, 10)
Label2.Text = d1result1.ToString
I want 1,2,3,4,5 appears more often
and 6,7,8,9,10 has less chance to appears.
So do you want random numbers or not? Because weighting some numbers means they are not random.
Well, it is pretty simple..
Module Module1
Sub Main()
Dim Generator As New Random
Dim Weights() As Long = New Long(9) {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Console.WriteLine(WeightedRandom(Weights, Generator))
Console.WriteLine(WeightedRandom(Weights, Generator))
Console.WriteLine(WeightedRandom(Weights, Generator))
Console.WriteLine(WeightedRandom(Weights, Generator))
Console.WriteLine(WeightedRandom(Weights, Generator))
Console.WriteLine(WeightedRandom(Weights, Generator))
Console.WriteLine("Done.")
Console.ReadLine()
End Sub
Function WeightedRandom(AWeights() As Long, AGenerator As Random) As Long
Dim MapCount As Long
Dim MapIndex As Long
Dim Range As Long = AWeights.Sum()
Dim WeightCount As Long
Dim Map(Range - 1) As Long
MapIndex = 0
For WeightCount = 0 To UBound(AWeights)
For MapCount = 1 To AWeights(WeightCount)
Map(MapIndex) = WeightCount
MapIndex = MapIndex + 1
Next
Next
WeightedRandom = Map(AGenerator.Next(0, Range - 1))
End Function
End Module
One way to achieve this is with an array.
The array elements will hold the chances of you number to get choosen.
The array index will be the desired number
Sample below:
Well, hope you'll get the idea.
The array elements will hold the chances of you number to get choosen.
The array index will be the desired number
Sample below:
Public Function weightedRandomNumber() As Integer
Const MIN As Integer = 1
Const MAX As Integer = 100
Dim numbers(1 To 10) As Integer
numbers(1) = 15
numbers(2) = 30
numbers(3) = 45
numbers(4) = 60
numbers(5) = 75
numbers(6) = 80
numbers(7) = 85
numbers(8) = 90
numbers(9) = 95
numbers(10) = 100
Randomize
Dim randomValue As Integer
randomValue = (MAX - MIN + 1) * Rnd + 1
Dim i As Integer
For i = 1 To 10
If (randomValue < numbers(i)) Then
weightedRandomNumber = i
Exit For
End If
Next
End Function
Ops, didn't notice it was .Net.Well, hope you'll get the idea.
@Fabrice: But it requires careful calculation of your array..
Dim Weights() As Long = New Long() {3, 1, 2} vs Dim numbers() As Long = New Long() {50, 67, 100}
p.s. it must be
Dim Weights() As Long = New Long() {3, 1, 2} vs Dim numbers() As Long = New Long() {50, 67, 100}
Module Module1
Sub Main()
Dim Generator As New Random
Dim Weights() As Long = New Long() {3, 1, 2}
Console.WriteLine(WeightedRandom(Weights, Generator))
Console.WriteLine(WeightedRandom(Weights, Generator))
Console.WriteLine(WeightedRandom(Weights, Generator))
Console.WriteLine(WeightedRandom(Weights, Generator))
Console.WriteLine(WeightedRandom(Weights, Generator))
Console.WriteLine(WeightedRandom(Weights, Generator))
Console.WriteLine(WeightedRandom(Weights, Generator))
Console.WriteLine(WeightedRandom(Weights, Generator))
Console.WriteLine(WeightedRandom(Weights, Generator))
Console.WriteLine(WeightedRandom(Weights, Generator))
Console.WriteLine("--")
Dim numbers() As Long = New Long() {50, 67, 100}
Console.WriteLine(WeightedRandom2(numbers, Generator))
Console.WriteLine(WeightedRandom2(numbers, Generator))
Console.WriteLine(WeightedRandom2(numbers, Generator))
Console.WriteLine(WeightedRandom2(numbers, Generator))
Console.WriteLine(WeightedRandom2(numbers, Generator))
Console.WriteLine(WeightedRandom2(numbers, Generator))
Console.WriteLine(WeightedRandom2(numbers, Generator))
Console.WriteLine(WeightedRandom2(numbers, Generator))
Console.WriteLine(WeightedRandom2(numbers, Generator))
Console.WriteLine(WeightedRandom2(numbers, Generator))
Console.WriteLine("Done.")
Console.ReadLine()
End Sub
Function WeightedRandom(AWeights() As Long, AGenerator As Random) As Long
Dim MapCount As Long
Dim MapIndex As Long
Dim Range As Long = AWeights.Sum()
Dim WeightCount As Long
Dim Map(Range - 1) As Long
MapIndex = 0
For WeightCount = 0 To UBound(AWeights)
For MapCount = 1 To AWeights(WeightCount)
Map(MapIndex) = WeightCount
MapIndex = MapIndex + 1
Next
Next
WeightedRandom = Map(AGenerator.Next(0, Range - 1)) + 1
End Function
Function WeightedRandom2(AWeights() As Long, AGenerator As Random) As Long
Dim index As Long
Dim randomValue As Long = AGenerator.Next(1, 100)
WeightedRandom2 = -1
For index = 0 To UBound(AWeights)
If (randomValue < AWeights(index)) Then
WeightedRandom2 = index + 1
Exit For
End If
Next
End Function
End Module
p.s. it must be
WeightedRandom = Map(AGenerator.Next(0, Range - 1)) + 1
in my function, otherwise it is off by one.
@ste5an:
@Fabrice: But it requires careful calculation of your array..Yeah, ehence why it is "one way to achieve it".
omg, still of by one, should have rtfm first, the upper boundary of Next() is exclusive:
Function WeightedRandom(AWeights() As Long, AGenerator As Random) As Long
Dim MapCount As Long
Dim MapIndex As Long
Dim Range As Long = AWeights.Sum()
Dim WeightCount As Long
Dim Map(Range - 1) As Long
MapIndex = 0
For WeightCount = 0 To UBound(AWeights)
For MapCount = 1 To AWeights(WeightCount)
Map(MapIndex) = WeightCount
MapIndex = MapIndex + 1
Next
Next
WeightedRandom = Map(AGenerator.Next(0, Range)) + 1
End Function
Function WeightedRandom2(AWeights() As Long, AGenerator As Random) As Long
Dim index As Long
Dim randomValue As Long = AGenerator.Next(1, 101)
WeightedRandom2 = -1
For index = 0 To UBound(AWeights)
If (randomValue < AWeights(index)) Then
WeightedRandom2 = index + 1
Exit For
End If
Next
End Function
I expanded your specification list and see that you might want to explain how often you see a 1
10 10%
9 20%
8 30%
7 40%
6 50%
5 60%
4 70%
3 80%
2 90%
1 100%
In a 100 of 550 cases.. or so ;)
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Just don't forget any numbers generated like this are not random. For a number to be random then it must have an equal chance with any other number in the desired range.
No comment has been added to this question in more than 21 days, so it is now classified as abandoned.
I have recommended this question be closed as follows:
Split:
-- ste5an (https:#a42539675)
-- Ark (https:#a42539448)
If you feel this question should be closed differently, post an objection and the moderators will review all objections and close it as they feel fit. If no one objects, this question will be closed automatically the way described above.
MacroShadow
Experts-Exchange Cleanup Volunteer
I have recommended this question be closed as follows:
Split:
-- ste5an (https:#a42539675)
-- Ark (https:#a42539448)
If you feel this question should be closed differently, post an objection and the moderators will review all objections and close it as they feel fit. If no one objects, this question will be closed automatically the way described above.
MacroShadow
Experts-Exchange Cleanup Volunteer