如何用 C++ 编写高效的遗传算法

发布于 2024-12-12 07:51:32 字数 1522 浏览 8 评论 0原文

我正在尝试为 规范遗传算法编写一个 C++ 程序,其中您有长度为 N 的个体(染色体),其中每个元素都是 O 或 1。

我已经开始使用 STL 向量编写我的程序,但在更深入地研究它之前,我想询问您的意见怎么写以最有效的方式处理函数和数据结构。

内存占用不是问题,我有大约 100 个人,其中每个人都是 64 个字符长的 0 和 1 字符串。另一方面,性能非常重要,因为大约有数千个世代,每个世代都有数千个操作。

这是我迄今为止的实现(仅是最重要的函数和数据结构):

typedef vector<int> chromosome;
typedef vector<chromosome> population;

population popul;
float eval[number];

void cross_chromosomes( const chromosome &parent_a, const chromosome &parent_b, chromosome &child_a, chromosome &child_b )
{
    int crossing_point = crossing_point_gen( gen );

    child_a.reserve( length );
    child_a.insert( child_a.end(), parent_a.cbegin(), parent_a.cbegin() + crossing_point );
    child_a.insert( child_a.end(), parent_b.cbegin() + crossing_point, parent_b.cend() );

    child_b.reserve( length );
    child_b.insert( child_b.end(), parent_b.cbegin(), parent_b.cbegin() + crossing_point );
    child_b.insert( child_b.end(), parent_a.cbegin() + crossing_point, parent_a.cend() );
}

void calculate_eval()
{
    for( int i = 0; i < number; i++ )
    {
        eval[i] = evaluate_chromosome( popul[i] );
    }
}

你认为这是实现该算法的有效方法吗?我最初使用向量作为染色体,但我读过这个问题:C++ 矢量与数组(时间) 并将我的代码更新为 vector

您认为我应该对我的代码进行其他优化以使其更加高效吗?跨码是否像现在一样高效?

I am trying to write a C++ program for the canonical genetic algorithm, where you have a population of individuals (chromosomes) of length N, where each element is a O or 1.

I have started writing my program using STL vectors, but before I go more deeply into it I would like to ask your opinions about how to write the functions and the data structures in the most efficient way.

Memory footprint is not a problem, I have a population about 100 individuals where each of them are a 64 character long string of 0-s and 1-s. The performance on the other hand is very important, as there would be about thousands of generations, each having thousands of operations.

Here is my implementation so far (just the most important funcitions and the data structure):

typedef vector<int> chromosome;
typedef vector<chromosome> population;

population popul;
float eval[number];

void cross_chromosomes( const chromosome &parent_a, const chromosome &parent_b, chromosome &child_a, chromosome &child_b )
{
    int crossing_point = crossing_point_gen( gen );

    child_a.reserve( length );
    child_a.insert( child_a.end(), parent_a.cbegin(), parent_a.cbegin() + crossing_point );
    child_a.insert( child_a.end(), parent_b.cbegin() + crossing_point, parent_b.cend() );

    child_b.reserve( length );
    child_b.insert( child_b.end(), parent_b.cbegin(), parent_b.cbegin() + crossing_point );
    child_b.insert( child_b.end(), parent_a.cbegin() + crossing_point, parent_a.cend() );
}

void calculate_eval()
{
    for( int i = 0; i < number; i++ )
    {
        eval[i] = evaluate_chromosome( popul[i] );
    }
}

Do you think it is an efficient way of implementing this algorithm? I originally used vector for the chromosome, but I have read this question: C++ Vector vs Array (Time) and I updated my code to vector<int>.

Do you think there are other optimisations I should do with my code to make it more efficient? Is the crossing code efficient as it is now?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

影子是时光的心 2024-12-19 07:51:32

如何利用进化算法中令人尴尬的并行性?尝试将您的解决方案移植到 GPU 上怎么样?正如 chetan 和 David 所说,使用现有框架可能比编写自己的快速框架要少得多。

OpenBeagleEO 是众所周知的、得到良好支持且非常高效的框架。

请注意,进化算法中真正需要快速的唯一部分是评估,其他所有部分通常并不耗时。您还可以寻找 DEAP,它允许在超级计算机(我们在 1024 上测试)上轻松分发评估(以及更多内容)通过更改串行算法中的一行代码来实现 Colosse 超级计算机的核心)。

What about taking advantage of the embarasing parallelism in evolutionary algorithm. And what about trying to port your solution on GPUs. And like chetan and David said it might be much less time consuming to use an existing framework than write your own fast one.

OpenBeagle and EO are well known well supported and very efficient frameworks.

Note that the only part that really needs to be fast in an evolutionary algorithm is the evaluation everything else is usually not time consuming. You can also look for DEAP that allows to distribute very easily the evaluation (and more) on supercomputer (we tested on 1024 cores of the Colosse super computer by changing a single line of code in our serial algorithm).

九歌凝 2024-12-19 07:51:32

对于您尝试对向量执行的操作来说,交叉代码似乎具有最高效率。根据我使用遗传算法的经验,适应度函数和选择运算符是最耗时的。由于您将对总体样本使用交叉和变异,因此您不必太担心交叉算子的效率。专注于为数据定义良好的表示和最佳的适应度函数实现。

The crossover code seems at max efficiency for what you are trying to do with the vectors. From my experience with genetic algorithms, the fitness function and selection operator are the most time intensive. Since you will be using crossover and mutation on a sample of the population you don't have to worry too much about the efficiency of the crossover operator. Focus on defining a good representation for your data and an optimal fitness function implementation.

鼻尖触碰 2024-12-19 07:51:32

如果您已经知道数组的大小,那么使用数组将比使用向量快得多。向量比数组需要更多的开销。

If you already know what the size of your arrays are going to be, then using arrays will be much faster than using vectors. Vectors require a lot more overhead than arrays.

落墨 2024-12-19 07:51:32

你可以稍微压缩一下你的内存:使用 4 个字节来表示一个二进制值是相当浪费的。我建议用 std::arraystd::bitset<64> 替换 chromosome 来打包它更多的。

尽管您声称不担心内存,但压缩内存可以更好地使用 CPU 中的缓存,从而可以加快程序速度。

然而,如果你真的想优化你的程序,唯一明智的方法就是使用成熟的分析器。我过去已经连续使用过 callgrind,但是还有其他的,具体取决于您的开发环境。

You could compact your memory somewhat: using 4 bytes to represent a binary value is quite wasteful. I would suggest replacing the chromosome with either std::array<unsigned char, 64> or std::bitset<64> to pack it more.

Even though you claim not to be worried about memory, compacting memory leads to better cache usage in the CPU which may speed up the program.

If you really want to optimize the heck out of your program, however, the only sane way to go at it is to use a full-blown profiler. I've used callgrind quite successively in the past, but there are others out there, depending on your development environment.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文