openmesh 基底和减枝

本文介绍了一种使用广度优先搜索(BFS)方法遍历三维模型并简化其结构的算法。该算法通过标记和剪枝技术减少模型的复杂度,同时保持关键特征。具体步骤包括对面的遍历、边的标记及迭代剪枝过程。

思路

先用vector模拟队列采用bfs方法来遍历所有的面,并对如果没有遍历过的面的公共边进行标记,将高亮设为false。剪枝则是反复遍历点的边,如果为高亮且这个点的高亮边只有一条,那么就将这条边的高亮设为false。直到没有点的高亮边的数量为1。

#include <iostream>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
#include <OpenMesh/Core/Utils/Property.hh>
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Mesh/Status.hh>



using namespace std;

typedef OpenMesh::TriMesh_ArrayKernelT<>  MyMesh;

struct MyTraits : public OpenMesh::DefaultTraits
{
	VertexTraits
	{
		int some_additional_index;
	};
};


vector<int>save_point[20000];
vector<int>mark_point;
map<int, int>do_mark_map;
map<int, int>read_mark;
map<int, int>mark_dd;
map<int, int>point_size;
map<int, map<int, int>>save_edge;
vector<MyMesh::FaceHandle>f_vector;
int get_s=0;
void find_path(int from,int last){
	if (mark_dd[from]){ get_s++; return; }
	for (int ii = 0; ii < save_point[from].size(); ii++){
		int yy = save_point[from][ii];
		if (yy!=last){
			mark_dd[yy] = 1;
			find_path(yy,from);
		}
	}
}

int main()
{
	
	MyMesh mesh;	
	OpenMesh::FPropHandleT<bool> fprop_bool;
	OpenMesh::EPropHandleT<bool> highlight;
	mesh.add_property(fprop_bool);
	mesh.add_property(highlight, "highlight");
	//unsigned int point_size = mesh.n_vertices();

     int num_v = mesh.n_vertices();

	if (!OpenMesh::IO::read_mesh(mesh, "meshes/cat.off")){
		cerr << "can't open the file." << endl;
		exit(1);
	}

	for (MyMesh::EdgeIter e_it = mesh.edges_begin(); e_it != mesh.edges_end(); ++e_it){
		mesh.property(highlight, *e_it) = true;
		mesh.property(highlight).set_persistent(true);
	}

	MyMesh::FaceIter f_it = mesh.faces_begin();
	
	f_vector.push_back(*f_it);
	vector<MyMesh::FaceHandle>::iterator f_vector_begin;
	int begin = 0;
	while (begin!=f_vector.size()){
		MyMesh::FaceHandle f_handle=f_vector[begin];
		for (auto it = mesh.fh_begin(f_handle); it != mesh.fh_end(f_handle); ++it){
			MyMesh::HalfedgeHandle halfedge_op_it = mesh.opposite_halfedge_handle(*it);
			MyMesh::Halfedge hh = mesh.halfedge(halfedge_op_it);
			
			MyMesh::FaceHandle f_op_it = mesh.face_handle(halfedge_op_it);
			if (!mesh.property(fprop_bool, f_op_it)){
				mesh.property(fprop_bool, f_op_it) = true;
				f_vector.push_back(f_op_it);
				mesh.property(highlight, mesh.edge_handle(halfedge_op_it)) = false;
			}
		}
		begin++;
	}
	bool mark;
	while (1){
		mark = false;
		for (auto v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it){
			int number = 0;
			for (auto ve_it = mesh.ve_begin(*v_it); ve_it != mesh.ve_end(*v_it); ++ve_it){
				if (mesh.property(highlight, *ve_it)){
					number++;
				}
			}
			if (number == 1){
				mark = true;
				for (auto ve_it = mesh.ve_begin(*v_it); ve_it != mesh.ve_end(*v_it); ++ve_it){
					mesh.property(highlight, *ve_it) = false;
					}
				}
			}
		if (!mark)break;
		}
	mesh.property(highlight).set_persistent(true);
	
	std::cout << mesh.n_edges() <<" "<< mesh.n_vertices()<<endl;
	std::cout << endl;

	try {
		if (!OpenMesh::IO::write_mesh(mesh, "meshes/cat3.om")) {
			std::cerr << "Cannot write mesh to file 'output.off'" << std::endl;
			return 1;
		}
	}
	catch (std::exception& x)
	{

		std::cerr << x.what() << std::endl;
		return 1;
	}
	std::cin.get();
	return 0;
}


### 决策树中预剪与后剪的概念及区别 #### 预剪概念 预剪是指在构建决策树的过程中,在每次分裂之前,先评估当前节点的划分是否能够提高模型的泛化能力。如果预计不会带来性能提升,则提前终止该分支的增长,并将其标记为叶节点[^3]。 #### 后剪概念 后剪则是指首先生成一颗完整的决策树,随后通过自底向上的方式逐一对非叶子节点进行检验。对于每一个非叶子节点,判断其对应的子树是否可以用单一的叶节点替代来获得更好的泛化效果。如果是,则将此子树替换为单个叶节点。 #### 主要区别 1. **结构复杂度** - 预剪倾向于较早地停止生长,因此产生的决策树通常较为简单,分支较少。 - 而后剪允许初始阶段充分扩展整棵树后再做裁,所以最终得到的树可能更加复杂并保留更多细节[^2]。 2. **过拟合/欠拟合风险** - 由于预剪可能会因为过于保守而错过某些潜在有用的特征分割点,存在较高的欠拟合可能性。 - 反之,后剪因前期不加限制地发展整个树形结构,再依据验证数据调整局部区域,故其欠拟合的风险相对较低[^1]。 3. **计算成本** - 实施预剪时只需考虑每一步操作的影响即可决定下一步行动方向,整体流程简洁明快,所需资源消耗也较小。 - 对于后剪而言,除了正常建立全量版决策树外还需额外执行一轮逆序扫描优化动作,这无疑增加了算法运行时间内存占用情况。 4. **实际表现差异** - 尽管如此,实验表明大多数情形下采用后剪方法所获模型具备更强适应未知样本的能力即更高的准确性得分;然而这一切是以牺牲效率换取质量的结果作为代价呈现出来的。 ```python # 示例代码展示如何实现简单的预剪逻辑 (伪代码形式) def pre_prune(node, dataset): if not can_improve_generalization(dataset): node.set_as_leaf() return split_dataset_into_subsets() # 进行常规的数据拆分处理... for subset in subsets: new_node = create_new_child_node(subset) # 创建新的孩子节点对象实例.. pre_prune(new_node, subset) # 继续递归调用本函数直至满足条件为止. ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值