回 帖 发 新 帖 刷新版面

主题:大家帮帮我这位新手吧,有没有Dijkstra算法寻找最短路径的源代码呀

一个新手遇到了困难,想请大家帮个忙!谢谢啦!

回复列表 (共5个回复)

沙发

源码多种多样,关键你要知道原理。
我以前写的,包括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

板凳

/*********************** 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 楼

/********************** 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 楼

上面三个文件。
再加上一个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 楼

同求

我来回复

您尚未登录,请登录后再回复。点此登录或注册