Dijkstra算法的实现
2015-06-01 10:47
375 查看
//dijkstra.cpp
//Dijkstra算法的实现
//读入“DijkstraTxt”中的部分网络数据“Test.txt”(弧段起点ID,弧段终点ID,弧段距离)
//用Dijkstra算法生成的最佳路径再写入“RouteTxt.txt”文件中
#include<iostream>
#include<fstream>
#include<iomanip>
#include<sstream>
using namespace std;
#define MAXIMUM 1000000000 //无穷大
typedef struct recordList{
int startPoint;
//起点
int endPoint;
//终点
float length;
//弧段长度
recordList* next;
//结构体指针
}record; //定义Record结构体类型表示从文件中读取的数据记录
void main()
{
//打开Test.txt并从中读取数据
ifstream inPutFile("Test.txt", ios::in);
//以创建方式打开文件RouteTxt.txt并写入数据
ofstream outPutFile("RouteTxt.txt", ios::out);
if (!inPutFile || !outPutFile)
//文件打开异常处理
{
cout << "文件打开失败!" << endl;
exit(1);
}
outPutFile << "\tDijkstra 算法实现结果数据\t" << endl;
outPutFile << "起点\t终点\t距离\t\t路径" << endl;
int numPoint;
//点数
int numEdge;
//边数
int maxPoint;
//最大点号
record* head = NULL;
//数据链表表头
record* data = NULL;
//读取的一行数据
data = (record*)new record;
//分配一行数据的内存空间
//读取一行数据,包括起点、终点、弧段长度
inPutFile >> data->startPoint >> data->endPoint >> data->length;
head = data;
//数据链表表头指针
numEdge = 1;
//初始边数为1
maxPoint = max(data->startPoint, data->endPoint);
//初始最大点号
while (!inPutFile.eof())
//逐行读取文件中的数据到data中
{
data->next = (record*)new record;
//动态分配内存空间
data = data->next;
//指向下一个结构体
//读取一行数据,包括起点、终点、弧段长度,数据格式(弧段起点ID,弧段终点ID,弧段距离)
inPutFile >> data->startPoint >> data->endPoint >> data->length;
//若maxPiont小于起点或终点点号,更新maxPoint
if (maxPoint < data->startPoint)
maxPoint = data->startPoint;
if (maxPoint < data->endPoint)
maxPoint = data->endPoint;
numEdge++;
//边数增加1
}
inPutFile.close();
//关闭文件流
data->next = NULL;
//最后的指针赋值为空
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////以上代码实现从文件读入数据,以下实现算法计算并写入结果到文件/////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int i, j, k;
//变量
float* path = new float[maxPoint + 1];
//路径距离数组
int* route = new int[maxPoint + 1];
//路由表
bool* flag = new bool[maxPoint + 1];
//最短路径求取成功标记
for (i = 0; i <= maxPoint; i++)
//按点号从小到大遍历所有结点做源结点
{
for (j = 0; j <= maxPoint; j++)
//初始化路由表和路径距离数组
{
path[j] = MAXIMUM;
//路径距离数组初始化为无穷大
route[j] = -1;
//-1表示不能到达或最短路径尚未找出
flag[j] = false;
}
record* getData = head;
//获得链表数据头指针
float minLength = MAXIMUM;
//当前的最小距离
int lastPoint = i;
//前一次找出的距离最短的路径的终点
while (getData != NULL)
//遍历链表,找出源结点出发的最短路径
{
if (getData->startPoint == i)
//起点为i
{
path[getData->endPoint] = getData->length;
//获得源结点到目的结点的距离
route[getData->endPoint] = getData->startPoint;
//路由信息存储为目的结点的前一个结点
if (minLength > getData->length)
//距离小于当前最小距离
{
minLength = getData->length;
//获得当前最小距离
lastPoint = getData->endPoint;
//获得当前最小距离的终点
}
}
getData = getData->next;
//指向下一个结构体
}
flag[lastPoint] = true;
//标记起点到当前终点的最短路径已求出
for (k = 0; k < maxPoint; k++)
//按点号从小到大遍历所有结点做目的结点
{
getData = head;
//获得链表数据头指针
float tempLength = MAXIMUM;
//当前的最小距离
int tempPoint = -1;
//前一次找出的距离最短的路径的终点
while (getData != NULL)
//遍历链表,更新路由信息和距离数组
{
if ((getData->startPoint == lastPoint) && (getData->endPoint != i) && !flag[getData-
>endPoint])
{//起点为上一次最短路径的终点,终点与起点不同,最短路径未求出
if ((minLength + getData->length) < path[getData->endPoint])
//有更短的路径
{
path[getData->endPoint] = minLength + getData->length;
//获得
源结点到目的结点的距离
route[getData->endPoint] = getData->startPoint;
//路由信息存储为目的结点的前一个结点
}
}
getData = getData->next;
//指向下一个结构体
}
for (j = 0; j < maxPoint; j++)
{//遍历path数组,找出到最短路径尚未找出的终点的距离最小值
if (!flag[j] && tempLength >= path[j] && j!=i)
{//最短路径尚未找出,且距离比当前最小距离更小,起点和终点不同
tempLength = path[j];
//更新最小距离值
tempPoint = j;
//更新当前最短路径的终点
}
}
lastPoint = tempPoint;
//获得当前最小距离的终点
minLength = tempLength;
//获得当前最小距离
flag[lastPoint] = true;
//标记起点到当前终点的最短路径已求出
}
////////////////////下面先指定文件写入结果数据///////////////////////////
for (j = 0; j <= maxPoint; j++)
//从每一个结点出发
{
if (path[j] == MAXIMUM)
//路径不可达,或者终点和起点重叠
{
//向文件写入信息
outPutFile << i << "\t" << j << "\t--\t\t--" << endl;
}
else
{
string strRoute;
//路径信息
int r = route[j];
//第j个点为终点时其上一跳位置
while (r!=i)
//根据路由表反向查找路径信息
{
stringstream ss;
//使用字符串流将int转化为string型
ss << r;
//字符串流写入
strRoute = "->" + ss.str() + strRoute;
//构建路径信息字符串
r = route[r];
//上一跳
}
//向文件写入数据 “起点
终点 距离 路径”
outPutFile << i << "\t" << j << "\t" << path[j] << "\t\t" << i << strRoute << "->" << j << endl;
}
}
}
outPutFile.close();
//关闭文件流
return;
}
//Dijkstra算法的实现
//读入“DijkstraTxt”中的部分网络数据“Test.txt”(弧段起点ID,弧段终点ID,弧段距离)
//用Dijkstra算法生成的最佳路径再写入“RouteTxt.txt”文件中
#include<iostream>
#include<fstream>
#include<iomanip>
#include<sstream>
using namespace std;
#define MAXIMUM 1000000000 //无穷大
typedef struct recordList{
int startPoint;
//起点
int endPoint;
//终点
float length;
//弧段长度
recordList* next;
//结构体指针
}record; //定义Record结构体类型表示从文件中读取的数据记录
void main()
{
//打开Test.txt并从中读取数据
ifstream inPutFile("Test.txt", ios::in);
//以创建方式打开文件RouteTxt.txt并写入数据
ofstream outPutFile("RouteTxt.txt", ios::out);
if (!inPutFile || !outPutFile)
//文件打开异常处理
{
cout << "文件打开失败!" << endl;
exit(1);
}
outPutFile << "\tDijkstra 算法实现结果数据\t" << endl;
outPutFile << "起点\t终点\t距离\t\t路径" << endl;
int numPoint;
//点数
int numEdge;
//边数
int maxPoint;
//最大点号
record* head = NULL;
//数据链表表头
record* data = NULL;
//读取的一行数据
data = (record*)new record;
//分配一行数据的内存空间
//读取一行数据,包括起点、终点、弧段长度
inPutFile >> data->startPoint >> data->endPoint >> data->length;
head = data;
//数据链表表头指针
numEdge = 1;
//初始边数为1
maxPoint = max(data->startPoint, data->endPoint);
//初始最大点号
while (!inPutFile.eof())
//逐行读取文件中的数据到data中
{
data->next = (record*)new record;
//动态分配内存空间
data = data->next;
//指向下一个结构体
//读取一行数据,包括起点、终点、弧段长度,数据格式(弧段起点ID,弧段终点ID,弧段距离)
inPutFile >> data->startPoint >> data->endPoint >> data->length;
//若maxPiont小于起点或终点点号,更新maxPoint
if (maxPoint < data->startPoint)
maxPoint = data->startPoint;
if (maxPoint < data->endPoint)
maxPoint = data->endPoint;
numEdge++;
//边数增加1
}
inPutFile.close();
//关闭文件流
data->next = NULL;
//最后的指针赋值为空
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////以上代码实现从文件读入数据,以下实现算法计算并写入结果到文件/////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int i, j, k;
//变量
float* path = new float[maxPoint + 1];
//路径距离数组
int* route = new int[maxPoint + 1];
//路由表
bool* flag = new bool[maxPoint + 1];
//最短路径求取成功标记
for (i = 0; i <= maxPoint; i++)
//按点号从小到大遍历所有结点做源结点
{
for (j = 0; j <= maxPoint; j++)
//初始化路由表和路径距离数组
{
path[j] = MAXIMUM;
//路径距离数组初始化为无穷大
route[j] = -1;
//-1表示不能到达或最短路径尚未找出
flag[j] = false;
}
record* getData = head;
//获得链表数据头指针
float minLength = MAXIMUM;
//当前的最小距离
int lastPoint = i;
//前一次找出的距离最短的路径的终点
while (getData != NULL)
//遍历链表,找出源结点出发的最短路径
{
if (getData->startPoint == i)
//起点为i
{
path[getData->endPoint] = getData->length;
//获得源结点到目的结点的距离
route[getData->endPoint] = getData->startPoint;
//路由信息存储为目的结点的前一个结点
if (minLength > getData->length)
//距离小于当前最小距离
{
minLength = getData->length;
//获得当前最小距离
lastPoint = getData->endPoint;
//获得当前最小距离的终点
}
}
getData = getData->next;
//指向下一个结构体
}
flag[lastPoint] = true;
//标记起点到当前终点的最短路径已求出
for (k = 0; k < maxPoint; k++)
//按点号从小到大遍历所有结点做目的结点
{
getData = head;
//获得链表数据头指针
float tempLength = MAXIMUM;
//当前的最小距离
int tempPoint = -1;
//前一次找出的距离最短的路径的终点
while (getData != NULL)
//遍历链表,更新路由信息和距离数组
{
if ((getData->startPoint == lastPoint) && (getData->endPoint != i) && !flag[getData-
>endPoint])
{//起点为上一次最短路径的终点,终点与起点不同,最短路径未求出
if ((minLength + getData->length) < path[getData->endPoint])
//有更短的路径
{
path[getData->endPoint] = minLength + getData->length;
//获得
源结点到目的结点的距离
route[getData->endPoint] = getData->startPoint;
//路由信息存储为目的结点的前一个结点
}
}
getData = getData->next;
//指向下一个结构体
}
for (j = 0; j < maxPoint; j++)
{//遍历path数组,找出到最短路径尚未找出的终点的距离最小值
if (!flag[j] && tempLength >= path[j] && j!=i)
{//最短路径尚未找出,且距离比当前最小距离更小,起点和终点不同
tempLength = path[j];
//更新最小距离值
tempPoint = j;
//更新当前最短路径的终点
}
}
lastPoint = tempPoint;
//获得当前最小距离的终点
minLength = tempLength;
//获得当前最小距离
flag[lastPoint] = true;
//标记起点到当前终点的最短路径已求出
}
////////////////////下面先指定文件写入结果数据///////////////////////////
for (j = 0; j <= maxPoint; j++)
//从每一个结点出发
{
if (path[j] == MAXIMUM)
//路径不可达,或者终点和起点重叠
{
//向文件写入信息
outPutFile << i << "\t" << j << "\t--\t\t--" << endl;
}
else
{
string strRoute;
//路径信息
int r = route[j];
//第j个点为终点时其上一跳位置
while (r!=i)
//根据路由表反向查找路径信息
{
stringstream ss;
//使用字符串流将int转化为string型
ss << r;
//字符串流写入
strRoute = "->" + ss.str() + strRoute;
//构建路径信息字符串
r = route[r];
//上一跳
}
//向文件写入数据 “起点
终点 距离 路径”
outPutFile << i << "\t" << j << "\t" << path[j] << "\t\t" << i << strRoute << "->" << j << endl;
}
}
}
outPutFile.close();
//关闭文件流
return;
}
相关文章推荐
- SAP凭证类型设计
- CentOS下桥接模式设置静态IP的方法
- 基于xmpp openfire smack开发之openfire介绍和部署[1]
- svn恢复到之前某个版本
- linuxIO刷新机制fsync和fdatasync详解
- cross validation 交叉验证
- TXT转换成PDF的问题
- git cherry-pick. 如何把已经提交的commit, 从一个分支放到另一个分支
- Android 命令行编译、打包生成apk文件
- 40个开源APP项目
- WinForm C# TreeView改变选中节点颜色,失去焦点时选中节点仍突显。
- DIV+CSS两种盒子模型(W3C盒子与IE盒子)
- freemarker中的directive
- [DFS]百度之星初赛第二场 棋盘占领
- 设计模式之建造者模式
- C语言 对输入的一个字符串进行排序
- 读书笔记:逆向思考的艺术
- 如何通过出色的设计让你的简历脱颖而出?
- 一个下载图片的小程序
- tcp有限状态机分析