Page 1 of 1

### Unique random choice based on weighted array

Posted: 03 Dec 2017, 07:09
I need a unique random choice algorithm based on a weighted array. For example My_choices := [Blue,Green,Red,Yellow] is the array of my choices and Weighted_array := [2,5,36,67] is the weighted array of my choices. How to modify the VxE's code in order to get what I want?

Code: Select all

``````Random,, % A_Now ^ A_TickCount ; as good as any seed
Blue = 36
green = 2
red = 13
yellow = 49
VarsListItDo =
( ltrim
Blue
Green
Red
Yellow
)
F5::MsgBox % WeightedRandomVarName(VarsListItDo)

WeightedRandomVarName( list )
{
Local R := 0 ; Global everything else
Loop, Parse, list, `n, `r %A_Tab%
R += Abs(%A_LoopField%) ; Abs() was required here... I don't know why
Random, R, 0, % R
Loop, Parse, list, `n, `r %A_Tab%
If ( 0 >= R -= %A_LoopField% )
Return A_LoopField
}
``````
Menixator has a solution for unique random choice. I want to combine these two algorithm but I need to do it dynamically using arrays since my choices and weighted arrays are coming from lengthy sqlite queries.

Code: Select all

``````Choices := ["glow stick", "needle", "stop sign", "blouse", "hanger", "rubber duck", "shovel", "bookmark", "model car", "tampon", "rubber band", "tire swing", "sharpie", "picture frame", "photo album", "nail filer", "tooth paste", "bath fizzers", "tissue box", "deodorant ", "cookie jar", "rusty nail", "drill press", "chalk", "word search", "thermometer ", "face wash", "paint brush", "candy wrapper", "shoe lace", "leg warmers", "wireless control", "boom box", "quilt", "stockings", "card", "tooth pick", "shawl", "speakers ", "key chain", "cork", "helmet", "mouse pad", "zipper", "glasses", "lamp shade", "sketch pad", "gage", "plastic fork", "flag", "clay pot", "check book", "CD"]

Loop,% Choices.MaxIndex()
MsgBox % Unique_RChoice(Choices)

Unique_RChoice(Array){
If (Array.MaxIndex() = 0 || Array.MaxIndex() = "")
return, "ERROR"
else {
Random,Rand,1,% Array.MaxIndex()
Ret := Array[Rand]
Array.Remove(Rand)
return, Ret
}
}``````

### Re: Unique random choice based on weighted array  Topic is solved

Posted: 03 Dec 2017, 09:11
Rewrite WeightedRandomVarName to act on an array (like Weighted_array).
Let it return the key (old: return a_loopfield; new e.g: return a_index)
You get the choice (afterwards) with My_choices[key].
Remove the key from Weighted_array to prevent repetition if desired (in or outside of the function, it's your choice).

### Re: Unique random choice based on weighted array

Posted: 03 Dec 2017, 12:39
... also remove key from My_choices in that case.