📅  最后修改于: 2023-12-03 15:12:21.759000             🧑  作者: Mango
在编程过程中, 我们常常需要从一些带权重的数据中进行随机选择。比如, 在游戏中, 我们需要从一定概率分布下生成不同的NPC或怪物;在推荐系统中, 我们需要从物品库中选出一些物品进行推荐等。
本文将介绍一些实现方法,帮助程序员实现这些随机选择过程。
在 C 语言中,可以使用rand()函数生成一个随机数,默认生成的随机数会均匀分布在 0 ~ RAND_MAX 之间。如果我们需要生成一定概率分布下的随机数,可以通过修改这个随机数的生成范围及使用权重来实现。
下面是一个示例代码,主要是通过使用概率分布来实现带权重的随机数选择:
#include <stdlib.h>
int weighted_random(int* weights, int size) {
int total_weight = 0, selected_index = 0;
// 计算所有权重之和
for (int i = 0; i < size; i++) {
total_weight += weights[i];
}
// 根据权重主键选择随机数
int random_weight = rand() % total_weight;
for(int i = 0; i < size; i++) {
selected_index = i;
if (random_weight < weights[i]) {
break;
}
random_weight -= weights[i];
}
return selected_index;
}
int main() {
int weights[] = {1, 2, 3, 4, 5};
int size = sizeof(weights) / sizeof(weights[0]);
for (int i = 0; i < 10; i++) {
int random_index = weighted_random(weights, size);
printf("Select item #%d with weight %d\n", random_index, weights[random_index]);
}
return 0;
}
代码中,我们首先计算所有权重的之和,然后随机生成一定范围内的随机数,并根据该随机数从前往后遍历每个权重值,累加它们的权重值,直到累加的权重值超过了随机数。此时,即可选出一个随机项,其在权重分布中的位置即为所选的位置。
上述方法并不高效,而且当权重极端不均衡时,可能导致某些项被选中的概率过低。更好的选择是使用轮盘赌算法,将选定随机数与累加权重值与整个权重和的比值进行比较,以此为标准来选择元素。
下面是一个示例代码,主要是通过使用轮盘赌算法来实现带权重的随机数选择:
#include <stdlib.h>
#include <math.h>
int roulette_random(double* weights, int size) {
double total_weight = 0.0, selected_weight = 0.0;
// 计算所有权重之和
for (int i = 0; i < size; i++) {
total_weight += weights[i];
}
// 使用轮盘赌算法选择随机数
double random_weight = (double)rand() / RAND_MAX;
for(int i = 0; i < size; i++) {
selected_weight += weights[i] / total_weight;
if (random_weight < selected_weight) {
return i;
}
}
return size - 1;
}
int main() {
double weights[] = {1.0, 2.0, 3.0, 4.0, 5.0};
int size = sizeof(weights) / sizeof(weights[0]);
for (int i = 0; i < 10; i++) {
int random_index = roulette_random(weights, size);
printf("Select item #%d with weight %lf\n", random_index, weights[random_index]);
}
return 0;
}
代码中,我们首先计算所有权重的之和,然后随机生成一个浮点数,并以此作为轮盘上的指针。接着遍历每个权重,对于每个权重,累加它们的权重值/总权重值的比值,直到累加的权重值比指针值大,此时,即可选出对应的随机项。
到此,我们就完成了利用某个概率分布生成随机数的过程。
带权重的随机选择可以使用不同的方法实现,比如,可以使用概率分布来实现,也可以使用轮盘赌算法来实现。不同的方法适用于不同的场景,程序员可以根据实际情况选择合适的方法来完成带权重的随机选择。