您的位置:首页 > 其它

用STL容器实现Dijkstraalg算法

2016-05-14 23:51 218 查看
写在前面的话: 第一篇博客。创建这个账号的念头纯属是自己在写编程作业时绕了许多弯路,几乎坚持不下去时所产生的念头。既然这么辛苦,为什么不一点点记录下来呢。留给以后的自己再看看。同时也和在编程这条路上奋斗的诸君共勉。这是学校通信网理论基础的题目。要求用STL容器实现:给定加权图G,并给定顶点s和d,求从s到d的最小权重路径。设计一个CPath类,从Dijkstra计算得到的CVertex中重构出一个CPath对象,并输出。
如下:


</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 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  STL dijkstra 通信