用STL容器实现Dijkstraalg算法
2016-05-14 23:51
218 查看
写在前面的话: 第一篇博客。创建这个账号的念头纯属是自己在写编程作业时绕了许多弯路,几乎坚持不下去时所产生的念头。既然这么辛苦,为什么不一点点记录下来呢。留给以后的自己再看看。同时也和在编程这条路上奋斗的诸君共勉。这是学校通信网理论基础的题目。要求用STL容器实现:给定加权图G,并给定顶点s和d,求从s到d的最小权重路径。设计一个CPath类,从Dijkstra计算得到的CVertex中重构出一个CPath对象,并输出。
如下:
// Author : SJQ From:Uestc 2016/5/15
如下:
</pre><pre name="code" class="cpp">#include"add.h" #include"CEdge.h" #include"tryy.h" class cgraph { private: int numvertex,numedge; list<cedge *>incidentlist; map<int,cvertex *>mapVID_vertex; // all cvertex list<cvertex *>listtempmark;// 暂时标记的顶点的集合 map<int,list<cedge*>>mapVID_listedge;//记录与顶点关联的出度边; public: cgraph(char* inputFile); cgraph(list<cedge*> listedge); cgraph(cgraph &); ~cgraph(); void Dijkstraalg(int s); void PrintShortestPath(int s, int f); void PrintAllShortestPath(int s); void DeleteIncidentList(int c); void update(int VID); void pro2_1output(); void update2(int VID); void Dijkstraalg2(int s); void PrintShortestPath2(int s,int f); }; int main() { cgraph* graph = new cgraph("dijkstra.txt"); graph->Dijkstraalg(1);//测试源结点为1的所有最短路的dijkstra和相应输出 graph->PrintAllShortestPath(1); cout<<"function pro2_1"<<endl; graph->PrintShortestPath(1,6);//单源单宿测试 graph->Dijkstraalg2(1); cout<<"function pro2_2"<<endl; graph->PrintShortestPath2(1,6); int c; cout<<"input the lower limit capacity"<<endl; cin>>c ; void DeleteIncidentList(int c); //pro2_3 graph->Dijkstraalg(1);//仍以1为例,假设删除小于c权重的边后1节点仍在图中 cout<<"function pro2_3"<<endl; graph->PrintShortestPath2(1,6); system("pause"); } void cgraph::Dijkstraalg(int s) { map<int,cvertex*>::iterator i,iend; iend=mapVID_vertex.end(); for(i=mapVID_vertex.begin();i!=iend;i++) { if(i->second->ID==s) i->second->d=0; listtempmark.push_back(i->second); } update(s); while(!listtempmark.empty()) { listtempmark.sort(pvertexcomp); int j=(*listtempmark.begin())->ID; listtempmark.pop_front(); update(j); } } void cgraph::update(int VID) { list<cedge *> ledge=mapVID_listedge[VID]; //与顶点关联的边 list<cedge *>::iterator i, iend; iend=ledge.end(); for(i=ledge.begin();i!=iend;i++) { double w=(*i)->getweight(); cvertex* h=mapVID_vertex[(*i)->gettail()]; cvertex* t=mapVID_vertex[VID]; if(t->d+w<h->d) { h->d=t->d+w; h->p=VID; } } } cgraph::cgraph(char* inputFile) { ifstream file(inputFile); int s,f,n; cout<<"input the s and the destination you wanted,after input please enter;"<<endl; cin>>s>>f; file>>numvertex>>numedge; for (int i = 1; i < 7; i++) { cvertex* vp; vp = new cvertex(INFINITY, NULL, i); mapVID_vertex[i] = vp; } for(int i=0;i<numedge;i++) { int edgid,tail,head,weight,cap; file>>edgid>>tail>>head >>weight>>cap; cout<<edgid<<" "<<tail<<" "<<head<<" "<<weight<<" "<<cap<<endl; cedge *ep=new cedge(edgid,tail,head,weight,cap); incidentlist.push_back(ep); for(n=0;n<numvertex;n++) //向mapVID_listedge导入每个节点出度边 { if(head==n) { //list<cedge*>listedge; //listedge.push_back(ep); mapVID_listedge .push_back(ep); } } } file.close(); } void cgraph::PrintShortestPath(int s, int f) { cout<< " the length of the shortest path from "<<s<<" to "<<f<<" is: "<<mapVID_vertex[f]->d<<endl; cout<< " the shortest path from "<<s<<" to "<<f<<" is: "; list<int> shortest; shortest.push_front(f); int pre=f; while(s!=pre) { pre = mapVID_vertex[pre]->p; shortest.push_front(pre); } list<int>::iterator beg, tempiter; for(beg = shortest.begin();beg != shortest.end();beg++) { cout<<*beg << " "; } cout<<endl; } void cgraph::PrintAllShortestPath(int s) { map<int, cvertex*>::iterator mapiter ; for (mapiter = mapVID_vertex.begin(); mapiter != mapVID_vertex.end(); mapiter++) { if ( s != mapiter->second->ID) { PrintShortestPath(s, mapiter->second->ID); } } } cgraph::~cgraph() { }
const int INFINITY=9999; #define NUL 0 class cvertex{ public: int d; int p; int ID; cvertex(){ d=INFINITY; p=NUL;} cvertex(int dis, int pre, int vid){d = dis; p = pre; ID = vid;} ~cvertex(); }; bool pvertexcomp ( cvertex* x, cvertex* y ); bool pvertexcomp ( cvertex* x, cvertex* y ) { if ( x->d < y->d ) return true; return false; }cedge里定义id,weight,tail,head,capacity即可。此处不赘述。希望大家有问题指出。或者有更好的写法都可以交流。
// Author : SJQ From:Uestc 2016/5/15
相关文章推荐
- C#实现子窗体与父窗体通信方法实例总结
- java和c#使用hessian通信的方法
- 浅析STL中的常用算法
- STL区间成员函数及区间算法总结
- win32下进程间通信(共享内存)实例分析
- WinForm实现跨进程通信的方法
- C#中使用UDP通信实例
- ASP.NET UserControl 通信的具体实现
- c++ STL容器总结之:vertor与list的应用
- C++在成员函数中使用STL的find_if函数实例
- 浅析iOS应用开发中线程间的通信与线程安全问题
- 关于STL中list容器的一些总结
- PHP多线程编程之管道通信实例分析
- flex与js通信与彼此之间的互调整理(一)
- 关于STL中的map容器的一些总结
- Perl的Mail::POP3Client模块和Gmail通信实例
- 使用DNode实现php和nodejs之间通信的简单实例
- 嵌入式iframe子页面与父页面js通信的方法
- Android单片机与蓝牙模块通信实例代码
- Android Socket通信详解