所有节点最短路径的Johnson实现
2017-05-09 19:03
423 查看
一、数据集形式
其中:6105(节点个数) 7035(边数)
0(id) 1609(起始边) 1622(终边) 57.403187(权重)
二、数据集
数据集下载链接三、实现代码
// Dijkstra.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "time.h" #include <fstream> #include<iostream> #include <stack> #include <queue> #include<algorithm> using namespace std; int nodeNumber; int edgeNumber; #define PATH "E://dataset//MapSet//MinCreateTree//Testnew.txt" //#define PATH "E://dataset//MapSet//MinCreateTree//Ol.txt" //#define PATH "E://dataset//MapSet//MinCreateTree//TGRoad.txt" //#define PATH "E://dataset//MapSet//MinCreateTree//California.txt" class CWeightSort { public: int value; double weight; CWeightSort *before; CWeightSort *next; }; class CTreeNode { public: CTreeNode() {} ~CTreeNode() {} int value; double weight; CTreeNode *next; }; class CTree { public: CTree() { weight = 65535; smallWeigth = NULL; } ~CTree() {} int value; CTreeNode *next; CTree *before; double weight; CWeightSort *smallWeigth; bool state; }; CTree * S; CTree* createTree(char* filename) { CTree *tree; ifstream ReadFile; int temp; ReadFile.open(filename, ios::in);//ios::in 表示以只读的方式读取文件 ReadFile >> nodeNumber;//第一个字符是数组长度 ReadFile >> edgeNumber; tree = new CTree[nodeNumber]; S = new CTree; S->weight = 0; S->value = 0; S->next = NULL; S->before = NULL; CTreeNode *nt; //为树赋初值 for (int i = 0; i < nodeNumber; i++) { nt = new CTreeNode; nt->value = i; nt->weight = 0; nt->next = S->next; S->next = nt; tree[i].next = NULL; tree[i].value = i; tree[i].before = NULL; } while (!ReadFile.eof()) //按空格读取,遇到空白符结束 { nt = new CTreeNode(); //读出的数据新建一个节点 ReadFile >> temp; ReadFile >> temp; ReadFile >> (nt->value); ReadFile >> (nt->weight); nt->next = tree[temp].next; tree[temp].next = nt; } return tree; } //Bellman算法 queue<CTree *> myQ; void Bellman(CTree *t, CTree *tree) { CTreeNode *p = t->next; while (p != NULL) { //链接的节点已经完成,不做任何改变 if (t->weight != 65535 && tree[p->value].weight>t->weight + p->weight) { //cout << tree[p->value].value << " "; tree[p->value].weight = t->weight + p->weight; tree[p->value].before = t; //Bellman(tree, p->value); myQ.push(&tree[p->value]); } p = p->next; } } void Bell(CTree *S,CTree *tree) { myQ.push(S); while (!myQ.empty()) { Bellman(myQ.front(), tree); myQ.pop(); } } double **Johnson; //Dijkstra 算法 class CQueue { //一个保持队形的队列结构 public: CQueue() { que = new CWeightSort(); que->next = NULL; } void Add(CWeightSort *nq) { //将新节点按顺序插入到队列上 CWeightSort *q = que; while (q->next != NULL) { if (nq->weight < q->next->weight) { q->next->before = nq; nq->next = q->next; nq->before = q; q->next = nq; break; } q = q->next; } if (q->next == NULL) { nq->next = q->next; nq->before = q; q->next = nq; } } CWeightSort * del(CWeightSort *nq) { nq->before->next = nq->next; if (nq->next != NULL) nq->next->before = nq->before; return nq; } bool empty() { if (que->next == NULL) return true; return false; } CWeightSort *que; }; void initDijkstra(CTree *tree, int in) { for (int i = 0; i < nodeNumber; i++) { tree[i].state=true; tree[i].before = NULL; //delete tree[i].smallWeigth; tree[i].smallWeigth = NULL; } tree[in].smallWeigth = new CWeigh 4000 tSort; tree[in].smallWeigth->weight = 0; } CTree* Dijkstra(CTree *tree,int in) { initDijkstra(tree, in); CQueue myQue; CWeightSort *myi = new CWeightSort; myi->value = in; myi->before = NULL; myQue.Add(myi); CWeightSort *nt = NULL; while (!myQue.empty()) { nt = myQue.del(myQue.que->next); Johnson[in][nt->value] = nt->weight + tree[nt->value].weight - tree[in].weight;//如果在这里设置数组可以得到所有值,但占用空间太大 //cout << nt->value << "(" << nt->weight << ")" << " "; //标记这个节点为已经访问状态 tree[nt->value].state = false; CTreeNode *p = tree[nt->value].next; while (p != NULL) { //链接的节点已经完成,不做任何改变 if (tree[p->value].state) { //链接的节点,没有更小的值 if (tree[p->value].smallWeigth == NULL) { CWeightSort *node = new CWeightSort; node->value = p->value; node->weight = tree[nt->value].smallWeigth->weight + p->weight; tree[p->value].smallWeigth = node; tree[p->value].before = &tree[nt->value]; myQue.Add(node); } //链接的节点,存在更小的值 else if (tree[p->value].smallWeigth->weight>tree[nt->value].smallWeigth->weight + p->weight) { CWeightSort *node = myQue.del(tree[p->value].smallWeigth); node->value = p->value; node->weight = tree[nt->value].smallWeigth->weight + p->weight; tree[p->value].smallWeigth = node; tree[p->value].before = &tree[nt->value]; myQue.Add(node); } } p = p->next; } } return &tree[nt->value]; } int main() { //构建图 CTree *tree = createTree(PATH); double useTime; clock_t start, finish; start = clock(); //修改图中的weight Bell(S,tree); //对图边的权重进行改变 for (int i = 0; i < nodeNumber; i++) { CTreeNode *p = tree[i].next; while (p!=NULL) { p->weight = p->weight + tree[0].weight - tree[p->value].weight; p = p->next; } } //对于每个节点进行Dijkstra Johnson = new double *[nodeNumber]; for (int i = 0; i < nodeNumber ; i++) { Johnson[i] = new double[nodeNumber]; memset(Johnson[i], 65535, sizeof(double)*nodeNumber); } for (int i = 0; i < nodeNumber; i++) { CTree *q = Dijkstra(tree, i); } finish = clock(); useTime = (double)(finish - start) / CLOCKS_PER_SEC * 1000; printf("%f 毫秒\n", useTime); system("pause"); return 0; }
相关文章推荐
- johnson方法求所有节点对最短路径
- 利用邻接表求解所有节点的最短路径 java实现 可运行
- 图两点间的最短路径,所有路径算法C语言实现
- 算法导论第二十五章-所有结点对的最短路径问题-Cpp代码实现
- 算法导论 所有节点对的最短路径问题 矩阵法
- 算法导论 所有节点对的最短路径
- MPI实现有向图所有点间最短路径
- 利用Dijkstra算法实现记录每个结点的所有最短路径
- 图的所有节点对之间的最短路径—Floyd算法(C++)
- 无向图中节点的迭代得到从起始节点到结束节点之间的所有路径,并从中得到最短路径的节点
- Floyd-Warshall算法求解所有结点对的最短路径问题Java实现
- 所有节点对的最短路径
- 算法导论笔记:25所有节点对的最短路径问题
- 简单实现dijstra算法和floyd算法并打印所有最短路径
- Floyd-Warshall(弗洛伊德)算法求所有节点对的最短路径问题
- 所有顶点间最短路径FloydWarshall算法实现文件C++
- 所有节点对最短路径-Floyd-Warshall算法
- hdu 1599 find the mincost route(无向图的最小环:求从一个点遍历所有节点以后回到原点的最短路径)
- Floyed多源节点--最短路径C++实现与实现打印路径
- 图两点间的最短路径,所有路径算法C语言实现