赞
踩
参数:
- //递归算法
- //优点:结构简单,缺点:递归太深容易爆栈
- void route_searching1(Eigen::MatrixXi& map, std::vector<int>& visit, std::vector<int>&path, int& m, int k, std::function<void(int,int)>fun){
- visit[k]=1;
- //正在访问
- path[m++]=k;
- for(int i=0;i<map.cols();i++){
- if(map(k,i)==1){
- //2个点之间有边
- if(visit[i]==0){
- route_searching1(map, visit, path, m, i, fun);
- //递归去访问
- }
- if(visit[i]==1){
- //出现环 打印出来
- for(int j=m-1;;j--){
- if(path[j]==i){
- fun(j, m-1);
- break;
- }
- }
- }
- //表示当前点访问过
- if(visit[i]==-1)
- {
- continue;
- }
- }
- }
- visit[k]=-1;
- //访问结束
- m--;
- }
参数:
-
- //使用栈,非递归
- //优点:不会爆栈
- void route_searching2(Eigen::MatrixXi& map, std::vector<int>& visit, std::function<void(std::vector<int>&,int,int)>fun){
- std::vector<int> path(map.rows(),0);
- //路径
- int m = 0;
- //路径中当前位置
- std::vector<std::pair<int,int>>stack;
- //栈
-
- for(int i=0;i<map.rows();i++){
- stack.push_back({i, m});
-
- while(stack.size()){
- std::pair<int,int> pair = stack.back();
- stack.pop_back();
-
- //回溯(将当前点后面的路径设置为已访问过)
- while(pair.second < m){
- visit[path[--m]] = -1;
- }
-
- int id = pair.first;
- if(visit[id]==0){
- //未访问
- path[m++] = id;
- //添加路径
- visit[id] = 1;
- //正在访问
- //下一个点(有可能有多个)
- for(int j = 0; j < map.cols(); ++j){
- if(map(id,j)){
- stack.push_back({j, m});
- }
- }
- }
- else if(visit[id]==1){
- //找到环
- for(int j=m-1;;j--){
- if(path[j]==id){
- fun(path, j, m-1);
- break;
- }
- }
- }
- else if(visit[id]==-1){
- //已访问过
- continue;
- }
- }
- //清空路径并设置已访问
- while(m){
- visit[path[--m]] = -1;
- }
- }
- }
参数:
adjacency_list、first,、next,:邻接表 out:输出
- struct STACK {
- int idx;
- int m;
- };
-
- //使用栈,非递归
- //优点:不会爆栈,内存占用少
-
- void route_searching3(int n, std::vector<std::pair<int, int>>&adjacency_list,std::vector<int>&first,std::vector<int>&next, std::function<void(int*, int, int)>fun) {
- std::vector<int> visit(n, 0);
- std::vector<int> path(n, -1);
- int m = 0;
- //路径中当前位置
- std::vector<STACK>stack;
- //栈
-
- for (int i = 0; i < n; i++) {
- if (visit[i] == -1)
- continue;
-
- stack.push_back({ i, m });
-
- while (stack.size()) {
- STACK cur_pt = stack.back();
- stack.pop_back();
-
- //回溯(将当前点后面的路径设置为已访问过)
- while (cur_pt.m < m) {
- visit[path[--m]] = -1;
- }
-
- int idx = cur_pt.idx;
- if (visit[idx] == 0) {
- //未访问
- path[m++] = cur_pt.idx;
- //添加路径
- visit[idx] = 1;
- //正在访问
-
- int next_id = first[idx];
- while (next_id != -1) {
- stack.push_back({ adjacency_list[next_id].second, m });
- next_id = next[next_id];
- }
- }
- else if (visit[idx] == 1) {
- //找到环
- for (int j = m - 1;; j--) {
- if (path[j] == idx) {
- fun(path.data(), j, m-1);
- break;
- }
- }
- }
- else if (visit[idx] == -1) {
- //已访问过
- continue;
- }
- }
- while (m) {
- visit[path[--m]] = -1;
- }
- }
- }
- //.h
- //数据结构
- struct holeEdge{
- QPoint p1;
- QPoint p2;
- };
-
- //类成员变量
- std::vector<holeEdge*> circularNodes;//有向线段
- std::vector<std::vector<QPoint>>out_pts;//输出
- std::vector<QPoint>pts;
-
- //.cpp
-
- bool operator < (const QPoint& p1,const QPoint& p2){
- if(p1.x() != p2.x())
- return p1.x() < p2.x();
- if(p1.y() != p2.y())
- return p1.y() < p2.y();
- return false;
- }
-
- void Widget::getCircular(std::vector<holeEdge*> &circularNodes, int flag ){
- //递归算法 + 邻接矩阵
- if(flag == 0){
- std::map<QPoint, int>pts_map;
- std::vector<std::pair<int,int>>pairs;
-
- pts.clear();
- for(auto& edge : circularNodes){
- auto pair1 = pts_map.insert(std::make_pair(edge->p1, pts.size()));
- if(pair1.second){
- pts.push_back(edge->p1);
- }
- auto pair2 = pts_map.insert(std::make_pair(edge->p2, pts.size()));
- if(pair2.second){
- pts.push_back(edge->p2);
- }
- pairs.push_back(std::make_pair(pair1.first->second, pair2.first->second));
- }
-
- Eigen::MatrixXi map(pts.size(),pts.size());//邻接矩阵
- map.setZero();
-
- std::vector<int> visit(pts.size(),0);//访问标记 -1:已访问;0为访问;1正在访问
- std::vector<int> path(pts.size(), -1);
-
- int m = 0;
-
- for(int i = 0; i < pairs.size(); ++i){
- auto pair = pairs[i];
- map(pair.first,pair.second) = 1;
- }
-
- out_pts.clear();
- for(int i=0;i<pts.size();i++){
- if(visit[i]!=-1)
- route_searching1(map, visit, path, m, i,[&](int a, int b){
- std::vector<QPoint> pt;
- for(int j = a; j <= b; j++)
- pt.push_back(pts[path[j]]);
- out_pts.push_back(pt);
- });
- }
- }
- //非递归 + 邻接矩阵
- else if (flag == 1){
- std::map<QPoint, int>pts_map;
- std::vector<std::pair<int,int>>pairs;
-
- pts.clear();
- for(auto& edge : circularNodes){
- auto pair1 = pts_map.insert(std::make_pair(edge->p1, pts.size()));
- if(pair1.second){
- pts.push_back(edge->p1);
- }
- auto pair2 = pts_map.insert(std::make_pair(edge->p2, pts.size()));
- if(pair2.second){
- pts.push_back(edge->p2);
- }
- pairs.push_back(std::make_pair(pair1.first->second, pair2.first->second));
- }
-
- Eigen::MatrixXi map(pts.size(),pts.size());//邻接矩阵
- map.setZero();
-
- std::vector<int> visit(pts.size(),0);//访问标记 -1:已访问;0为访问;1正在访问
- std::vector<int> path(pts.size(), -1);
-
- int m = 0;
-
- for(int i = 0; i < pairs.size(); ++i){
- auto pair = pairs[i];
- map(pair.first,pair.second) = 1;
- }
-
- out_pts.clear();
-
- for(int i=0;i<pts.size();i++){
- if(visit[i]!=-1)
- route_searching2(map, visit,[&](std::vector<int>&path, int a, int b){
- std::vector<QPoint> pt;
- for(int j = a; j <= b; j++)
- pt.push_back(pts[path[j]]);
- out_pts.push_back(pt);
- });
- }
- }
- //非递归 + 邻接表
- else if (flag == 2){
- std::vector<std::vector<int>> points_out;
-
- std::map<QPoint, int>map_pt;
- std::vector<QPoint>vertices;
-
- for (int i = 0; i < circularNodes.size(); i++) {
- holeEdge* edge = circularNodes[i];
- auto pair1 = map_pt.insert({ edge->p1, vertices.size()});
- if (pair1.second) {
- vertices.push_back(edge->p1);
- }
- auto pair2 = map_pt.insert({ edge->p2, vertices.size() });
- if (pair2.second) {
- vertices.push_back(edge->p2);
- }
- }
-
- std::vector<std::pair<int,int>>adjacency_list;//邻接表
- std::vector<int>first(vertices.size(),-1);
- std::vector<int>next(circularNodes.size(), -1);
-
- for (int i = 0; i < circularNodes.size(); i++) {
- holeEdge* edge = circularNodes[i];
- int u = map_pt[edge->p1];
- int v = map_pt[edge->p2];
- adjacency_list.push_back({u,v});
-
- int idx = adjacency_list.size() - 1;
- next[idx] = first[u];
- first[u] = idx;
- }
-
- route_searching3(vertices.size(), adjacency_list, first, next, [&points_out](int *path, int start, int end) {
- if (end - start >= 2) {
- std::vector<int>& vec = points_out.emplace_back();
- while (start <= end)
- vec.push_back(path[start++]);
- }
- });
-
- out_pts.clear();
- for(auto& vec : points_out){
- std::vector<QPoint> vec2;
- for(int i : vec){
- vec2.push_back(vertices[i]);
- }
- out_pts.push_back(vec2);
- }
- }
- }
-
-
- Widget::Widget(QWidget *parent)
- : QWidget(parent)
- , ui(new Ui::Widget)
- {
- ui->setupUi(this);
-
- //构建实验数据
- //1
- circularNodes.push_back(new holeEdge{QPoint(146,431),QPoint(270,461)});
- circularNodes.push_back(new holeEdge{QPoint(270,461),QPoint(254,321)});
- circularNodes.push_back(new holeEdge{QPoint(254,321),QPoint(163,338)});
- circularNodes.push_back(new holeEdge{QPoint(163,338),QPoint(146,431)});
-
- //2
- circularNodes.push_back(new holeEdge{QPoint(254,321),QPoint(309,388)});
- circularNodes.push_back(new holeEdge{QPoint(309,388),QPoint(425,407)});
- circularNodes.push_back(new holeEdge{QPoint(425,407),QPoint(465,337)});
- circularNodes.push_back(new holeEdge{QPoint(465,337),QPoint(404,268)});
- circularNodes.push_back(new holeEdge{QPoint(404,268),QPoint(254,321)});
-
- //3
- circularNodes.push_back(new holeEdge{QPoint(254,321),QPoint(326,241)});
- circularNodes.push_back(new holeEdge{QPoint(326,241),QPoint(308,158)});
- circularNodes.push_back(new holeEdge{QPoint(308,158),QPoint(162,160)});
- circularNodes.push_back(new holeEdge{QPoint(162,160),QPoint(125,255)});
- circularNodes.push_back(new holeEdge{QPoint(125,255),QPoint(254,321)});
-
- //4
- circularNodes.push_back(new holeEdge{QPoint(308,158),QPoint(370,94)});
- circularNodes.push_back(new holeEdge{QPoint(370,94),QPoint(238,49)});
- circularNodes.push_back(new holeEdge{QPoint(238,49),QPoint(197,118)});
- circularNodes.push_back(new holeEdge{QPoint(197,118),QPoint(308,158)});
-
- //5
- circularNodes.push_back(new holeEdge{QPoint(577,528),QPoint(712,515)});
- circularNodes.push_back(new holeEdge{QPoint(712,515),QPoint(713,395)});
- circularNodes.push_back(new holeEdge{QPoint(713,395),QPoint(577,528)});
- circularNodes.push_back(new holeEdge{QPoint(569,406),QPoint(577,528)});
-
- //6
- circularNodes.push_back(new holeEdge{QPoint(519,211),QPoint(625,298)});
- circularNodes.push_back(new holeEdge{QPoint(625,298),QPoint(719,247)});
-
- //7
- circularNodes.push_back(new holeEdge{QPoint(480,94),QPoint(574,131)});
- circularNodes.push_back(new holeEdge{QPoint(574,131),QPoint(543,21)});
- circularNodes.push_back(new holeEdge{QPoint(543,21),QPoint(480,94)});
-
- //getCircular(circularNodes, 0);
- //getCircular(circularNodes, 1);
- getCircular(circularNodes, 2);
- }
-
- Widget::~Widget()
- {
- delete ui;
- }
-
-
- void Widget::paintEvent(QPaintEvent *event)
- {
- QPainter painter(this);
- #if 0
- painter.setPen(Qt::red);
- for(auto& edge : circularNodes){
- painter.drawLine(edge->p1, edge->p2);
- }
- #else
- for(auto& path : out_pts){
- painter.setBrush(QColor(rand()%255,rand()%255,rand()%255));
- painter.drawPolygon(path.data(), path.size());
- }
- #endif
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。