我正在使用C ++中大约2000个元素的数组。
每个元素代表随机选择该元素的概率。
然后我将此数组转换为累积数组,目的是使用它来计算掷骰子时选择的元素。
示例数组: {1,2,3,4,5}
示例累积数组: {1,3,6,10,15}
我希望能够在滚动数字3,4或5时在累积数组中选择3。
增加的复杂性是我的阵列由长双打组成。以下是几个连续元素的示例:
0.96930161525189592646367317541056252139242133125662803649902343750 0.96941377254127855667142910078837303444743156433105468750000000000 0.96944321382974149711383993199831365927821025252342224121093750000 0.96946143938926617454089618153290075497352518141269683837890625000 0.96950069444055009509463721739663810694764833897352218627929687500 0.96951751803395748961766908990966840065084397792816162109375000000
这可能是使用此数据集进行加权概率的一种可怕方式,因此我愿意接受任何更好的解决方法的建议。
答案 0 :(得分:2)
您可以使用partial_sum
:
unsigned int SIZE = 5;
int array[SIZE] = {1,2,3,4,5};
int partials[SIZE] = {0};
partial_sum(array, array+SIZE, partials);
// partials is now {1,3,6,10,15}
您希望从数组中获得的值可以从部分总和中获得:
12 == array[2] + array[3] + array[4];
12 == partials[4] - partials[1];
总数显然是部分总和中的最后一个值:
15 == partial[4];
答案 1 :(得分:1)
考虑将信息存储为整数分子和分母,以便在最后一步之前不会丢失精度。
答案 2 :(得分:1)
您实际上可以使用流选择来执行此操作,而无需计算部分和的数组。以下是我在Java中使用的代码:
public static int selectRandomWeighted(double[] wts, Random rnd) {
int selected = 0;
double total = wts[0];
for( int i = 1; i < wts.length; i++ ) {
total += wts[i];
if( rnd.nextDouble() <= (wts[i] / total)) {
selected = i;
}
}
return selected;
}
如果您希望在总和中保留尽可能多的精度数字,则可以使用Kahan summation进一步改进上述内容。
但是,如果你想重复从这个数组中绘制,那么预先计算一个部分和的数组并使用二进制搜索来找到正确的索引会更快。
答案 3 :(得分:0)
好的,我想我已经解决了这个问题。
我刚刚进行了二元分割搜索,而不仅仅是
if (arr[middle] == value)
我添加了OR
if (arr[middle] == value || (arr[middle] < value && arr[middle+1] > value))
这似乎以我希望的方式处理它。