我们经常用dijkstra算法来计算最短路径,其原理可以参考http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm.
boost库也提供了它的实现,我们就以上图为准,利用boost库中dijkstra算法对其做一个简单的实现:
#include <iostream> #include<boost\graph\adjacency_list.hpp> #include<boost\graph\dijkstra_shortest_paths.hpp> typedef boost::adjacency_list < boost::listS, boost::vecS, boost::directedS, boost::no_property, boost::property < boost::edge_weight_t, unsigned long > > graph_t; typedef boost::graph_traits < graph_t >::vertex_descriptor vertex_descriptor; typedef boost::graph_traits < graph_t >::edge_descriptor edge_descriptor; #include<vector> using namespace std; //Node定义 struct Node { int nId; //Node编号 }; //Link定义 struct Link { int nStartNodeId; //起始Node编号 int nEndNodeId; //终止Node编号 int nLength; //Link的长度 Link(int nSId,int nEId,int nLen) { nStartNodeId=nSId; nEndNodeId=nEId; nLength=nLen; } }; //获取路径经过结点的信息 void GetPath(int fromId,int toId,vector<vertex_descriptor>& vPredecessor,std::string& strPath) { vector<int> vecPath; while(fromId!=toId) { vecPath.push_back(toId); //因为本例子的特殊性和自己很懒,所以可以直接取值 toId = vPredecessor[toId]; } vecPath.push_back(toId); vector<int>::reverse_iterator pIter = vecPath.rbegin(); strPath="路径:"; std::string strOperator="->"; char c[20]={}; for(;pIter!=vecPath.rend();pIter++) { itoa(*pIter,c,10); if(*pIter!=fromId) { strPath+=(strOperator+c); } else { strPath+=c; } } } int _tmain(int argc, _TCHAR* argv[]) { //构造Node集合 vector<Node> vecNodes; for(int i=1;i<=6;i++) { Node nd; nd.nId = i; vecNodes.push_back(nd); } //构造Link集合 vector<Link> vecLinks; Link lk(1,3,9); vecLinks.push_back(lk); Link lk1(1,2,7); vecLinks.push_back(lk1); Link lk2(1,6,14); vecLinks.push_back(lk2); Link lk3(2,4,15); vecLinks.push_back(lk3); Link lk4(2,3,10); vecLinks.push_back(lk4); Link lk5(3,4,11); vecLinks.push_back(lk5); Link lk6(3,6,2); vecLinks.push_back(lk6); Link lk7(6,5,9); vecLinks.push_back(lk7); Link lk8(4,5,6); vecLinks.push_back(lk8); //图定义 graph_t g; g.clear(); boost::property_map<graph_t, boost::edge_weight_t>::type pmpWeightmap = boost::get(boost::edge_weight, g); for(int i=0;i<vecLinks.size();i++) { edge_descriptor edEdge; bool bInserted; //加入Link的起始和终止NodeID boost::tie(edEdge,bInserted)=boost::add_edge(vecLinks[i].nStartNodeId,vecLinks[i].nEndNodeId,g); //加入Link的长度 pmpWeightmap[edEdge]=vecLinks[i].nLength; } //路径计算结果定义 vector<vertex_descriptor> vPredecessor(boost::num_vertices(g)); //存储从起始结点到其他结点的路径上经过的最后一个中间结点序号 vector<unsigned long> vDistance(boost::num_vertices(g)); //存储起始结点到其他结点的路径的距离 //路径探索起始点定义 vertex_descriptor s = boost::vertex(vecNodes[0].nId, g); //路径计算 boost::property_map<graph_t, boost::vertex_index_t>::type pmpIndexmap = boost::get(boost::vertex_index, g); boost::dijkstra_shortest_paths(g, s, &vPredecessor[0], &vDistance[0], pmpWeightmap, pmpIndexmap, std::less<unsigned long>(), boost::closed_plus<unsigned long>(), std::numeric_limits<unsigned long>::max(), 0, boost::default_dijkstra_visitor()); std::string strPath; GetPath(1,5,vPredecessor,strPath); cout<<strPath<<endl; cout<<"路径长度:"<<vDistance[5]<<endl; return 0; }