QT_地图导航 源码下载

QT_地图导航 源码下载

https://github.com/douzujun/MyMapView

主要算法讲解:

1. 计算最短路径(dijkstra算法)

Step1:

  (1)找到最短路径已经确定的顶点,从它已经确定的顶点,从它除法更新相邻顶点的最短距离。

  (2)此后不需要再关心1中的“最短距离已经确定的顶点”。

  (3)在(1)和(2)中提到的“最短距离已经确定的顶点”要求解的关键。在最开始时,只有起点的最短距离是确定的。而在尚未使用过的顶点中,距离d[i]最小的顶点就是最短距离已经确定的顶点。这是因为由于不存在负边,所以d[i]不会在更新中变小。

定义几个方便算法描述的变量:

  int cost[MAX_V][MAX_V]; //cost[u][v]表示表e=(u,v)的权值(不存在这条边时设为INF)

  int d[MAX_V];                 //顶点s出发的最短路径

  bool used[MAX_V];          //已经使用的图

Step2:

  (1)如果,我们需要输出最短路的路径。注,在求解最短路径时,满足d[j] = d[k] + cost[k][j]顶点k(d[j]是表示从起点开始到j的最短路径距离,cost[k][j]是表示k到j的距离),就是最短路上的顶点j的前驱结点,因此通过不断寻找前驱结点就可以恢复最短路。时间复杂度是O(E)

  (2)如果,我们用prev[j]来记录最短路上的顶点j的前驱,那么就可以在O(|V|)时间内完成最短路的恢复。在d[j]=d[k]+cost[k][j]更新时,修改prev[j]=k, 这样就可以求得prev数组。在计算从起点s出发到j的最短路时,通过prev[j]就可以知道顶点j的前驱,因此不断把j替换成prev[j]直到j = s为止即可。代码如下:

1. 首先要对图进行初始化,才能正常计算最短路径

 1 MainWindow::DijkstraFindPath::DijkstraFindPath()
 2 {
 3     mgraph.vexnum = 40;                        //初始化点数目
 4        for (int i = 0; i < mgraph.vexnum; i++) //初始化点编号
 5            mgraph.vexs.push_back (i);
 6        mgraph.arcnum = 98;                     //边数
 7        for (int i = 0; i < mgraph.vexnum; i++) {
 8            for (int j = 0; j < mgraph.vexnum; j++) {
 9                if (i == j)
10                    mgraph.arcs[i][j].adj = 0;
11                else
12                    mgraph.arcs[i][j].adj = INF;
13            }
14        }
15 }

2. 设置图的景点之间的权值。

 1 void MainWindow::DijkstraFindPath::CreateGraph ()
 2 {
 3         mgraph.arcs[0][1].adj = mgraph.arcs[1][0].adj = 45;    //6 - 5
 4         mgraph.arcs[0][6].adj = mgraph.arcs[6][0].adj = 165;   //6 - 10
 5         mgraph.arcs[1][2].adj = mgraph.arcs[2][1].adj = 45;    //5 - 4
 6         mgraph.arcs[2][3].adj = mgraph.arcs[3][2].adj = 45;    //4 - 3
 7         mgraph.arcs[3][4].adj = mgraph.arcs[4][3].adj = 45;    //3 - 2
 8         mgraph.arcs[3][15].adj = mgraph.arcs[15][3].adj = 24;  //3 - 22
 9         mgraph.arcs[4][5].adj = mgraph.arcs[5][4].adj = 45;    //2 - 1
10         mgraph.arcs[13][15].adj = mgraph.arcs[15][13].adj = 85;//23 - 22
11         mgraph.arcs[0][13].adj = mgraph.arcs[13][0].adj = 55;  //6 - 23
12         mgraph.arcs[13][2].adj = mgraph.arcs[2][13].adj = 50;  //23 - 4
13         mgraph.arcs[5][11].adj = mgraph.arcs[11][5].adj = 65;  //1 - 一食堂
14         mgraph.arcs[11][12].adj = mgraph.arcs[12][11].adj = 10;//一食堂-操场
15         mgraph.arcs[11][27].adj = mgraph.arcs[27][11].adj = 85;//一食堂-祁通1
16         mgraph.arcs[27][28].adj = mgraph.arcs[28][27].adj = 85;//祁通1-祁通2(路口)
17         mgraph.arcs[5][29].adj = mgraph.arcs[29][5].adj = 87;  //一食堂-岔路口
18         mgraph.arcs[29][11].adj = mgraph.arcs[11][29].adj = 50;//一食堂到岔路(通向7号楼的)
19         mgraph.arcs[29][30].adj = mgraph.arcs[30][29].adj = 32;//岔路-祁通大道
20         mgraph.arcs[30][10].adj = mgraph.arcs[10][30].adj = 90;//祁通大道-图书馆
21         mgraph.arcs[30][28].adj = mgraph.arcs[28][30].adj = 80;//祁通大道-祁通2
22         mgraph.arcs[28][26].adj = mgraph.arcs[26][28].adj = 15;//祁通2-方肇周
23         mgraph.arcs[25][27].adj = mgraph.arcs[27][25].adj = 273;//西大门-祁通1
24         mgraph.arcs[27][28].adj = mgraph.arcs[28][27].adj = 84; //祁通1-祁通2
25         mgraph.arcs[5][12].adj = mgraph.arcs[12][5].adj = 70;   //1 - 操场
26         mgraph.arcs[6][7].adj = mgraph.arcs[7][6].adj = 45;    //10 - 9
27         mgraph.arcs[7][8].adj = mgraph.arcs[8][7].adj = 45;    //9 - 8
28         mgraph.arcs[8][9].adj = mgraph.arcs[9][8].adj = 45;    //8 - 7
29         mgraph.arcs[9][10].adj = mgraph.arcs[10][9].adj = 150; //7 - 图书馆
30         mgraph.arcs[6][14].adj = mgraph.arcs[14][6].adj = 140; //10 - 13
31         mgraph.arcs[14][16].adj = mgraph.arcs[16][14].adj = 39;//13 - 12
32         mgraph.arcs[14][17].adj = mgraph.arcs[17][14].adj = 39;//13 - 16
33         mgraph.arcs[16][18].adj = mgraph.arcs[18][16].adj = 39;//12 - 15
34         mgraph.arcs[17][18].adj = mgraph.arcs[18][17].adj = 39;//16 - 15
35         mgraph.arcs[18][19].adj = mgraph.arcs[19][18].adj = 20;//15 - 14
36         mgraph.arcs[17][20].adj = mgraph.arcs[20][17].adj = 137;//16 - 19
37         mgraph.arcs[20][21].adj = mgraph.arcs[21][20].adj = 39; //19 - 18
38         mgraph.arcs[21][22].adj = mgraph.arcs[22][21].adj = 39; //18 - 17
39         mgraph.arcs[19][22].adj = mgraph.arcs[22][19].adj = 130;//14 - 17
40         mgraph.arcs[22][23].adj = mgraph.arcs[23][22].adj = 53; //17 - 二超
41         mgraph.arcs[23][24].adj = mgraph.arcs[24][23].adj = 5;  //二超 - 二食堂
42 
43         //以下处理细节—这是景点之间的一小段路之间的权值,因为用界面绘制路线,会//出现弧状的路线,所以需要定额外的坐标
44         mgraph.arcs[30][31].adj = mgraph.arcs[31][30].adj = 30; //祁通大道-祁通大道2
45         mgraph.arcs[31][32].adj = mgraph.arcs[32][31].adj = 10; //祁通大道2-祁通大道3
46         mgraph.arcs[32][10].adj = mgraph.arcs[10][32].adj = 20; //祁通大道3-图书馆
47         mgraph.arcs[10][33].adj = mgraph.arcs[33][10].adj = 80; //图书馆-祁通大道4
48         mgraph.arcs[33][34].adj = mgraph.arcs[34][33].adj = 45; //祁通4-祁通5
49         mgraph.arcs[34][24].adj = mgraph.arcs[24][34].adj = 45; //祁通5-二食堂
50         mgraph.arcs[34][23].adj = mgraph.arcs[23][34].adj = 45; //祁通5-二超
51         mgraph.arcs[33][35].adj = mgraph.arcs[35][33].adj = 30; //祁通4-通向14号楼的小道
52         mgraph.arcs[35][19].adj = mgraph.arcs[19][35].adj = 10; //小道-14号楼
53         mgraph.arcs[35][36].adj = mgraph.arcs[36][35].adj = 10; //小道14-小道15
54         mgraph.arcs[36][18].adj = mgraph.arcs[18][36].adj = 10; //小道15-15
55         mgraph.arcs[36][16].adj = mgraph.arcs[16][36].adj = 5;  //小道15-12
56         mgraph.arcs[37][29].adj = mgraph.arcs[29][37].adj = 40; //岔路-岔路2
57         mgraph.arcs[37][9].adj = mgraph.arcs[9][37].adj = 45;   //岔路2-7
58 
60 }

3. 计算最短路径,并对输出路径进行初始化工作。

 1 void MainWindow::DijkstraFindPath::dijkstra (int startPos)
 2 {
 3     for (int i = 0; i < mgraph.vexnum; i++) d[i] = INF;
 4     for (int i = 0; i < mgraph.vexnum; i++) used[i] = false;
 5     for (int i = 0; i < mgraph.vexnum; i++) prev[i] = -1;
 6     d[startPos] = 0;
 7 
 8     while (true) {
 9         int v = -1;
10         for (int u = 0; u < mgraph.vexnum; u++) {
11             if (!used[u] && (v == -1 || d[u] < d[v])) v = u;
12         }
13 
14         if (v == -1) break;
15         used[v] = true;
16 
17         for (int u = 0; u < mgraph.vexnum; u++) {
18             if (d[u] > d[v] + mgraph.arcs[v][u].adj) {
19                 d[u] = d[v] + mgraph.arcs[v][u].adj;
20                 prev[u] = v;
21             }
22         }
23     }
24 }

4.存储起点到终点之间的路径。

 1 QVector<int> MainWindow::DijkstraFindPath::get_Path (int endPos)
 2 {
 3     QVector<int> path;
 4 //保存景点之间的最短路径上的全部景点
 5     for ( ; endPos != -1; endPos = prev[endPos]) {
 6         path.push_back (endPos);
 7     }
 8 //由于路径是从终点向起点保存的,还需要将路径逆置。
 9     std::reverse(path.begin (), path.end ());
10     return path;
11 }

 

全部代码: 

1 首先要对图进行初始化,才能正常计算最短路径

  1 /**
  2  * 主要功能:
  3  * 1. 绘制输入起点,终点最短路径
  4  * 2. 双击地点, 查看景点信息
  5  * 3. 修改景点图片
  6  * 4. 打开测试地图,查看地图坐标,可缩放地图.
  7  **/
  8 #ifndef MAINWINDOW_H
  9 #define MAINWINDOW_H
 10 
 11 #include <QMainWindow>
 12 #include "mapwidget.h"
 13 #include <QToolButton>
 14 #include <QGraphicsLineItem>
 15 #include <QGraphicsScene>
 16 #include <QGraphicsView>
 17 #include <QLabel>
 18 #include <QComboBox>
 19 #include <QTextEdit>
 20 #include <QVector>
 21 #include <QMouseEvent>
 22 #include <QDialog>
 23 #include <QPixmap>
 24 #include <QGridLayout>
 25 #include <QLineEdit>
 26 #include <QFileDialog>
 27 #include <QHBoxLayout>
 28 
 29 class MainWindow : public QMainWindow
 30 {
 31     Q_OBJECT
 32 public:
 33     MainWindow(QWidget *parent = 0);
 34     ~MainWindow();
 35     void createToolBar();
 36     void createAction();
 37     void setStart(int X, int Y);
 38     void setEnd(int X, int Y);
 39     void setNextPos (int index);
 40     void initScene();
 41 public slots:
 42     void setStartStation();
 43     void setEndStation();
 44     void FindPath();
 45     void Clear();
 46     void Revise();
 47     void callOtherMap();
 48     void ShowDialog();
 49 private:
 50     MapWidget *mapWidget;
 51     QLabel *startLabel;
 52     QLabel *endLabel;
 53     QComboBox *startComboBox;
 54     QComboBox *endComboBox;
 55     QComboBox *reviseComboBox;
 56 
 57     QAction *findPathAction;
 58     QAction *clearAction;
 59     QAction *reviseAction;
 60     QAction *callMap;
 61 
 62     QGraphicsScene *scene;
 63     QGraphicsView *view;
 64 
 65     int startX, startY, endX, endY;
 66     QVector<int> nextPath;
 67 
 68     /*
 69      * 图的实现,和最短路径算法声明
 70      */
 71     struct ArcCell{    //弧信息
 72         int adj;       //对无权图有1,0表示是否相邻,对带权图,则为权值类型
 73     //    string info; //该弧的相关信息
 74     };
 75 
 76 
 77     //内部类
 78     static const int MAX_VERTEX_NUM = 50;
 79     static const int INF = 999999;
 80 
 81     struct MGraph{
 82         QVector<int> vexs;                                    //顶点集合
 83         //临接矩阵
 84         ArcCell arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
 85         int vexnum;                                           //顶点数
 86         int arcnum;                                           //边数
 87     //    int kind;                                             //图的类型
 88     };
 89 
 90     class DijkstraFindPath
 91     {
 92     public:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值