提交 bc3d30b7 编写于 作者: D dev@dev.com

Merge branch 'master' of git@codechina.csdn.net:coloreaglestdio/qtcpp_demo.git

......@@ -12,6 +12,10 @@ cpp_threadpool
functional助力C++11实现高度可重用接口-线程池例子
https://goldenhawking.blog.csdn.net/article/details/51981905
find0xff
论坛:二维数组中找最大特征数组
https://goldenhawking.blog.csdn.net/article/details/116240710
floodfill_mdf
作业讲评-二值矩阵避障最短路径算法
https://goldenhawking.blog.csdn.net/article/details/109411787
......
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += \
main.cpp
QMAKE_CXXFLAGS += -fopenmp
LIBS += -lgomp -lpthread
#include <iostream>
#include <random>
#include <cassert>
#include <vector>
#include <list>
#include <algorithm>
#include <array>
#include <set>
#include <memory.h>
using namespace std;
//行列、测试列(本例子取8)
template<int R, int C, int T>
class tag_item {
public:
tag_item(){
for (int i=0;i<T;++i)
coords[i] = 0;
}
tag_item(const tag_item & t){
memcpy(coords,t.coords,sizeof(coords));
good = t.good;
}
int coords[T];
int good = 0;
public:
inline bool operator == (const tag_item & t) const
{
for (int i=0;i<T;++i)
if (t.coords[i]!=coords[i])
return false;
return true;
}
inline tag_item & operator = (const tag_item & t)
{
for (int i=0;i<T;++i)
coords[i] = t.coords[i];
good = t.good;
return *this;
}
inline int cal_good(const char (* data)[C]) const
{
int res = 0;
for (int i = 0; i < R; ++i)
{
bool failed = false;
for (int j = 0; j < T && !failed; ++j)
{
if (!data[i][coords[j]])
failed = true;
}
if (!failed)
++res;
}
return res;
}
inline void output() const
{
using std::cout;
cout << "Weight=" << good <<" Cols: ";
for (int i = 0; i < T; ++i)
cout << " " << coords[i];
cout << "\n";
}
inline void sort()
{
std::sort(coords,coords+T,std::less<int>());
}
};
template<int R, int C, int T>
inline bool operator < (const tag_item <R,C,T>& t1, const tag_item <R,C,T>& 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<R,C,T> 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 <R ; ++i)
for (int j = 0; j < 8; ++j)
data[i][best[j]] = 0;
for (int i = 0; i <R/2 ; ++i)
{
int r = e() % R;
for (int j = 0; j < 8; ++j)
{
data[r][best[j]] = 1;
}
}
//种群1024
const int S = 1024;
vector<citem> group;
std::set<citem> 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<citem> new_group;
//交叉
#pragma omp parallel for
for (int i = 0; i < S; ++i)
{
set<int> cols;
vector<int> 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;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册