#include #include #include #include #include #include #include #include #include using namespace std; //行列、测试列(本例子取8) template class tag_item { public: tag_item(){ for (int i=0;i()); } }; template inline bool operator < (const tag_item & t1, const tag_item & t2) { for (int i = 0; i < T; ++i) { if (t1.coords[i] < t2.coords[i]) return true; else if (t1.coords[i] > t2.coords[i]) return false; } return false; } int main(int /*argc*/, char* /*argv*/[]) { using namespace std; default_random_engine e; const int R = 5000, C = 5000, T=8; typedef tag_item citem; char(*data)[C] = new char[R][C]; assert(data); for (int i = 0; i < R; ++i) for (int j = 0; j < C; ++j) data[i][j] = e() % 2; int best[8] = {12,445,17,2314,3033,1273,2289,4987}; //Best rows,重量一致,但是排齐 for (int i = 0; i group; std::set group_set; //产生初始集合 for (int i = 0; i < S; ++i) { citem tmp; for (int j = 0; j < T; ++j) { bool failed = false; do { tmp.coords[j] = e() % C; failed = false; if (j) { for (int k = 0; k < j && !failed; ++k) if (tmp.coords[k] == tmp.coords[j]) failed = true; } } while (failed); } tmp.sort(); tmp.good = tmp.cal_good(data); if (group_set.find(tmp)== group_set.end()) { group_set.insert(tmp); group.push_back(tmp); } else --i; } //开始遗传优化K次 const int K = 1<<20; for (int g = 0; g < K; ++g) { vector new_group; //交叉 #pragma omp parallel for for (int i = 0; i < S; ++i) { set cols; vector cols_v; for (int j = 0; j < T; ++j) { cols.insert(group[i].coords[j]); cols_v.push_back(group[i].coords[j]); } const int s = e() % S; citem nw; if (s != i) { for (int j = 0; j < T; ++j) { if (cols.find(group[s].coords[j]) == cols.end()) { cols_v.push_back(group[s].coords[j]); cols.insert(group[s].coords[j]); } } const size_t sz_set = cols_v.size(); for (int b = 0; b < T; ++b) { const int take = e() % (sz_set - b); auto iter = cols_v.begin() + take; nw.coords[b] = *iter; cols_v.erase(iter); } nw.good = nw.cal_good(data); nw.sort(); #pragma omp critical new_group.push_back(nw); } } //复制 std::copy(new_group.begin(), new_group.end(), back_inserter(group)); new_group.clear(); const size_t S2 = group.size(); //变异 #pragma omp parallel for for (size_t i = 0; i < S2; ++i) { const int b = e() % T; citem nw = group[i]; bool failed = false; do { nw.coords[b] = e() % C; failed = false; for (int k = 0; k < T && !failed; ++k) if (nw.coords[b] == nw.coords[k] && b!=k) failed = true; } while (failed); nw.good = nw.cal_good(data); nw.sort(); #pragma omp critical new_group.push_back(nw); } std::copy(new_group.begin(), new_group.end(), back_inserter(group)); new_group.clear(); //增补 for (int i = 0; i < S/4; ++i) { citem tmp; for (int j = 0; j < T; ++j) { bool failed = false; do { tmp.coords[j] = e() % C; failed = false; if (j) { for (int k = 0; k < j && !failed; ++k) if (tmp.coords[k] == tmp.coords[j]) failed = true; } } while (failed); } tmp.sort(); tmp.good = tmp.cal_good(data); if (group_set.find(tmp)== group_set.end()) { group_set.insert(tmp); group.push_back(tmp); } else --i; } //排序 sort(group.begin(), group.end(), [](const citem& t1,const citem& t2)->bool { return t1.good > t2.good; }); //淘汰 if (g%4==0) { group_set.clear(); int kept = 0; for (auto p = group.begin(); p != group.end() && kept < S; ++p) { if (group_set.find(*p) == group_set.end()) { new_group.push_back(*p); group_set.insert(*p); ++kept; } } group = new_group; } //输出 cout << "Iter " << g << ":"; group.begin()->output(); } delete[] data; data = nullptr; return 0; }