C++ 如何在C++;?
我正在尝试用骰子做一个游戏,我需要有随机数(来模拟骰子的两边。我知道如何在1到6之间进行)。使用C++ 如何在C++;?,c++,random,C++,Random,我正在尝试用骰子做一个游戏,我需要有随机数(来模拟骰子的两边。我知道如何在1到6之间进行)。使用 所以我想要一个每次生成不同随机数的命令,而不是一行生成5次相同的随机数。是否有命令可以执行此操作?根据随机数生成器的不同,使用模可能会在随机数中引入偏差。当然,完全有可能得到随机序列中的重复数字 尝试一些C++11功能以获得更好的分发: #include <random> #include <iostream> int main() { std::random_de
所以我想要一个每次生成不同随机数的命令,而不是一行生成5次相同的随机数。是否有命令可以执行此操作?根据随机数生成器的不同,使用模可能会在随机数中引入偏差。当然,完全有可能得到随机序列中的重复数字 尝试一些C++11功能以获得更好的分发:
#include <random>
#include <iostream>
int main()
{
std::random_device dev;
std::mt19937 rng(dev());
std::uniform_int_distribution<std::mt19937::result_type> dist6(1,6); // distribution in range [1, 6]
std::cout << dist6(rng) << std::endl;
}
#包括
#包括
int main()
{
std::随机_设备开发;
std::mt19937 rng(dev());
std::uniform_int_dist6(1,6);//范围内的分布[1,6]
std::cout测试应用程序最基本的问题是调用srand
一次,然后调用rand
一次并退出
srand
函数的要点是用随机种子初始化伪随机数序列
这意味着,如果在两个不同的应用程序中(使用相同的srand
/rand
实现)将相同的值传递给srand
,那么在这两个应用程序中读取的rand()
值序列将完全相同
然而,在您的示例应用程序中,伪随机序列仅由一个元素组成—从seed生成的伪随机序列的第一个元素等于当前时间的1秒
精度。那么您希望在输出上看到什么
显然,当您碰巧在同一秒上运行应用程序时——您使用了相同的种子值——因此您的结果当然是相同的(正如Martin York在对问题的评论中所提到的)
实际上,您应该调用srand(seed)
一次,然后多次调用rand()
并分析该序列-它应该看起来是随机的
修改件1-示例代码:
好的,我明白了。
显然,口头描述是不够的(可能是语言障碍或其他……:))
基于问题中使用的相同函数的老式C代码示例:
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
int main(void)
{
unsigned long j;
srand( (unsigned)time(NULL) );
for( j = 0; j < 100500; ++j )
{
int n;
/* skip rand() readings that would make n%6 non-uniformly distributed
(assuming rand() itself is uniformly distributed from 0 to RAND_MAX) */
while( ( n = rand() ) > RAND_MAX - (RAND_MAX-5)%6 )
{ /* bad value retrieved so get next one */ }
printf( "%d,\t%d\n", n, n % 6 + 1 );
}
return 0;
}
#include <iostream>
#include <cctype>
#include <random>
using u32 = uint_least32_t;
using engine = std::mt19937;
int main( void )
{
std::random_device os_seed;
const u32 seed = os_seed();
engine generator( seed );
std::uniform_int_distribution< u32 > distribute( 1, 6 );
for( int repetition = 0; repetition < 10; ++repetition )
std::cout << distribute( generator ) << std::endl;
return 0;
}
以前使用的代码的版本
#包括
#包括
#包括
int main()
{
std::随机_装置rd;
std::mt19937::结果类型seed=rd()(
(标准::mt19937::结果类型)
标准::计时::持续时间(
std::chrono::system_clock::now().自_epoch()以来的时间
).count()+
(标准::mt19937::结果类型)
标准::计时::持续时间(
std::chrono::高分辨率时钟::now()。自新纪元以来的时间()
).count());
标准:mt19937 gen(种子);
标准:均匀分布分布(1,6);
用于(无符号长j=0;j<100500;++j)
{
std::cout这里有一个解决方案。创建一个返回随机数的函数并放置它
在主要功能之外使其全球化。希望这有助于
#include <iostream>
#include <cstdlib>
#include <ctime>
int rollDie();
using std::cout;
int main (){
srand((unsigned)time(0));
int die1;
int die2;
for (int n=10; n>0; n--){
die1 = rollDie();
die2 = rollDie();
cout << die1 << " + " << die2 << " = " << die1 + die2 << "\n";
}
system("pause");
return 0;
}
int rollDie(){
return (rand()%6)+1;
}
#包括
#包括
#包括
int rollDie();
使用std::cout;
int main(){
srand((未签名)时间(0));
int die1;
int die2;
对于(int n=10;n>0;n--){
die1=滚刀();
die2=滚刀();
不能包含
#包括
#包括
int main(){
srand(时间(空));
int random_number=std::rand();//rand()返回介于0 还有兰德·马克斯
std::cout如果使用libs,可以通过以下方式获得随机生成器:
#include <iostream>
#include <string>
// Used in randomization
#include <ctime>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/random/variate_generator.hpp>
using namespace std;
using namespace boost;
int current_time_nanoseconds(){
struct timespec tm;
clock_gettime(CLOCK_REALTIME, &tm);
return tm.tv_nsec;
}
int main (int argc, char* argv[]) {
unsigned int dice_rolls = 12;
random::mt19937 rng(current_time_nanoseconds());
random::uniform_int_distribution<> six(1,6);
for(unsigned int i=0; i<dice_rolls; i++){
cout << six(rng) << endl;
}
}
对于每个随机运行文件
size_t randomGenerator(size_t min, size_t max) {
std::mt19937 rng;
rng.seed(std::random_device()());
//rng.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());
std::uniform_int_distribution<std::mt19937::result_type> dist(min, max);
return dist(rng);
}
size\t随机生成器(size\t最小值、size\t最大值){
标准:mt19937 rng;
种子(std::random_device());
//种子(标准::时钟::高分辨率时钟::现在();
标准:均匀分布距离(最小值、最大值);
返回距离(rng);
}
每次生成不同的随机数,而不是连续六次生成相同的随机数。
用例场景
我把可预测性的问题比作一个由六张纸组成的袋子,每一张纸上都写着0到5的值。每次需要一个新的值时,都会从袋子里抽出一张纸。如果袋子是空的,那么数字就会放回袋子里
…由此,我可以创建一个排序算法
算法
包通常是集合
。我选择了bool[]
(也称为布尔数组、位平面或位映射)来扮演包的角色
我之所以选择bool[]
是因为每个项目的索引已经是每张纸的值。如果纸上还需要写任何东西,我会使用字典来代替它。布尔值用于跟踪数字是否已经绘制
一个名为RemainingNumberCount
的计数器被初始化为5
,当选择一个随机数时,它会进行倒计时。这样我们就不必在每次希望绘制一个新的数字时都要计算剩余的纸张数量
为了选择下一个随机值,我使用了一个for..loop
来扫描索引包,当index
为false
时,使用一个计数器来计数,称之为NumberOfMoves
NumberOfMoves
用于选择下一个可用数字。NumberOfMoves
首先被设置为介于0
和5
之间的随机值,因为我们可以通过包执行0..5个可用步骤。在下一次迭代中,NumberOfMoves
被设置为介于0
和之间的随机值d4
,因为现在我们可以通过袋子执行0..4个步骤。随着数字的使用,可用数字减少,因此我们使用rand()%(RemainingNumberCount+1)
来计算n
#include <iostream>
#include <cstdlib>
#include <ctime>
int rollDie();
using std::cout;
int main (){
srand((unsigned)time(0));
int die1;
int die2;
for (int n=10; n>0; n--){
die1 = rollDie();
die2 = rollDie();
cout << die1 << " + " << die2 << " = " << die1 + die2 << "\n";
}
system("pause");
return 0;
}
int rollDie(){
return (rand()%6)+1;
}
#include <iostream>
#include <cstdlib>
#include <ctime>
int main() {
srand(time(NULL));
int random_number = std::rand(); // rand() return a number between 0 and RAND_MAX
std::cout << random_number;
return 0;
}
#include <iostream>
#include <string>
// Used in randomization
#include <ctime>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/random/variate_generator.hpp>
using namespace std;
using namespace boost;
int current_time_nanoseconds(){
struct timespec tm;
clock_gettime(CLOCK_REALTIME, &tm);
return tm.tv_nsec;
}
int main (int argc, char* argv[]) {
unsigned int dice_rolls = 12;
random::mt19937 rng(current_time_nanoseconds());
random::uniform_int_distribution<> six(1,6);
for(unsigned int i=0; i<dice_rolls; i++){
cout << six(rng) << endl;
}
}
#include <iostream>
#include <ctime>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/random/variate_generator.hpp>
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/date_time/gregorian/gregorian.hpp"
using namespace std;
using namespace boost;
using namespace boost::posix_time;
using namespace boost::gregorian;
class Randomizer {
private:
static const bool debug_mode = false;
random::mt19937 rng_;
// The private constructor so that the user can not directly instantiate
Randomizer() {
if(debug_mode==true){
this->rng_ = random::mt19937();
}else{
this->rng_ = random::mt19937(current_time_nanoseconds());
}
};
int current_time_nanoseconds(){
struct timespec tm;
clock_gettime(CLOCK_REALTIME, &tm);
return tm.tv_nsec;
}
// C++ 03
// ========
// Dont forget to declare these two. You want to make sure they
// are unacceptable otherwise you may accidentally get copies of
// your singleton appearing.
Randomizer(Randomizer const&); // Don't Implement
void operator=(Randomizer const&); // Don't implement
public:
static Randomizer& get_instance(){
// The only instance of the class is created at the first call get_instance ()
// and will be destroyed only when the program exits
static Randomizer instance;
return instance;
}
bool method() { return true; };
int rand(unsigned int floor, unsigned int ceil){
random::uniform_int_distribution<> rand_ = random::uniform_int_distribution<> (floor,ceil);
return (rand_(rng_));
}
// Is not considering the millisecons
time_duration rand_time_duration(){
boost::posix_time::time_duration floor(0, 0, 0, 0);
boost::posix_time::time_duration ceil(23, 59, 59, 0);
unsigned int rand_seconds = rand(floor.total_seconds(), ceil.total_seconds());
return seconds(rand_seconds);
}
date rand_date_from_epoch_to_now(){
date now = second_clock::local_time().date();
return rand_date_from_epoch_to_ceil(now);
}
date rand_date_from_epoch_to_ceil(date ceil_date){
date epoch = ptime(date(1970,1,1)).date();
return rand_date_in_interval(epoch, ceil_date);
}
date rand_date_in_interval(date floor_date, date ceil_date){
return rand_ptime_in_interval(ptime(floor_date), ptime(ceil_date)).date();
}
ptime rand_ptime_from_epoch_to_now(){
ptime now = second_clock::local_time();
return rand_ptime_from_epoch_to_ceil(now);
}
ptime rand_ptime_from_epoch_to_ceil(ptime ceil_date){
ptime epoch = ptime(date(1970,1,1));
return rand_ptime_in_interval(epoch, ceil_date);
}
ptime rand_ptime_in_interval(ptime floor_date, ptime ceil_date){
time_duration const diff = ceil_date - floor_date;
long long gap_seconds = diff.total_seconds();
long long step_seconds = Randomizer::get_instance().rand(0, gap_seconds);
return floor_date + seconds(step_seconds);
}
};
size_t randomGenerator(size_t min, size_t max) {
std::mt19937 rng;
rng.seed(std::random_device()());
//rng.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());
std::uniform_int_distribution<std::mt19937::result_type> dist(min, max);
return dist(rng);
}
#include "stdafx.h"
#include <ctime>
#include <iostream>
#include <string>
class RandomBag {
public:
int Value = -1;
RandomBag() {
ResetBag();
}
void NextValue() {
int BagOfNumbersLength = sizeof(BagOfNumbers) / sizeof(*BagOfNumbers);
int NumberOfMoves = rand() % (RemainingNumberCount + 1);
for (int i = 0; i < BagOfNumbersLength; i++)
if (BagOfNumbers[i] == 0) {
NumberOfMoves--;
if (NumberOfMoves == -1)
{
Value = i;
BagOfNumbers[i] = 1;
break;
}
}
if (RemainingNumberCount == 0) {
RemainingNumberCount = 5;
ResetBag();
}
else
RemainingNumberCount--;
}
std::string ToString() {
return std::to_string(Value);
}
private:
bool BagOfNumbers[6];
int RemainingNumberCount;
int NumberOfMoves;
void ResetBag() {
RemainingNumberCount = 5;
NumberOfMoves = rand() % 6;
int BagOfNumbersLength = sizeof(BagOfNumbers) / sizeof(*BagOfNumbers);
for (int i = 0; i < BagOfNumbersLength; i++)
BagOfNumbers[i] = 0;
}
};
Console::WriteLine("The next value is " + randomBag.ToString());
std::cout << "The next value is " + randomBag.ToString() << std::endl;
class Console {
public:
static void WriteLine(std::string s) {
std::cout << s << std::endl;
}
};
int main() {
srand((unsigned)time(0)); // Initialise random seed based on current time
RandomBag randomBag;
Console::WriteLine("First set of six...\n");
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
Console::WriteLine("\nSecond set of six...\n");
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
Console::WriteLine("\nThird set of six...\n");
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
randomBag.NextValue();
Console::WriteLine("The next value is " + randomBag.ToString());
Console::WriteLine("\nProcess complete.\n");
system("pause");
}
First set of six...
The next value is 2
The next value is 3
The next value is 4
The next value is 5
The next value is 0
The next value is 1
Second set of six...
The next value is 3
The next value is 4
The next value is 2
The next value is 0
The next value is 1
The next value is 5
Third set of six...
The next value is 4
The next value is 5
The next value is 2
The next value is 0
The next value is 3
The next value is 1
Process complete.
Press any key to continue . . .
int getNextRandom(const size_t lim)
{
int nextRand = rand() % lim;
int nextSign = rand() % lim;
if (nextSign < lim / 2)
return -nextRand;
return nextRand;
}
int main()
{
srand(time(NULL));
int r = getNextRandom(100);
cout << r << endl;
return 0;
}
int random(int from, int to){
return rand() % (to - from + 1) + from;
}
int main(){
srand(time(0));
cout << random(0, 99) << "\n";
}
class Randomer {
// random seed by default
std::mt19937 gen_;
std::uniform_int_distribution<size_t> dist_;
public:
/* ... some convenient ctors ... */
Randomer(size_t min, size_t max, unsigned int seed = std::random_device{}())
: gen_{seed}, dist_{min, max} {
}
// if you want predictable numbers
void SetSeed(unsigned int seed) {
gen_.seed(seed);
}
size_t operator()() {
return dist_(gen_);
}
};
int main() {
Randomer randomer{0, 10};
std::cout << randomer() << "\n";
}
/// Proper way!
seed( 1234 ) /// Seed set only once...
for( x in range( 0, 10) ):
PRNG( seed ) /// Will work as expected
/// Wrong way!
for( x in rang( 0, 10 ) ):
seed( 1234 ) /// Seed reset for ten iterations!
PRNG( seed ) /// Output will be the same...
#include <iostream>
#include <cstdlib>
#include <ctime>
int main( void )
{
int low_dist = 1;
int high_dist = 6;
std::srand( ( unsigned int )std::time( nullptr ) );
for( int repetition = 0; repetition < 10; ++repetition )
std::cout << low_dist + std::rand() % ( high_dist - low_dist ) << std::endl;
return 0;
}
#include <iostream>
#include <cctype>
#include <random>
using u32 = uint_least32_t;
using engine = std::mt19937;
int main( void )
{
std::random_device os_seed;
const u32 seed = os_seed();
engine generator( seed );
std::uniform_int_distribution< u32 > distribute( 1, 6 );
for( int repetition = 0; repetition < 10; ++repetition )
std::cout << distribute( generator ) << std::endl;
return 0;
}
0: 5268
1: 5284
2: 5279
3: 5242
4: 5191
5: 5135
6: 5183
7: 5236
8: 5372
9: 5343