CFLib.org – Common Function Library Project

randomWeightedSelection(weights, n)

Last updated May 25, 2006

author

Chris Spencer

Version: 1 | Requires: CF5 | Library: DataManipulationLib

Description:
Requires a structure and the number of selections to make (with replacement). All keys are selectable elements. All values are unbounded numeric weights, representing the likelyhood of selection for their respective keys. Based on free code by Peter Norvig (http://aima.cs.berkeley.edu/python/search.html).

Return Values:
Returns an array.

Example:

<cfset data = structNew()>
<cfset data['abc'] = 5>
<cfset data['def'] = 20>
<cfset data['mno'] = 50>
<cfset data['xyz'] = 25>

<cfset counts = structNew()>
<cfset toLimit = 100>
<cfloop index="index" from="1" to="#toLimit#">
	<cfset sels = randomWeightedSelection(data,1)>
	<cfif not StructKeyExists(counts,sels[1])><cfset counts[sels[1]] = 0></cfif>
	<cfset counts[sels[1]] = counts[sels[1]]+1>
</cfloop>
<cfloop index="key" list="#StructKeyList(counts)#">
	<cfoutput>
		<p>#key#(#data[key]#) = #counts[key]/toLimit#</p>
	</cfoutput>
</cfloop>

Parameters:

Name Description Required
weights Structure with keys and numeric values for weights. Yes
n Number of selections to make. Yes

Full UDF Source:

/**
 * Returns a number of random selections from a list based on their given weights.
 * 
 * @param weights 	 Structure with keys and numeric values for weights. (Required)
 * @param n 	 Number of selections to make. (Required)
 * @return Returns an array. 
 * @author Chris Spencer (chrisspen@gmail.com) 
 * @version 1, May 25, 2006 
 */
function randomWeightedSelection(weights, n){
	var seq = structKeyArray(weights);
	var totals = arrayNew(1);
	var runningtotal = 0;
	var selections = arrayNew(1);
	var s = 0;
	var i = 0;
	
	for(i=1; i lte arrayLen(seq); i=i+1){
		runningtotal = runningtotal + weights[seq[i]];
		arrayAppend(totals, runningtotal);
	}
	for(s=1; s lte n; s=s+1){
		r = rand()*runningtotal;
		for(i=1; i lte arrayLen(seq); i=i+1){
			if(totals[i] gt r){
				arrayAppend(selections,seq[i]);
				break;
			}
		}
	}
	
	return selections;
}
blog comments powered by Disqus

Search CFLib.org


Latest Additions

Kevin Cotton added
date2ExcelDate
May 5, 2016

Raymond Camden added
CapFirst
April 25, 2016

Chris Wigginton added
loremIpsum
January 18, 2016

Gary Stanton added
calculateArrival...
November 19, 2015

Sebastiaan Naafs - van Dijk added
getDaysInQuarter
November 13, 2015

Created by Raymond Camden / Design by Justin Johnson