【发布时间】:2019-10-26 13:03:51
【问题描述】:
假设我们有一个由0 和1 填充的stack。我想将mutation_rate_ 的许多元素从0 更改为1,反之亦然。应该“变异”的元素是随机选择的。我为此编写了两个函数,我将在下面发布一个测试用例,但其中一个似乎无法正常工作。
#include <stack>
#include <vector>
#include <random>
#include <set>
#include <algorithm>
#include <iostream>
using age_t = unsigned int;
std::stack<age_t> mutate( std::stack<age_t> genome_, age_t mutation_rate_ = 3){
std::stack<age_t> final_stack;
// Generate a set, whose elements are the positions at which we perforem the mutation.
std::set<age_t> positions_to_switch;
while(positions_to_switch.size() < mutation_rate_){
positions_to_switch.insert(rand() % genome_.size());
}
// Create a counter to go through the stack amd iterator of the set.
age_t cnt = 0;
std::set<age_t>::iterator it= positions_to_switch.begin();
while(genome_.empty()!=true){ // Go through the whole genome_
if(*it==cnt){ // check if current position in stack matches with
// element that needs mutation
if(genome_.top()==1) final_stack.push(0); // mutate
else final_stack.push(1);
++it; // go to next element that needs mutation
}
else{ // if no mutation is needed
final_stack.push(genome_.top());
}
genome_.pop(); // go to next element in stack
++cnt; // increase counter of stack
}
// final stack is in reverse order
std::stack<age_t> res;
while(!final_stack.empty()){
res.push(final_stack.top());
final_stack.pop();
}
return res;
};
std::stack<age_t> mutate_2( std::stack<age_t> genome_, age_t mutation_rate_ = 3){
std::stack<age_t> final_stack;
std::vector<age_t> enumeration;
age_t pos = 0;
while(enumeration.size() < genome_.size()){
enumeration.push_back(pos);
++pos;
}
pos = 0;
auto rng = std::default_random_engine {};
std::shuffle(enumeration.begin(), enumeration.end(), rng);
std::vector<age_t> positions_to_switch;
while(positions_to_switch.size() < mutation_rate_){
positions_to_switch.push_back(enumeration[pos]);
++pos;
}
// Create a counter to go through the stack amd iterator of the set.
age_t cnt = 0;
std::vector<age_t>::iterator it= positions_to_switch.begin();
while(genome_.empty()!=true){ // Go through the whole genome_
if(*it==cnt){ // check if current position in stack matches with
// element that needs mutation
if(genome_.top()==1) final_stack.push(0); // mutate
else final_stack.push(1);
++it; // go to next element that needs mutation
}
else{ // if no mutation is needed
final_stack.push(genome_.top());
}
genome_.pop(); // go to next element in stack
++cnt; // increase counter of stack
}
// final stack is in reverse order
std::stack<age_t> res;
while(!final_stack.empty()){
res.push(final_stack.top());
final_stack.pop();
}
return res;
};
int main(){
std::stack<age_t> test_stack;
test_stack.push(1);
test_stack.push(0);
test_stack.push(0);
test_stack.push(0);
test_stack.push(1);
test_stack.push(1);
std::stack<age_t> test_stack_copy = test_stack;
std::stack<age_t> test_stack_copy_2 = test_stack;
std::stack<age_t> res = mutate(test_stack);
std::stack<age_t> res_2 = mutate_2(test_stack);
std::cout << "Original Stack:\t";
while(test_stack_copy_2.empty()!=true){
std::cout << test_stack_copy_2.top();
test_stack_copy_2.pop();
}
std::cout << "\n";
std::cout << "Muatet:\t\t";
while(res.empty()!=true){
std::cout << res.top();
res.pop();
}
std::cout << "\n";
std::cout << "Muatet_2:\t";
while(res_2.empty()!=true){
std::cout << res_2.top();
res_2.pop();
}
std::cout << "\n";
return 0;
}
考虑到测试用例110001,mutate 返回100111 和mutate_2 返回111101,其中我设置了mutation_rate_=3,所以初始堆栈的三个元素应该已更改。我们可以直接看到mutate确实改变了三个条目,而mutate_2只改变了其中两个……我很确定这与set和vector对象的处理方式有关,但我就是找不到错误...
【问题讨论】:
-
我没有检查整个代码,可能还有其他错误,但
*it==cnt应该是it!=positions_to_switch.end() && *it==cnt。 -
你检查了集合/向量
positions_to_switch的内容吗? -
@MikeCAT 是的,我打印了它们,尺寸和内容也很合理。大小为
muattion_rate_,内容为usnigned int介于零和genome.size()之间的数字 -
您是否尝试过进行代码演练?随机性可能很难通过,但您已经打印出
positions_to_switch的内容,所以这应该不是问题。 (如果您需要测试用例,请尝试positions_to_switch = { 2, 3, 1 }。)
标签: c++ algorithm sorting vector set