如何根据其值随机返回关联数组名称

时间:2012-07-18 02:57:38

标签: javascript random probability

我有一系列与一些“积分”相对应的广告系列。看起来像这样:

[ {"c1":4, "c2":8, "c3":25} ]

我想从此套装中随机挑选一个广告系列。我假设rand()会在某个时候发挥作用。但是,我希望每个人的价值都会影响被选中的机会。

因此,例如,广告系列“c2”的选择频率应该是广告系列“c1”的两倍(大致)。 “c3”将成为国王,最有可能被选中。

每次运行脚本时,广告系列和相应值的数量可能相同,也可能不同。

有什么好办法可以解决这个问题?

2 个答案:

答案 0 :(得分:4)

这很容易。 只需为每个广告系列创建另一张具有CDF值的地图。对于你的例子,它将是:

0.108: C1
0.324: C2
1: C3

然后得到一个介于0和1之间的随机数。浏览地图并找到大于随机数的最小数字(您可以二进制搜索它或创建一个排序的哈希映射,也可以给出最大的数字)< / p>

请注意,通过添加概率,最后一个条目可能不会添加到1(可以是0.999)。只需手动将其设置为1.

答案 1 :(得分:1)

这是一个为您解决此问题的功能。它会创建一个加权数组,您可以使用随机数对每个项目的加权值进行适当加权。

var campaigns = {"c1":4, "c2":8, "c3":24};

function getWeightedRandomCampaign(list) {
    var weighting = [];
    var total = 0;
    for (var item in list) {
        weighting.push({key: item, value: list[item]});
        total += list[item];
    }
    // generate random number between 1 and total
    var rand = Math.floor(Math.random() * total);
    // figure out which weighted slot it fits in
    var cum = 0;
    for (var i = 0; i < weighting.length; i++) {
        cum += weighting[i].value;
        if (rand < cum) {
            return(weighting[i].key);
        }            
    }
    return(weighting[weighting.length - 1]);
}

您可以在此处查看:http://jsfiddle.net/jfriend00/ffwqQ/


以下是它的工作原理。

首先是广告系列对象和加权值。

var campaigns = {"c1":4, "c2":8, "c3":24};

然后,它构建一个如下所示的临时数据结构:

var weighting = [{key: "c1", value: 4}, {key: "c2", value: 8}, {key: "c3", value: 24}];

在创建数据结构时,它会跟踪所有权重值的运行总计。

然后

然后创建一个介于0和总数之间的随机数。

然后遍历加权数组,将值相加以查找超过随机数的第一个累计值。当它发现时,这是被选中的插槽。