Melona380 - 1 year ago 65
Vb.net Question

# Visual Basic Divide Double Randomly based on Divisor

Ok, so I want to divide a number randomly not evenly...
so lets say we have 20 I need 5 (Divisor) random chunks of 20.

4 4 4 4 4

6 2 4 3 5

It cant exceed the starting number

How can this be accomplished in vb?

``````Public Iterator Function DivideUp(ByVal Number As Integer, ByVal Groups As Integer, Optional ByVal Variance As Integer = 5) As IEnumerable(Of Integer)
Dim rnd As New Random()

While Groups > 0 AndAlso Number > 0
If Groups = 1 Then
Yield Number
Exit Function
End If
If Variance > Number - Groups Then Variance = Number - Groups

Dim temp As Integer = Number / Groups
temp += rnd.Next(Variance * -1, Variance)

Yield temp
Number -= temp
Groups -= 1
End While
End Function
``````

Call it like this:

``````For Each num As Integer In DivideUp(20, 5)
Console.WriteLine(num)
Next
``````

Something more conventional:

``````Public Function DivideUp(ByVal Number As Integer, ByVal Groups As Integer, Optional ByVal Variance As Integer = 5) As Integer()
Static rnd As New Random()

Dim result(Groups-1) As Integer
For i As Integer = 0 To Groups - 1
If Variance > Number - Groups Then Variance = Number - Groups
If i = Groups - 1 Then
result(i) = Number
Else
Dim temp As Integer = Number / Groups
temp += rnd.Next(Variance * -1, Variance)
result(i) = temp
Number -= temp
End If
Next i
Return result
End Function
``````

If you want to get real fancy, you could use a log or natural log of your random variance to try make it more likely to stay closer to the median, ie: if your number divides evenly into groups of 4, do you want it to be rarer to see a 2 than a 3, rarer to see a 1 than a 2?

Finally, a test harness:

``````Dim errorCount As Integer = 0
For i As Integer = 0 To 10000
Dim items = DivideUp(100, 12)
Dim sum As Integer = 0
For Each j As Integer In items
Console.Write(j)
Console.Write(" ")
sum += j
Next j
Console.WriteLine("Total: {0}", sum)
If sum <> 100 Then
errorCount += 1
Dim tempColor = Console.ForegroundColor
Console.ForegroundColor = ConsoleColor.Red
Console.WriteLine("Error: incorrect total!")
Console.ForegroundColor = tempColor
End If
Next i
If errorCount > 0 Then
Dim tempColor = Console.ForegroundColor
Console.ForegroundColor = ConsoleColor.Red
Console.WriteLine("Error: incorrect total on {0} tries!")
Console.ForegroundColor = tempColor
End If
``````

If you're working with real money, you need to use a cryptographic random number generator (the simple `Random` type won't cut it) and you want to actually save each of these results (plus run it more like a few million times than just 10,000). Then you pull that data into something like R and graph your distributions, to make sure things flat (evenly distributed) with no visible bias. And you have to do this for a number of different Number/Group/Variance combinations. Failure to rigorously validate the randomness the purge any bias will result in someone gaming your system to win much more often than they should.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download