|
-
Jan 12th, 2020, 04:11 PM
#1
Thread Starter
Junior Member
Randomising (an array) without repeats VB.net
I hope it's okay to post a solution without a query!
Last week, I wanted to randomise the order of an array (of FileInfo that defaults to numero-alpha order), so needed a way of generating random index numbers without repeating any. I couldn't find a very good solution online so came up with this. I thought it's pretty good (though no doubt could be more elegantly written), so wanted to share it somewhere should it help somebody sometime.
**************************************************************************************************** ********
To randomise the order of the items in an array (or similar).
Create a list the same length as the array and populate it with the numbers of indexes i.e. index(0)=0, index(1)=1 etc
Derive a random number then use that number to draw another number from the list – use it before removing it from the list.
This means we can have repeated random numbers, but the numbers actually used cannot be repeated.
For example:
(0) = 0; (1) = 1; (2) = 2; (3) = 3
2 is picked at random (from the range 0 to 3) so copy item 2 (number 2) from the array and put it into item 0. Delete item 2.
Now:
(0) = 0; (1)=1; (2)=3
2 is picked at random again (from the range 0 to 2), so copy item 2 (number 3) from the array and put it into item 1. Delete item 2.
Now:
(0) = 0; (1)=1
0 is picked at random (from the range 0 to 1), so copy item 0 (number 0) from the array and put it into item 2. Delete item 0.
Etc.
**************************************************************************************************** ********
Code:
Private Sub shuffle_Arr()
Dim i As Integer = myArray.Length - 1 'how big the global array is
Dim tmp_List As New List(Of Integer)(i) 'a temporary list for random numbers
Dim myArray_2(i) 'a temporary array to cache the random items
Dim rnum As Integer = 0 'each random number
Dim tmpRnd As Integer = 0 'the number taken from the array randomly
Dim temp As FileInfo 'temporary item of whatever type
Dim s As Integer = 0 'to count with
Dim g As Integer = 0 'to count with
While s <= 9 'populate the list with the number of its reference i.e. f(0) = 0, f(1) = 1 etc
tmp_List.Add(s)
s += 1 's counts up to the length of the list
End While
s -= 1 's is now list length -1
For Each f In myArray 'a global array
rnum = genRand(0, s) 'random number is 0 to size of list of numbers (and array)
tmpRnd = tmp_List(rnum) 'grab a number at random.
temp = myArray(tmpRnd) 'temp is randomly taken from the array
myArray_2(g) = temp 'populate temporary array from 0 up
tmp_List.RemoveAt(rnum) 'remove the used number – this can be done with a list. This means that the index can be repeated, but the items against the indexes are unique.
g += 1 'count up through myArray_2
s = s - 1 'count down as we loop round
Next
ReDim myArray(i + 1) 'clear the array
myArray = myArray_2.Clone 'clone it from the randomised version.
End Sub
Private Function genRand(min As Int32, max As Int32) As Int32
Static rnum2 As New Random
Return rnum2.Next(min, max + 1)
End Function
Last edited by Shaggy Hiker; Jan 13th, 2020 at 03:01 PM.
Reason: Added CODE tags.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|