如何依据GA_Vector对vector<vector<ZydisDisassembledInstruction>>排序?
遗传算法排序问题解决方案
原代码存在的问题
FitnessSort函数设计完全错误:std::sort的比较函数需要接收两个待比较的元素(或对应索引),而非单个size_t;且函数内返回PopulationParametrs[Unit].Fitness < PopulationParametrs[Unit].Fitness,永远为false,无法实现排序逻辑。- 两个容器
PopulationSetInstrs和PopulationParametrs分离存储,直接排序其中一个会导致指令与对应GA参数的关联关系完全混乱,无法同步。
推荐解决方案:绑定数据结构(最优方案)
把每个个体的指令集合与GA参数封装到同一个类中,从根源上避免同步问题:
1. 重新定义个体类
// 单个遗传个体:包含指令集合和对应的GA属性 class GA_Individual { public: std::vector<ZydisDisassembledInstruction> instructions; float Fitness = 0.0f; bool Parent = false; // 用false代替0,语义更清晰 };
2. 修改GA_Population类
class GA_Population { private: // 种群是GA_Individual的向量,每个个体的指令和参数绑定在一起 std::vector<GA_Individual> population; public: void FitnessSorting(); };
3. 实现排序函数
void GA_Population::FitnessSorting() { // 按Fitness升序排序,如果需要降序,把<改成>即可 std::sort(population.begin(), population.end(), [](const GA_Individual& a, const GA_Individual& b) { return a.Fitness < b.Fitness; }); }
这种方案结构清晰,后续维护、修改逻辑都更简单,完全不会出现数据不同步的问题。
备选方案:索引排序(适配现有结构)
如果不想大规模修改现有代码,可以通过排序索引的方式,重新排列两个容器:
实现代码
#include <numeric> // 需要std::iota函数 void GA_Population::FitnessSorting() { // 先检查两个容器大小是否一致,避免越界错误 if (PopulationSetInstrs.size() != PopulationParametrs.size()) { // 可根据需求添加错误处理,比如断言 return; } // 创建索引向量:0,1,2,...n-1 std::vector<size_t> indices(PopulationSetInstrs.size()); std::iota(indices.begin(), indices.end(), 0); // 按照GA参数的Fitness对索引排序(升序) std::sort(indices.begin(), indices.end(), [this](size_t i, size_t j) { return PopulationParametrs[i].Fitness < PopulationParametrs[j].Fitness; }); // 根据排序后的索引,重新构建两个容器 std::vector<std::vector<ZydisDisassembledInstruction>> new_instrs; GA_Vector new_params; // 预分配内存提升性能 new_instrs.reserve(PopulationSetInstrs.size()); new_params.reserve(PopulationParametrs.size()); for (size_t idx : indices) { // 用std::move避免复制,提升效率 new_instrs.push_back(std::move(PopulationSetInstrs[idx])); new_params.push_back(std::move(PopulationParametrs[idx])); } // 替换原容器,完成排序 PopulationSetInstrs.swap(new_instrs); PopulationParametrs.swap(new_params); }
注意:使用该方案时,必须保证PopulationSetInstrs和PopulationParametrs的大小始终一致,否则会出现访问越界或数据丢失的问题。
内容的提问来源于stack exchange,提问作者Leo Galante
相关产品推荐
相关产品推荐

