您的位置:首页 > 其它

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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: