主题:大家帮帮我这位新手吧,有没有Dijkstra算法寻找最短路径的源代码呀
lanseqicheng
[专家分:0] 发布于 2006-07-05 16:42:00
一个新手遇到了困难,想请大家帮个忙!谢谢啦!
回复列表 (共5个回复)
沙发
Vaan [专家分:120] 发布于 2006-07-05 16:47:00
源码多种多样,关键你要知道原理。
我以前写的,包括Prim、kruskal和Dijkstra的。
/*************** graph.h *********************/
#ifndef _Graph_Vaan
#define _Graph_Vaan
#include <iostream>
#include <fstream>
using namespace std;
#define MaxValue 0x7FFFFFFF
class edge{
public:
int fromvex;
int weight;
int endvex;
edge & operator = (edge& e);
};
// DijItem & Queue is exist for Dijktra
class DijItem{
public:
int iNode;
int iPrev;
int iDist;
DijItem * next;
};
class Queue{
public:
Queue(){
this->root = NULL;
this->length = 0;
}
~Queue(){
DijItem * temp;
while(this ->root){
temp = this ->root;
this ->root = this ->root ->next;
delete temp;
}
}
void enQueue(int, int, int);
void dequeue(int&, int&, int&);
int getLength(){
return this->length;
}
private:
DijItem * root;
int length;
};
// Graph
class Graph{
public:
Graph(){
ifstream fin;
fin.open("data.txt");
int i, m;
fin >> m;
this ->MaxVertextNum = m;
this ->adjmatrix = new int[m * m];
for(i = 0; i < m*m; i ++){
fin >> adjmatrix[i];
if(adjmatrix[i] == -1) adjmatrix[i] = MaxValue;
}
}
~Graph(){
delete [] adjmatrix;
}
int Prim(edge *&);
int Kruskal(edge *&);
int Dijkstra(int, int *&, int *&);
void printGraph();
private:
int MaxVertextNum;
int* adjmatrix;
};
#endif
板凳
Vaan [专家分:120] 发布于 2006-07-05 16:51:00
/*********************** graph.cpp ******************/
#include "graph.h"
// edge
edge & edge::operator =(edge &e){
this ->endvex = e.endvex;
this ->fromvex = e.fromvex;
this ->weight = e.weight;
return *this;
}
// Queue
void Queue::enQueue(int iNode, int iDist, int iPrev){
DijItem * temp = new DijItem();
temp ->iNode = iNode;
temp ->iDist = iDist;
temp ->iPrev = iPrev;
temp ->next = NULL;
if(this ->length){
DijItem * p = this ->root;
while(p ->next)
p = p ->next;
p ->next = temp;
}
else
this ->root = temp;
this ->length ++;
}
void Queue::dequeue(int& iNode, int& iDist, int& iPrev){
if(!this ->length)
exit(0);
DijItem * temp = this->root;
iNode = temp ->iNode;
iDist = temp ->iDist;
iPrev = temp ->iPrev;
this ->root = this ->root ->next;
this ->length --;
delete temp;
}
// Graph
void Graph::printGraph(){
cout << MaxVertextNum << " * " << MaxVertextNum << " Graph" << endl;
for(int i = 0; i < MaxVertextNum*MaxVertextNum; i ++){
cout << ((adjmatrix[i] == MaxValue) ? -1 : adjmatrix[i]) << ((i + 1)%MaxVertextNum?' ':'\n');
}
cout << endl;
}
int Graph::Prim(edge *& CT){
int i, j, k, min, t, m, w;
CT = new edge[MaxVertextNum - 1];
for(i = 0; i < MaxVertextNum - 1; i ++){
CT[i].fromvex = 0;
CT[i].endvex = i + 1;
CT[i].weight = adjmatrix[i + 1];
}
for(k = 1; k < MaxVertextNum - 1; k ++){
min = MaxValue;
m = k - 1;
for(j = k - 1; j < MaxVertextNum - 1; j ++)
if(CT[j].weight < min){
min = CT[j].weight;
m = j;
}
edge temp = CT[k - 1];
CT[k - 1] = CT[m];
CT[m] = temp;
j = CT[k - 1].endvex;
for(i = k; i < MaxVertextNum - 1; i ++){
t = CT[i].endvex;
if(t != j){
w = adjmatrix[j * MaxVertextNum + t];
if(w < CT[i].weight){
CT[i].weight = w;
CT[i].fromvex = j;
}
}
}
}
return MaxVertextNum - 1;
}
int Graph::Kruskal(edge *& C){
C = new edge[MaxVertextNum - 1];
int i, j;
bool *s = new bool[MaxVertextNum * MaxVertextNum];
int n = MaxVertextNum;
int k = 1, d = 0, m1 = 0, m2 = 0;
// Get the sorted edge;
edge * GE = new edge[MaxVertextNum * (MaxVertextNum - 1) / 2];
int edgenum = 0;
for(i = 0; i < MaxVertextNum; i ++){
for(j = i + 1; j < MaxVertextNum; j ++){
if(adjmatrix[i * MaxVertextNum + j] != MaxValue){
GE[edgenum].fromvex = i;
GE[edgenum].endvex = j;
GE[edgenum ++].weight = adjmatrix[i * MaxVertextNum + j];
}
}
}
for(i = 0; i < edgenum - 1; i ++){
for(j = i + 1; j < edgenum; j ++){
if(GE[i].weight > GE[j].weight){
edge temp = GE[i];
GE[i] = GE[j];
GE[j] = temp;
}
}
}
// Vertext Sets;
for(i = 0; i < n; i ++){
for(j = 0; j < n; j ++){
s[i * MaxVertextNum + j] = (i == j);
}
}
// Get the Mini edges
while(k < n && d < edgenum){
for(i = 0; i < n; i ++){
if(s[i * MaxVertextNum + GE[d].fromvex])
m1 = i;
if(s[i * MaxVertextNum + GE[d].endvex])
m2 = i;
}
if(m1 != m2){
C[k - 1] = GE[d];
k ++;
for(j = 0; j < n; j ++){
s[m1 * MaxVertextNum + j] = s[m1 * MaxVertextNum + j] || s[m2 * MaxVertextNum + j];
s[m2 * MaxVertextNum + j] = false;
}
}
d ++;
}
delete [] GE;
for(i = 0; i < MaxVertextNum; i ++){
if(s[i * MaxVertextNum]){
for(j = 1; j < MaxVertextNum; j ++){
if(!s[i * MaxVertextNum + j])
break;
}
if(j != MaxVertextNum){
delete [] s;
return -1;
}
else{
delete [] s;
return MaxVertextNum - 1;
}
}
}
delete [] s;
return -1;
}
int Graph::Dijkstra(int sp, int *& len, int *& lp){
if(sp < 0 || sp >= MaxVertextNum)
exit(0);
len = new int[MaxVertextNum];
lp = new int[MaxVertextNum];
Queue q;
int iNode, iPrev, iCost, iDist;
int i;
for(i = 0; i < MaxVertextNum; i ++){
len[i] = MaxValue;
lp[i] = MaxValue;
}
len[sp] = 0;
lp[sp] = MaxValue;
q.enQueue(sp, 0, MaxValue);
while(q.getLength()){
q.dequeue(iNode, iDist, iPrev);
for(i = 0; i < MaxVertextNum; i ++){
if((iCost = this ->adjmatrix[iNode * MaxVertextNum + i]) != MaxValue){
if(len[i] == MaxValue || len[i] > iDist + iCost){
len[i] = iDist + iCost;
lp[i] = iNode;
q.enQueue(i, len[i], lp[i]);
}
}
}
}
return MaxVertextNum;
}
3 楼
Vaan [专家分:120] 发布于 2006-07-05 16:52:00
/********************** use.cpp *********************/
#include "graph.h"
void printPath(int * lp, int cp){
if(lp[cp] != MaxValue)
printPath(lp, lp[cp]);
cout << cp + 1 << ' ';
}
int main(void){
Graph g;
g.printGraph();
/*
edge * edges_prim;
edge * edges_kruskal;
int i;
int n = g.Prim(edges_prim);
cout << "Prim Mini edges : " << endl;
for(i = 0; i < n; i ++)
cout << '(' << edges_prim[i].fromvex << ',' << edges_prim[i].endvex << ')' <<
" Weight : " << edges_prim[i].weight << endl;
n = g.Kruskal(edges_kruskal);
cout << "Kruskal Mini edges : " << endl;
for(i = 0; i < n; i ++)
cout << '(' << edges_kruskal[i].fromvex << ',' << edges_kruskal[i].endvex << ')' <<
" Weight : " << edges_kruskal[i].weight << endl;
*/
int spoint;
int * length;
int * last_point;
cout << "Enter this start point : ";
cin >> spoint;
int n = g.Dijkstra(spoint - 1, length, last_point);
for(int i = 0; i < n; i ++){
cout << "Point:" << i + 1 << "; Lenght:" << length[i] << "; Path:";
printPath(last_point, i);
cout << endl;
}
return 0;
}
4 楼
Vaan [专家分:120] 发布于 2006-07-05 16:54:00
上面三个文件。
再加上一个data.txt来输入图的边结构。
第一行是边长n,以后共n行,每行n个数据。
/********** data.txt **************/
6
0 5 7 -1 -1 2
5 0 12 3 8 4
7 12 0 6 20 3
-1 3 6 0 15 8
-1 8 20 15 0 7
2 4 3 8 7 0
5 楼
雨523 [专家分:200] 发布于 2006-07-29 16:59:00
同求
我来回复