写这篇博文是因为我怕一两年内,没碰到这个算法,到时候又把它忘了。因为这个算法是图论中,一个非常重要的算法,经常要用到,为了某一天重新拾起这个算法的时候,能够把下面的代码复制一下,然后改装一下再次快速熟练应用它。这个算法在图形学中的三角网格曲面中,可以说是一个基础算法,目前为止,我至少用过十次。在图像中,我也遇到过好几次,比如我写的另一篇博文《基于测地距离的图像分割算法》,这个算法就要与之相结合。
这个算法本身不难,然而对于解释这个算法的流程网上说的乱七八糟的,很多都是c语言版的,用c语言写这个算法,如果没有用结构体,那代码写了起来很乱,每个顶点有好几个相关的变量。下面直接贴一些自己写的代码,以备以后使用:
一、算法大体流程
输入:图、源点seed
输出、图上每个点到源点的 最短距离
Algorithm:
begin
1、初始化所有的点到源点的距离为无穷大
2、把seed到源点的距离置为0
3、把seed加入队列Queue
4、当Queue不为空的时候 循环
{
(1)从队列中选择距离源点最短的顶点Pmin,并从队列中删除
(2)遍历Pmin的邻接顶点q,更新未被冻结的邻接顶点测地距离,即:
如果,邻接顶点q当前测地距离d(q)<d(Pmin)+E(q,Pmin),其中E(q,Pmin)表示Pmin与q点的连接边的长度,那么:
{
更新d;
更新q的前一个路径点为Pmin
}
(3)往队列里插入Pmin未被访问过的邻接顶点q
}
end
二、算法代码实现
主要程序:
vector<cnode>nodes=m_nodes; nodes[seed].distance_from_source()=0.0;//初始化源点的距离为0 std::set<cnode_pointer cnode=””>Queue0; Queue0.clear(); Queue0.insert(&nodes[seed]);//把源点加入队列 nodes[seed].m_VisitFlag=CNode::Active;//标记为加入队列中 //广度优先遍历 while(!Queue0.empty()) { CNode_pointer min_node = *Queue0.begin(); Queue0.erase(Queue0.begin());//提取队列的第一个元素,也就是距离最小的元素 min_node->m_VisitFlag=CNode::Frozen;//标记为已访问,即已经加入过队列 vector<int>&NeighborE=m_Tmesh->adjancetedge[min_node->m_VertexID];//遍历邻接顶点 int NeighborEN=NeighborE.size(); //更新邻接顶点的到源点的距离 for(int j=0; j<neighboren j=”” tedge=”” ae=”m_Tmesh-“>m_edges[NeighborE[j]]; int neiv=ae.opposite_vertex(min_node->m_VertexID); CNode_pointer New_node=&nodes[neiv]; if(New_node->m_VisitFlag!=CNode::Frozen) { float dist0=(float)(min_node->distance_from_source() +ae.length()); if(New_node->distance_from_source() > dist0) { New_node->distance_from_source() = dist0; New_node->m_Pre_Edge=NeighborE[j]; } } } //邻接顶点中,如果未被加入过队列,那么把这个点插入队列中 int vn_nei0=m_Tmesh->neighbors[min_node->m_VertexID].size(); for (int j=0;j<vn_nei0 j=”” int=”” neighbors_of_u=”m_Tmesh-“>neighbors[min_node->m_VertexID][j]; if (nodes[neighbors_of_u].m_VisitFlag==CNode::Inactive) { Queue0.insert(&nodes[neighbors_of_u]); nodes[neighbors_of_u].m_VisitFlag=CNode::Active; } } }//while</vn_nei0></neighboren></int></cnode_pointer></cnode>
相关头文件:
class CNode { typedef CNode* CNode_pointer; public: CNode(void){m_VisitFlag=Inactive;m_GeodesicDistance =std::numeric_limits<float>::max();}; ~CNode(void){}; enum VisitFlag{Frozen,Active,Inactive}; VisitFlag m_VisitFlag; float m_GeodesicDistance; int m_VertexID; int m_Pre_Edge; float& distance_from_source(){return m_GeodesicDistance;}; virtual bool operator()(CNode_pointer const s1, CNode_pointer const s2) const { return s1->distance_from_source()!=s2->distance_from_source() ? s1->distance_from_source() < s2->distance_from_source() ://不等的时候根据距离排序 s1->m_VertexID< s2->m_VertexID;//相等的时候需要根据ID号来 }; void clear() { m_GeodesicDistance = std::numeric_limits<float>::max();//无穷大数值 m_VisitFlag=Inactive; } }; typedef CNode* CNode_pointer; </float></float>
本文地址:http://blog.csdn.net/hjimce/article/details/45751503 作者:hjimce 联系qq:1393852684 更多资源请关注我的博客:http://blog.csdn.net/hjimce 原创文章,转载请保留本行信息。