Unique random choice based on weighted array Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
DanielToward13
Posts: 74
Joined: 18 May 2017, 10:56

Unique random choice based on weighted array

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
	}
}
Guest

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

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).
Guest

Re: Unique random choice based on weighted array

03 Dec 2017, 12:39

... also remove key from My_choices in that case.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: wineguy and 382 guests