Arrays 动态概率加权随机选择

Arrays 动态概率加权随机选择,arrays,algorithm,random,Arrays,Algorithm,Random,我一直在寻找一种好的算法,用于从具有不同加权概率的对象列表中选择一个随机对象,并找到了一个真正的可能性宝库,从将每个对象放入数组n次,到对包含离散累积密度函数(CDF)的数组执行二元搜索,将CDF放入桶中,以及一些更令人困惑的回答,特别是感谢 但所有的回答似乎都集中在随机选择的效率上,而不是动态构建或调整权重的成本上。由于我的应用程序似乎要求在运行时调整权重的频率几乎与进行选择的频率相同,因此允许动态调整概率权重的最有效算法是什么?向列表中添加新对象可能只在初始化时进行,但删除对象的频率可能比仅

我一直在寻找一种好的算法,用于从具有不同加权概率的对象列表中选择一个随机对象,并找到了一个真正的可能性宝库,从将每个对象放入数组n次,到对包含离散累积密度函数(CDF)的数组执行二元搜索,将CDF放入桶中,以及一些更令人困惑的回答,特别是感谢

但所有的回答似乎都集中在随机选择的效率上,而不是动态构建或调整权重的成本上。由于我的应用程序似乎要求在运行时调整权重的频率几乎与进行选择的频率相同,因此允许动态调整概率权重的最有效算法是什么?向列表中添加新对象可能只在初始化时进行,但删除对象的频率可能比仅仅更改值要低一些(也许将概率设置为零就足够了)

我最初的印象是,使用一系列CDF是我的最佳选择;将相同的调整应用到目标概率之后的所有事情似乎都是微不足道的,但我没有看到任何事情对CDF bucket来说如此容易。有什么想法吗


如果有人在乎的话,我正在用haxe实现这一点

假设你有一个对象数组{O.1,O.2,…,O.N}和一个关联概率权重数组{w.1,w.2,…,w.N}

您可以设置介于0和1之间的值范围(“桶”),这些值的大小根据每个权重而定,然后只需选择介于0和1之间的随机值(均匀分布)。随机值将落在您定义的某个存储桶中。如果它落在第i个桶中,则从数组中拾取第i个对象

抱歉,我不知道haxe,但下面是一些java代码来说明:

    Random mRandom = new Random();

double[] weights = {0.3, 0.2, 0.1, 0.5}; //Make sure these sum to 1!!  But at least you can change these at run-time.


int getRandomObject() {

    double randNum = mRandom.nextDouble();

    double sumOfWeightSoFar = 0;
    int currentIndex = 0;
    while (true) {
        if (randNum < weights[currentIndex] + sumOfWeightSoFar)
            return currentIndex;
        else {
            currentIndex++;
            sumOfWeightSoFar = sumOfWeightSoFar + weights[currentIndex];
        }
    }
    //If your weights don't sum to 1 or more, then "currentIndex" will eventually exceed your array bounds.  But you get the idea.
}
Random mRandom=new Random();
双[]权重={0.3,0.2,0.1,0.5}//确保这些总和为1!!但至少您可以在运行时更改这些。
int getRandomObject(){
double randNum=mRandom.nextDouble();
双倍重量总和=0;
int currentIndex=0;
while(true){
if(随机数<权重[currentIndex]+权重之和)
返回电流指数;
否则{
currentIndex++;
重量总和=重量总和+重量[当前指数];
}
}
//如果你的权重总和不是1或更多,那么“currentIndex”最终将超过你的数组边界。但是你明白了。
}

您可以使用for O(log n)-时间采样和更新,但根据调整的内容,您可能会做得更好。这并不能解决问题。他的概率在变化,所以每次选择时他都需要重建这个表。而且,即使你有固定的概率,这也不是一个好的实现;二叉树提供了更快的查找,大多数库都会有一个API来执行选择,而无需额外的代码。我认为他的观点是,现有的实现在固定概率下工作得最好,他希望在运行时可以更改某些内容。可以在运行时设置“weights[]”数组的值。当然,有人可以提出一个更有效的实现,但是这个概念已经被阐明了……除非我完全没有回答这个问题。谢谢,但这似乎是我在问题中所说的,我目前认为我的最佳选择,减去在更改时的二进制搜索和计算CDF。