通信网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 ...
随机推荐
- Objective-C辛格尔顿
单例类是一种特殊的类.在一个进程种仅仅会存在一个该类的对象,在iOS应用中仅仅会出现一个对象.这样的设计模式在系统框架中很多地方都使用了.如NSFileManager.UIApplication等. ...
- 详谈socket请求Web服务器过程(转)
最开始我们需要明白一件事情,因为这是这篇文章的前提: HTTP协议只是一个应用层协议,它底层是通过TCP进行传输数据的.因此,浏览器访问Web服务器的过程必须先有“连接建立”的发生. 而有人或许会问: ...
- poj2524
说来惭愧啊..现在才会并查集.我竟然给我妈妈讲明白并查集怎么回事了- - #define _CRT_SECURE_NO_WARNINGS #include <iostream> using ...
- dispatch_once认识分析
dispatch_once为了确保代码运行一次 +(NSDateFormatter*)getDBDateFormat { static NSDateFormatter* format; static ...
- HDU 5059 Help him(细节)
HDU 5059 Help him 题目链接 直接用字符串去比較就可以,先推断原数字正确不对,然后写一个推断函数,注意细节,然后注意判掉空串情况 代码: #include <cstdio> ...
- ecshop广告调用方法
在简单地概括ecshop广告调用该方法,已发表在博客上,在这里,我们总结了以下 :就是官方默认的方法.先加入广告位,然后加入模板的广告位区域,再在将两者相应上. 1.后台 > 广告管理 > ...
- atitit.无线上网卡 无法搜索WiFi 解决无线路由器信号不能被连接
atitit.无线上网卡 无法搜索WiFi 解决无线路由器信号不能被连接 #---现象 pc机无线网卡无法搜索到无线路由器的信号.. 但是,笔记本电脑和手机能够... 只要pc机无线网卡可以搜索信号, ...
- 表复制语句select into from 与 insert into select 区别鉴赏
select into from 与 insert into select 区别鉴赏 1.INSERT INTO SELECT语句 语句形式为:Insert into Table2(field1,fi ...
- k8s with flanneld
三台机器 kmaster 192.168.1.201 kslave202 192.168.1.202 kslave203 192.168.1.203 安装好k8s 1. 在Node机器上安装flann ...
- mvc与My97DatePicker插件的结合
Razor视图引擎与My97DatePicker插件的结合 1 using System; 2 using System.Collections.Generic; 3 using System.Run ...