通过构造函数创建的所有对象都具有相同的向量
All objects made through constructor have the same vectors
我是 C++ 的新手,我正在尝试创建一个基本的遗传算法。我创建了一个染色体 class 并想创建一个社会 class 来生成这些染色体的向量,这些染色体具有随机生成的 "genes"。基因是染色体中包含 0 或 1 值的向量。我正在测试染色体构造函数,所有对象都具有相同的基因向量。如何让构造函数生成随机值?我在下面包含了代码。任何其他编码实践或优化技巧也将不胜感激。
Source.cpp
#include "Chromosome.h"
#include "Society.h"
using namespace std;
int main()
{
Chromosome demo = Chromosome::Chromosome();
Chromosome demo2 = Chromosome::Chromosome();
return 1;
}
Chromosome.h
#pragma once
#include <vector>
using namespace std;
class Chromosome
{
private:
int fitness;
vector<int> genes;
public:
Chromosome();
void generateGenes();
int calculateFitness(),
getFitness();
vector<int> getGenes();
void setGenes(vector<int> child);
};
Chromosome.cpp
#include "Chromosome.h"
#include <cstdlib>
#include <ctime>
#include <numeric>
using namespace std;
Chromosome::Chromosome()
{
generateGenes();
Chromosome::fitness = calculateFitness();
}
void Chromosome::generateGenes()
{
srand(time(NULL));
for (unsigned i = 0; i < 10; i++)
{
unsigned chance = rand() % 5;
Chromosome::genes.push_back((!chance)? 1 : 0);
}
}
int Chromosome::calculateFitness()
{
int sum = 0;
for (unsigned i = 0; i < Chromosome::genes.size(); i++)
{
sum += Chromosome::genes[i];
}
return sum;
}
int Chromosome::getFitness()
{
return Chromosome::fitness;
}
vector<int> Chromosome::getGenes()
{
return Chromosome::genes;
}
void Chromosome::setGenes(vector<int> child)
{
Chromosome::genes = child;
}
您使用相同的值 time(NULL)
为随机数生成器设置种子。
彼此之后的两次调用将 return 相同 time_t
。您将首先生成一组随机数,然后重置随机数生成器并再次生成它们。
整个程序只调用srand()
一次运行.
此外,使用 <random>
来获取 better/faster 个随机数生成器。
而不是 rand() % 5;
使用 <random>
:
#include <random>
// A function to return a random number generator.
inline std::mt19937& generator() {
// the generator will only be seeded once since it's static
static std::mt19937 gen(std::random_device{}());
return gen;
}
// A function to generate unsigned int:s in the range [min, max]
int my_rand(unsigned min, unsigned max) {
std::uniform_int_distribution<unsigned > dist(min, max);
return dist(generator());
}
然后调用它:
unsigned chance = my_rand(0, 4);
您的问题是在 C++ 程序中使用 rand
& srand
。
srand(time(NULL));
unsigned chance = rand() % 5;
在这个实现中,rand
可能 return 多个数字会给你相同的 final 结果。例如:
19, 24, 190214, 49789, 1645879, 15623454, 4, 156489719, 1645234, 152349, ...
在 C++ 中有多种生成随机数的方法,由于结果不好,不推荐使用这种方法。
在 C++ 中使用 "pseudo-random" 生成随机数的(许多)好方法之一:
void Chromosome::generateGenes()
{
// Initialize random
std::random_device rd; // Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<> dis(0, 5);
for (unsigned i = 0; i < 10; i++)
{
// Use random: dis(gen);
unsigned chance = dis(gen);
Chromosome::genes.push_back((!chance)? 1 : 0);
}
}
包括:
#include <random>
@TedLyngmo 的右注:每次调用该函数时(在您的情况下,在构造函数调用中的每个对象创建中),这段代码都会让您生成一个新的随机种子(在 'Initialize random'部分)。在更多进展情况下,或者随着程序的增长,强烈建议将此初始化提取到另一个函数(出于模块化编程的原因,可能提取到新的 class 对象)。在此回复中,我演示了在您的案例中使用这种类型的随机数的一般语法。
了解:
Pseudo-random number generation
感谢@M.M:How to succinctly, portably, and thoroughly seed the mt19937 PRNG?
我是 C++ 的新手,我正在尝试创建一个基本的遗传算法。我创建了一个染色体 class 并想创建一个社会 class 来生成这些染色体的向量,这些染色体具有随机生成的 "genes"。基因是染色体中包含 0 或 1 值的向量。我正在测试染色体构造函数,所有对象都具有相同的基因向量。如何让构造函数生成随机值?我在下面包含了代码。任何其他编码实践或优化技巧也将不胜感激。
Source.cpp
#include "Chromosome.h"
#include "Society.h"
using namespace std;
int main()
{
Chromosome demo = Chromosome::Chromosome();
Chromosome demo2 = Chromosome::Chromosome();
return 1;
}
Chromosome.h
#pragma once
#include <vector>
using namespace std;
class Chromosome
{
private:
int fitness;
vector<int> genes;
public:
Chromosome();
void generateGenes();
int calculateFitness(),
getFitness();
vector<int> getGenes();
void setGenes(vector<int> child);
};
Chromosome.cpp
#include "Chromosome.h"
#include <cstdlib>
#include <ctime>
#include <numeric>
using namespace std;
Chromosome::Chromosome()
{
generateGenes();
Chromosome::fitness = calculateFitness();
}
void Chromosome::generateGenes()
{
srand(time(NULL));
for (unsigned i = 0; i < 10; i++)
{
unsigned chance = rand() % 5;
Chromosome::genes.push_back((!chance)? 1 : 0);
}
}
int Chromosome::calculateFitness()
{
int sum = 0;
for (unsigned i = 0; i < Chromosome::genes.size(); i++)
{
sum += Chromosome::genes[i];
}
return sum;
}
int Chromosome::getFitness()
{
return Chromosome::fitness;
}
vector<int> Chromosome::getGenes()
{
return Chromosome::genes;
}
void Chromosome::setGenes(vector<int> child)
{
Chromosome::genes = child;
}
您使用相同的值 time(NULL)
为随机数生成器设置种子。
彼此之后的两次调用将 return 相同 time_t
。您将首先生成一组随机数,然后重置随机数生成器并再次生成它们。
整个程序只调用srand()
一次运行.
此外,使用 <random>
来获取 better/faster 个随机数生成器。
而不是 rand() % 5;
使用 <random>
:
#include <random>
// A function to return a random number generator.
inline std::mt19937& generator() {
// the generator will only be seeded once since it's static
static std::mt19937 gen(std::random_device{}());
return gen;
}
// A function to generate unsigned int:s in the range [min, max]
int my_rand(unsigned min, unsigned max) {
std::uniform_int_distribution<unsigned > dist(min, max);
return dist(generator());
}
然后调用它:
unsigned chance = my_rand(0, 4);
您的问题是在 C++ 程序中使用 rand
& srand
。
srand(time(NULL));
unsigned chance = rand() % 5;
在这个实现中,rand
可能 return 多个数字会给你相同的 final 结果。例如:
19, 24, 190214, 49789, 1645879, 15623454, 4, 156489719, 1645234, 152349, ...
在 C++ 中有多种生成随机数的方法,由于结果不好,不推荐使用这种方法。
在 C++ 中使用 "pseudo-random" 生成随机数的(许多)好方法之一:
void Chromosome::generateGenes()
{
// Initialize random
std::random_device rd; // Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<> dis(0, 5);
for (unsigned i = 0; i < 10; i++)
{
// Use random: dis(gen);
unsigned chance = dis(gen);
Chromosome::genes.push_back((!chance)? 1 : 0);
}
}
包括:
#include <random>
@TedLyngmo 的右注:每次调用该函数时(在您的情况下,在构造函数调用中的每个对象创建中),这段代码都会让您生成一个新的随机种子(在 'Initialize random'部分)。在更多进展情况下,或者随着程序的增长,强烈建议将此初始化提取到另一个函数(出于模块化编程的原因,可能提取到新的 class 对象)。在此回复中,我演示了在您的案例中使用这种类型的随机数的一般语法。
了解:
Pseudo-random number generation
感谢@M.M:How to succinctly, portably, and thoroughly seed the mt19937 PRNG?