ExcelBanter

ExcelBanter (https://www.excelbanter.com/)
-   Excel Programming (https://www.excelbanter.com/excel-programming/)
-   -   Shuffle Array (https://www.excelbanter.com/excel-programming/338073-shuffle-array.html)

Rik Smith[_2_]

Shuffle Array
 
Hello all,

I usually find the answers I'm looking for without having to post them. So
I'd like to thank you all for all the help you've given me, you have no idea
how helpful you've been.

Since I'm relatively new at this, I was wondering if there was a better way
to (pseudo)randomly shuffle an array than what I've come up with. The code
is posted below. If any of you have some advice, I'd love to hear it.
Thanks!

Sub BuildAlistArr()

Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False

Dim arrAList As Variant, arrRnd As Variant, arrBList As Variant
Dim i As Long, j As Long
Dim flag As Boolean
Dim x As Long, y As Long, z As Long

With Worksheets("Sheet1")
With .Range("AList")
ReDim arrAList(.Cells.Count - 1)
For i = LBound(arrAList) To UBound(arrAList)
arrAList(i) = .Cells(i + 1)
Next
End With

x = LBound(arrAList)
y = UBound(arrAList)
z = y - x

ReDim arrRnd(y)
ReDim arrBList(y)

Randomize
For i = x To y
Do
arrRnd(i) = Int((y - x + 1) * Rnd + x) 'Unique Random Number
For j = x To i
flag = False
If arrRnd(i) = arrRnd(j) And i < j Then
flag = True
Exit For
End If
Next
Loop Until Not flag
arrBList(i) = arrAList(arrRnd(i))
.Cells(i + 2, 3).Value = arrBList(i)
Next
End With
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub

Tom Ogilvy

Shuffle Array
 
if you want the shuffled list to the right of the Alist

Sub ABC()
Dim v As Variant
With Worksheets("Sheet1")
With .Range("AList")
v = .Value
.Offset(0, 1).Formula = "=Rand()"
.Resize(, 2).Sort Key1:=.Offset(0, 1)
.Offset(0, 1).Value = .Value
.Value = v
End With
End With
End Sub
--
Regards,
Tom Ogilvy

"Rik Smith" wrote in message
...
Hello all,

I usually find the answers I'm looking for without having to post them.

So
I'd like to thank you all for all the help you've given me, you have no

idea
how helpful you've been.

Since I'm relatively new at this, I was wondering if there was a better

way
to (pseudo)randomly shuffle an array than what I've come up with. The

code
is posted below. If any of you have some advice, I'd love to hear it.
Thanks!

Sub BuildAlistArr()

Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False

Dim arrAList As Variant, arrRnd As Variant, arrBList As Variant
Dim i As Long, j As Long
Dim flag As Boolean
Dim x As Long, y As Long, z As Long

With Worksheets("Sheet1")
With .Range("AList")
ReDim arrAList(.Cells.Count - 1)
For i = LBound(arrAList) To UBound(arrAList)
arrAList(i) = .Cells(i + 1)
Next
End With

x = LBound(arrAList)
y = UBound(arrAList)
z = y - x

ReDim arrRnd(y)
ReDim arrBList(y)

Randomize
For i = x To y
Do
arrRnd(i) = Int((y - x + 1) * Rnd + x) 'Unique Random Number
For j = x To i
flag = False
If arrRnd(i) = arrRnd(j) And i < j Then
flag = True
Exit For
End If
Next
Loop Until Not flag
arrBList(i) = arrAList(arrRnd(i))
.Cells(i + 2, 3).Value = arrBList(i)
Next
End With
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub




Rik Smith[_2_]

Shuffle Array
 
Tom, as always, you come up with the more efficient answer. The only thing
faster than your answer is your code. Monumentally faster than mine! Would
I be pushing my luck to challenge you to try again and keep it all in VBA
just for (my)learning's sake?

"Tom Ogilvy" wrote:

if you want the shuffled list to the right of the Alist

Sub ABC()
Dim v As Variant
With Worksheets("Sheet1")
With .Range("AList")
v = .Value
.Offset(0, 1).Formula = "=Rand()"
.Resize(, 2).Sort Key1:=.Offset(0, 1)
.Offset(0, 1).Value = .Value
.Value = v
End With
End With
End Sub
--
Regards,
Tom Ogilvy

"Rik Smith" wrote in message
...
Hello all,

I usually find the answers I'm looking for without having to post them.

So
I'd like to thank you all for all the help you've given me, you have no

idea
how helpful you've been.

Since I'm relatively new at this, I was wondering if there was a better

way
to (pseudo)randomly shuffle an array than what I've come up with. The

code
is posted below. If any of you have some advice, I'd love to hear it.
Thanks!

Sub BuildAlistArr()

Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False

Dim arrAList As Variant, arrRnd As Variant, arrBList As Variant
Dim i As Long, j As Long
Dim flag As Boolean
Dim x As Long, y As Long, z As Long

With Worksheets("Sheet1")
With .Range("AList")
ReDim arrAList(.Cells.Count - 1)
For i = LBound(arrAList) To UBound(arrAList)
arrAList(i) = .Cells(i + 1)
Next
End With

x = LBound(arrAList)
y = UBound(arrAList)
z = y - x

ReDim arrRnd(y)
ReDim arrBList(y)

Randomize
For i = x To y
Do
arrRnd(i) = Int((y - x + 1) * Rnd + x) 'Unique Random Number
For j = x To i
flag = False
If arrRnd(i) = arrRnd(j) And i < j Then
flag = True
Exit For
End If
Next
Loop Until Not flag
arrBList(i) = arrAList(arrRnd(i))
.Cells(i + 2, 3).Value = arrBList(i)
Next
End With
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub





Tom Ogilvy

Shuffle Array
 
Use Donald Knuth's algorithm for a single pass shuffle.

Sub RandomizeRange()
Dim rng As Range
Set rng = Range("AList")
varr = Application.Transpose(rng)
varr1 = ShuffleArray(varr)
rws = UBound(varr1, 1) - LBound(varr1, 1) + 1
ReDim varr2(1 To rws, 1 To 1)
j = 1
For i = LBound(varr1) To UBound(varr1)
varr2(j, 1) = varr1(i)
j = j + 1
Next
rng.Offset(0, 1).Value = varr2
End Sub

Public Function ShuffleArray(varr)

'
' Algorithm from:
' The Art of Computer Programming: _
' SemiNumerical Algorithms Vol 2, 2nd Ed.
' Donald Knuth
' p. 139
'
'
Dim List() As Long
Dim t As Long
Dim i As Long
Dim j As Long
Dim k As Long
Dim lngTemp As Long

t = UBound(varr, 1) - LBound(varr, 1) + 1
ReDim List(1 To t)
For i = 1 To t
List(i) = varr(i)
Next
j = t
Randomize
For i = 1 To t
k = Rnd() * j + 1
lngTemp = List(j)
List(j) = List(k)
List(k) = lngTemp
j = j - 1
Next
ShuffleArray = List
End Function


--
Regards,
Tom Ogilvy

"Rik Smith" wrote in message
...
Tom, as always, you come up with the more efficient answer. The only

thing
faster than your answer is your code. Monumentally faster than mine!

Would
I be pushing my luck to challenge you to try again and keep it all in VBA
just for (my)learning's sake?

"Tom Ogilvy" wrote:

if you want the shuffled list to the right of the Alist

Sub ABC()
Dim v As Variant
With Worksheets("Sheet1")
With .Range("AList")
v = .Value
.Offset(0, 1).Formula = "=Rand()"
.Resize(, 2).Sort Key1:=.Offset(0, 1)
.Offset(0, 1).Value = .Value
.Value = v
End With
End With
End Sub
--
Regards,
Tom Ogilvy

"Rik Smith" wrote in message
...
Hello all,

I usually find the answers I'm looking for without having to post

them.
So
I'd like to thank you all for all the help you've given me, you have

no
idea
how helpful you've been.

Since I'm relatively new at this, I was wondering if there was a

better
way
to (pseudo)randomly shuffle an array than what I've come up with. The

code
is posted below. If any of you have some advice, I'd love to hear it.
Thanks!

Sub BuildAlistArr()

Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False

Dim arrAList As Variant, arrRnd As Variant, arrBList As Variant
Dim i As Long, j As Long
Dim flag As Boolean
Dim x As Long, y As Long, z As Long

With Worksheets("Sheet1")
With .Range("AList")
ReDim arrAList(.Cells.Count - 1)
For i = LBound(arrAList) To UBound(arrAList)
arrAList(i) = .Cells(i + 1)
Next
End With

x = LBound(arrAList)
y = UBound(arrAList)
z = y - x

ReDim arrRnd(y)
ReDim arrBList(y)

Randomize
For i = x To y
Do
arrRnd(i) = Int((y - x + 1) * Rnd + x) 'Unique Random Number
For j = x To i
flag = False
If arrRnd(i) = arrRnd(j) And i < j Then
flag = True
Exit For
End If
Next
Loop Until Not flag
arrBList(i) = arrAList(arrRnd(i))
.Cells(i + 2, 3).Value = arrBList(i)
Next
End With
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub







Rik Smith[_2_]

Shuffle Array
 
Works like a charm. Thanks for the insight!

"Tom Ogilvy" wrote:

Use Donald Knuth's algorithm for a single pass shuffle.

Sub RandomizeRange()
Dim rng As Range
Set rng = Range("AList")
varr = Application.Transpose(rng)
varr1 = ShuffleArray(varr)
rws = UBound(varr1, 1) - LBound(varr1, 1) + 1
ReDim varr2(1 To rws, 1 To 1)
j = 1
For i = LBound(varr1) To UBound(varr1)
varr2(j, 1) = varr1(i)
j = j + 1
Next
rng.Offset(0, 1).Value = varr2
End Sub

Public Function ShuffleArray(varr)

'
' Algorithm from:
' The Art of Computer Programming: _
' SemiNumerical Algorithms Vol 2, 2nd Ed.
' Donald Knuth
' p. 139
'
'
Dim List() As Long
Dim t As Long
Dim i As Long
Dim j As Long
Dim k As Long
Dim lngTemp As Long

t = UBound(varr, 1) - LBound(varr, 1) + 1
ReDim List(1 To t)
For i = 1 To t
List(i) = varr(i)
Next
j = t
Randomize
For i = 1 To t
k = Rnd() * j + 1
lngTemp = List(j)
List(j) = List(k)
List(k) = lngTemp
j = j - 1
Next
ShuffleArray = List
End Function


--
Regards,
Tom Ogilvy

"Rik Smith" wrote in message
...
Tom, as always, you come up with the more efficient answer. The only

thing
faster than your answer is your code. Monumentally faster than mine!

Would
I be pushing my luck to challenge you to try again and keep it all in VBA
just for (my)learning's sake?

"Tom Ogilvy" wrote:

if you want the shuffled list to the right of the Alist

Sub ABC()
Dim v As Variant
With Worksheets("Sheet1")
With .Range("AList")
v = .Value
.Offset(0, 1).Formula = "=Rand()"
.Resize(, 2).Sort Key1:=.Offset(0, 1)
.Offset(0, 1).Value = .Value
.Value = v
End With
End With
End Sub
--
Regards,
Tom Ogilvy

"Rik Smith" wrote in message
...
Hello all,

I usually find the answers I'm looking for without having to post

them.
So
I'd like to thank you all for all the help you've given me, you have

no
idea
how helpful you've been.

Since I'm relatively new at this, I was wondering if there was a

better
way
to (pseudo)randomly shuffle an array than what I've come up with. The
code
is posted below. If any of you have some advice, I'd love to hear it.
Thanks!

Sub BuildAlistArr()

Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False

Dim arrAList As Variant, arrRnd As Variant, arrBList As Variant
Dim i As Long, j As Long
Dim flag As Boolean
Dim x As Long, y As Long, z As Long

With Worksheets("Sheet1")
With .Range("AList")
ReDim arrAList(.Cells.Count - 1)
For i = LBound(arrAList) To UBound(arrAList)
arrAList(i) = .Cells(i + 1)
Next
End With

x = LBound(arrAList)
y = UBound(arrAList)
z = y - x

ReDim arrRnd(y)
ReDim arrBList(y)

Randomize
For i = x To y
Do
arrRnd(i) = Int((y - x + 1) * Rnd + x) 'Unique Random Number
For j = x To i
flag = False
If arrRnd(i) = arrRnd(j) And i < j Then
flag = True
Exit For
End If
Next
Loop Until Not flag
arrBList(i) = arrAList(arrRnd(i))
.Cells(i + 2, 3).Value = arrBList(i)
Next
End With
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub








All times are GMT +1. The time now is 12:34 PM.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
ExcelBanter.com