我正在编制一个程序,其中列出了34个城市的名单,我希望为这些城市中的每个城市提供被选中的概率。
所以我有:
vector<float> vec;
int s;
cin >> s;
srand(s);
for (int k=0; k < 34; k++)
{
float p1= (float)rand()/(float)((unsigned)RAND_MAX+1);
vec.push_back(p1);
}
这样每个城市都有概率。我现在遇到的问题是我想做一个随机数生成器,它将选择其中两个城市。因此,例如city1将有5%,city2有2%,city3,有3%等等。我如何根据给定的概率随机选择其中两个城市?
答案 0 :(得分:5)
我在遗传算法中做到了这一点。 为您的城市考虑10个单位的线。 现在从0-5单位在线,city1 6-7为city2,8-9为city3。 现在从0-9随机选择一个数字。 并发现它进入哪个城市范围。
答案 1 :(得分:1)
乍一看我的解决方案是:
创建一个随机数,最大随机数等于前一个数字
取随机数字,然后浏览你的城市向量,并选择相应的人。
示例:
City 1 : 5%
City 2 : 8%
City 3 : 2%
City 4 : 5%
City 5 : 12%
Create a number -> Number a = 32 (5+8+2+5+12)
Generate a number with : 1 <= number
Assume that the number is equal to 12
City 1 is choose if : 1 <= number <= 5 (So not)
City 2 is choose if : 6 <= number <= 13 (So yes)
City 2 is choose.
如果您对此有任何疑问,欢迎您:)
修改:
我会给你一些解释。
拿这段代码:
for (int k=0; k < 10; k++)
{
float p1= (float)rand()/(float)((unsigned)RAND_MAX+1);
vec.push_back(p1);
}
现在假设vec包含以下信息:
5
3
8
5
12
14
8
5
6
18
每个数字对应于选择城市的概率。
5 -> 5% probability to choose (City1) 3 -> 3% probability to choose (City2) 8 -> 8% probability to choose (City3) ... etc
现在我将给你一些代码,我将解释它:
int nbReference = 0;
for (auto it = vec.begin() ; it != vec.end() ; ++it)
{
nbReference += *it;
}
nbReference = rand(nbReference);
int i = 0;
int cityProbability = 0;
for (auto it = vec.begin() ; it != vec.end() ; ++it)
{
cityProbability = *it;
if ((i + cityProbability) > nbReference)
{
return (i + 1);
}
i += cityProbability;
}
首先我创建一个数字等于添加所有城市的概率
int nbReference = 0;
for (auto it = vec.begin() ; it != vec.end() ; ++it)
{
nbReference += *it;
}
其次,我生成一个尊重以下范围的数字 - &gt; 0&lt; nbReference
第三,我创建了一个循环,逐个占据所有城市,当我们到达正确的城市时退出。
我们如何知道城市什么时候好?
我们举个例子!
以我们之前的概率
5 3 8 5 12 14 8 5 6 18
NbReference等于(5 + 3 + 8 + 5 + 12 + 14 + 8 + 5 + 6 + 18)所以84
对于每个城市,我们将把一个范围等于他的概率加上以前所有城市的概率。让我告诉你:
5 -> Range 0 to 4 (0 to 4 = 5 ---> 5%)
3 -> Range 5 to 8 (5 to 8 = 3 ---> 3%)
8 -> Range 9 to 17
5 -> Range 18 to 22
... etc
如果我们在这里创建的号码
nbReference = rand(nbReference);
在城市范围内,选择城市。
示例:如果数字为16,则选择city3!
5 -> Range 0 to 4 Number is 16 so NOPE
3 -> Range 5 to 8 Number is 16 so NOPE
8 -> Range 9 to 17 Number is 16 so YES!
5 -> Range 18 to 22
... etc
这有用吗? :)
有任何问题吗?不客气
答案 2 :(得分:1)
也许这段代码可以帮助你(部分跟随WhozCraig建议)
#include <iostream>
#include <random>
#include <algorithm>
int main(int argc, const char * argv[])
{
using namespace std::chrono;
system_clock::time_point tp = system_clock::now();
system_clock::duration dtn = tp.time_since_epoch();
std::default_random_engine generator(static_cast<int>(dtn.count()));
//Generate 34 cities
std::uniform_real_distribution<double> gen_distribution(0,1);
auto getProb = std::bind ( gen_distribution, generator );
std::vector<double> citiesProb;
double probSum(0.0);
double cityProb(0.0);
for (int k=0; k < 34; k++)
{
cityProb = getProb();
probSum += cityProb;
citiesProb.push_back(cityProb);
}
//Pick 7 cities
std::uniform_real_distribution<double> pick_distribution(0,probSum);
auto pickCity = std::bind ( pick_distribution, generator );
double chooseCity;
double probBasket;
for (int k=0; k < 7; ++k)
{
probBasket = 0.0;
chooseCity = pickCity();
for (int i = 0; i < citiesProb.size(); ++i)
{
if (chooseCity >= probBasket && chooseCity < probBasket + citiesProb[i])
{
std::cout << "City with index " << i << " picked" << std::endl;
}
probBasket += citiesProb[i];
}
}
return 0;
}
工作原理:
city1 5%(0.05), city2 25%(0.25), city3 8%(0.08), city4 10%(0.1)
然后
probSum = 0.05 + 0.25 + 0.08 + 0.1 = 0.48
然后选择0到0.48之间的数字(名为pickProb)和
if pickProb is between 0 and 0.05 pick city1 (prob = 0.05/0.48 = 10%)
if pickProb is between 0.05 and 0.30 pick city2 (prob = 0.25/0.48 = 52%)
if pickProb is between 0.30 and 0.38 pick city3 (prob = 0.08/0.48 = 16%)
if pickProb is between 0.38 and 0.48 pick city4 (prob = 0.1/0.48 = 20%)
如果probSum = 1.0,那么city1的概率为5%,city2的概率为25%,等等。