通信网Project之——单源单宿最短路问题
最主要的Vertex类:
#ifndef VERTEX_H
#define VERTEX_H #include <climits>
#include <cstddef>
#define INF INT_MAX class Vertex
{
public:
int ID;
Vertex* parent;
int d; Vertex(int id) : ID(id), d(INF), parent(NULL){}
}; #endif
接下来是Edge类:
#ifndef EDGE_H
#define EDGE_H #include "vertex.h" class Edge
{
private:
float weight;
float capacity;
float passrate; public:
int id;
Vertex* tail;
Vertex* head;
/******** constructor *******/
Edge(int ID, Vertex& t, Vertex& h, float wght = 1,
float cap = 1, float pssrt = 1) :
id(ID), head(&h), tail(&t), weight(wght),
capacity(cap), passrate(pssrt) {} /********** The ID **********/
void setId(int ID)
{
id = ID;
}
int getId()
{
return id;
} /********* The vertex ********/
void setTail(Vertex& v)
{
tail = &v;
}
void setHead(Vertex& v)
{
head = &v;
} /******** Other method *******/
void setWeight(const float w)
{
weight = w;
}
float getWeight()
{
return weight;
}
float getCapacity()
{
return capacity;
}
float getPassRate()
{
return passrate;
} }; #endif
当然还有路问题须要的Path类:
#ifndef PATH_H
#define PATH_H #include <list>
#include "vertex.h" class Path : std::list<Vertex*>
{
public:
Path(Vertex& tail); void print();
}; #endif
这是Path类的实现:
#include "path.h"
#include <iostream>
#include "vertex.h"
#include <list> using namespace std; Path::Path(Vertex& tail)
{
Vertex* temp = &tail;
while (temp->parent != NULL)
{
push_back(temp);
temp = temp->parent;
}
push_back(temp);
} void Path::print()
{
reverse();
list<Vertex*>::iterator it;
it = begin();
cout << "Vertex " << (*it)->ID;
it++;
for (; it != end(); it++)
cout << " -> Vertex " << (*it)->ID;
}
下来就是最重要也是最复杂的Graph类了!
#ifndef GRAPH_H
#define GRAPH_H #include <map>
#include "edge.h"
#include "vertex.h"
#include "path.h"
#include <set>
#include <list> class Graph
{
std::map<int, Vertex*> vertexMap;
// The map: vertex and its incident edge.
std::map<Vertex*, std::list<Edge*> > incMap;
std::set<Edge*> edgeList;
std::list<Vertex*> notMarkedVertex;
bool fromFile;
Path* path; void update(Vertex* v); public:
/********** constructor *********/
Graph(): fromFile(false){}
Graph(const char* inputFileName);
Graph(std::list<Edge*>& edge);
~Graph(); /*********** size info **********/
int getNumVertex()
{
return vertexMap.size();
}
int getNumEdge()
{
return edgeList.size();
} void print();
void addEdge(Edge& edge);
void dijkstra(int s, int d);
void dijkstra(Vertex& s, Vertex& d);
}; #endif
下来是实现:
#include "graph.h"
#include <iostream>
#include <fstream>
#include <map>
#include <set>
#include <list>
#include <string>
#include <cstdlib> using namespace std; Graph::Graph(const char* inputFileName)
{
fromFile = true;
ifstream in(inputFileName); string s;
getline(in, s);
getline(in, s); while (in.good())
{
int id, tail, head;
float weight, capacity, passrate;
in >> id >> tail >> head
>> weight >> capacity >> passrate;
map<int, Vertex*>::iterator it;
it = vertexMap.find(tail); Vertex *t;
Vertex *h; if (it == vertexMap.end())
t = new Vertex(tail);
else
t = it->second; it = vertexMap.find(head);
if (it == vertexMap.end())
h = new Vertex(head);
else
h = it->second; Edge* e = new Edge(id, *t, *h, weight, capacity, passrate);
addEdge(*e);
}
} Graph::Graph(list<Edge*>& edge)
{
list<Edge*>::iterator it;
for (it = edge.begin(); it != edge.end(); it++)
addEdge(**it);
fromFile = false;
} void Graph::addEdge(Edge& edge)
{
edgeList.insert(&edge);
vertexMap.insert(pair<int, Vertex*>(edge.tail->ID, edge.tail));
vertexMap.insert(pair<int, Vertex*>(edge.head->ID, edge.head)); if (incMap.find(edge.tail) == incMap.end())
{
list<Edge*>* l = new list<Edge*>(1, &edge);
incMap.insert(pair<Vertex*, list<Edge*> >(edge.tail, *l));
}
else
incMap.find(edge.tail)->second.push_back(&edge);
} void Graph::print()
{
map<Vertex*, list<Edge*> >::iterator it;
list<Edge*>::iterator it2;
for (it = incMap.begin(); it != incMap.end(); it++)
{
cout << "Vertex " << it->first->ID << endl;
for (it2 = it->second.begin();
it2 != it->second.end();
it2++)
cout << "\tEdge " << (*it2)->id << " to Vertex "
<< (*it2)->head->ID << endl;
}
} Graph::~Graph()
{
if (fromFile)
{
set<Edge*>::iterator it;
for (it = edgeList.begin();
it != edgeList.end();
it++)
delete *it; map<int, Vertex*>::iterator it2;
for (it2 = vertexMap.begin();
it2 != vertexMap.end();
it2++)
delete it2->second;
}
} bool comp(Vertex* a, Vertex* b)
{
return a->d < b->d;
} void Graph::update(Vertex* v)
{
list<Edge*> inc = incMap[v];
if (inc.size() == 0)
{
cerr << "No out degree!" << endl;
exit(EXIT_FAILURE);
} list<Edge*>::iterator it;
for (it = inc.begin(); it != inc.end(); it++)
{
int d = v->d + (*it)->getWeight();
if ((*it)->head->d > d)
{
(*it)->head->parent = v;
(*it)->head->d = d;
}
}
} void Graph::dijkstra(int sid, int did)
{
Vertex* s = vertexMap[sid];
Vertex* temp;
s->d = 0; map<int, Vertex*>::iterator it;
for (it = vertexMap.begin();
it != vertexMap.end();
it++)
if (it->second->ID != sid)
notMarkedVertex.push_back(it->second);
update(s); do
{
notMarkedVertex.sort(comp);
temp = notMarkedVertex.front();
notMarkedVertex.pop_front();
if (temp->ID == did)
break;
update(temp);
}while(!notMarkedVertex.empty()); path = new Path(*vertexMap[did]);
path->print();
} void Graph::dijkstra(Vertex& s, Vertex& d)
{
dijkstra(s.ID, d.ID);
}
眼下的工作就是这些了。
以下是一个測试程序:
test.cpp:
#include <iostream>
#include "graph.h"
#include "path.h" using namespace std; int main()
{
Graph graph("InputFile.txt");
graph.print(); cout << "Please input the s and d: ";
int s, d;
cin >> s >> d;
graph.dijkstra(s, d); return 0;
}
还有InputFile.txt 的内容:
n 7
e 9
1 1 2 1 20 0.8
2 2 3 5 30 0.8
3 3 6 6 22 0.6
4 7 6 5 22 0.4
5 1 7 3 20 0.2
6 5 6 2 20 0.3
7 3 5 1 20 0.5
8 4 5 6 20 0.6
9 2 4 2 20 0.7
最后是执行结果了!
通信网Project之——单源单宿最短路问题的更多相关文章
- Vijos 1006 晴天小猪历险记之Hill 单源单汇最短路
背景 在很久很久以前,有一个动物村庄,那里是猪的乐园(^_^),村民们勤劳.勇敢.善良.团结-- 不过有一天,最小的小小猪生病了,而这种病是极其罕见的,因此大家都没有储存这种药物.所以晴天小猪自告奋勇 ...
- 单源最短路问题:OJ5——低德地图
本题就是一道单源最短路问题.由于是稀疏图,我们采用Dijkstra算法. Dijkstra算法原理 Dijkstra算法的步骤 我们把所有的节点分为两个集合:被选中的(visited==1) 和 未被 ...
- [ACM_图论] Domino Effect (POJ1135 Dijkstra算法 SSSP 单源最短路算法 中等 模板)
Description Did you know that you can use domino bones for other things besides playing Dominoes? Ta ...
- UVa 12661 (单源最短路) Funny Car Racing
题意: 有一个赛车跑道,可以看做一个加权有向图.每个跑道(有向边)还有一个特点就是,会周期性地打开a秒,然后关闭b秒.只有在赛车进入一直到出来,该跑道一直处于打开状态,赛车才能通过. 开始时所有跑道处 ...
- 利用分支限界法求解单源最短路(Dijkstra)问题
分支限界法定义:采用Best fist search算法,并使用剪枝函数的算法称为分支界限法. 分支限界法解释:按Best first的原则,有选择的在其child中进行扩展,从而舍弃不含有最优解的分 ...
- 单源最短路——Bellman-Ford算法
1.Dijkstra的局限性 Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的. 列如以 ...
- 图论-单源最短路-SPFA算法
有关概念: 最短路问题:若在图中的每一条边都有对应的权值,求从一点到另一点之间权值和最小的路径 SPFA算法的功能是求固定起点到图中其余各点的的最短路(单源最短路径) 约定:图中不存在负权环,用邻接表 ...
- [10.26_P2] 最短路 (单源最短路应用)
单源最短路问题拓展 Description 给你一张图,图上有 n 个点,m 条边,要你找到两个点,使其最短路恰好包含给定的 k 个点.输出这条最短路的长度,输入保证有解. 输入格式 第一行两个数 n ...
- 【算法】单源最短路径和任意两点最短路径总结(补增:SPFA)
[Bellman-Ford算法] [算法]Bellman-Ford算法(单源最短路径问题)(判断负圈) 结构: #define MAX_V 10000 #define MAX_E 50000 int ...
随机推荐
- axWindowsMediaPlayer1获取音频长度
OpenFileDialog openFileDialog1 = new OpenFileDialog { InitialDirectory = "c:\\", Filter = ...
- C# WebBrowser.DocumentCompleted 多次调用解决方法
大概出现了以下几种情况. 1.WebBrowser载入一个页面后DocumentCompleted事件会执行两次,但这两次的ReadyState状态不一样,分别是Intercative和Complet ...
- 告别乱码,针对GBK、UTF-8两种编码的智能URL解码器的java实现(转)
效果图 字符 字符是早于计算机而存在,从人类有文明那时起,人们就用一个个符号代表世间万象.如ABC,如“一.二.三”. 字符集 字符集是所有字符的集合. XXX字符集 给字符集中的每一个字符套上一个序 ...
- Cocos2d-X 使用CCTableView创建滚动视图
CCTableView和CCScrollView如创建滚动视图,CCTableView该函数将是更,制造更多麻烦 实例1:使用CCTableView创建滚动视图 首先创建一个TableView类 Ta ...
- FastReport扩展类
题记: 最近有在用FastReport进行开发报表工作,当然也有在看书,突然想到可以用书中所写来实现一个fastreport的帮助类. 对于引用第三方类库,我们都会去将这个库在调用前进行相应的封装,也 ...
- CodeForces 482C Game with Strings
意甲冠军: n一定长度m串 隐藏的字符串相等的概率 然后,你猜怎么着玩家隐藏的字符串 的询问字符串的一个位置 再不断的知道一些位置后 游戏者就能够确定藏起来的串是什么 问 游戏者的期望步 ...
- javascript滚动栏响应鼠标滑轮的实现上下滚动事件
实现鼠标滚动滚轮事件: <script type="text/javascript"><pre name="code" class=" ...
- jquery ui tab跳转
1.tabs_iframe.jsp <%-- Document : tabs Created on : 2015-2-28, 14:44:02 Author : liyulin lyl01099 ...
- cocos2d-x使用CCClippingNode实现跑马灯
直接在代码,这是一个很好的包layer,可以直接调用 //原来白白 bool TestLayer::init() { CCSize size = CCDirector::sharedDirector ...
- 【SSH2(实用文章)】--Struts2文件上传和下载的例子
回想一下,再上一篇文章Struts2实现机制,该步骤做一步一步来解决,这种决心不仅要理清再次Struts2用法.映射机制及其在深入分析.最后一个例子来介绍Struts2一种用法,这里将做一个有关文件上 ...