最短路径寻优
(以下关于Dijstra的说明,是借用算法与数据结构的发帖说明、侵权即删)原帖链接最短路径寻优如上图所示、如何寻求从 A 出发到 G 点的最短路径呢?Dijstra算法就是要求出这个最短的路径;
让我们来演示一下迪杰斯特拉的详细过程: 第1步,创建距离表。表中的Key是顶点名称,Value是从起点A到对应顶点的已知最短距离。 但是,一开始我们并不知道A到其他顶点的最短距离是多少,Value默认是无限大:
第2步,遍历起点A,找到起点A的邻接顶点B和C。从A到B的距离是5,从A到C的距离是2。把这一信息刷新到距离表当中:
第3步,从距离表中找到从A出发距离最短的点,也就是顶点C。第4步,遍历顶点C,找到顶点C的邻接顶点D和F(A已经遍历过,不需要考虑!!!!!!!!!!代码编写中就需要注意这一点)。从C到D的距离是6,所以A到D的距离是2+6=8;从C到F的距离是8,所以从A到F的距离是2+8=10。把这一信息刷新到表中:
接下来重复第3步、第4步所做的操作:第5步,也就是第3步的重复,从距离表中找到从A出发距离最短的点(C已经遍历过,不需要考虑),也就是顶点B。第6步,也就是第4步的重复,遍历顶点B,找到顶点B的邻接顶点D和E(A已经遍历过,不需要考虑)。从B到D的距离是1,所以A到D的距离是5+1=6,小于距离表中的8;从B到E的距离是6,所以从A到E的距离是5+6=11。把这一信息刷新到表中:
(在第6步,A到D的距离从8刷新到6,可以看出距离表所发挥的作用。距离表通过迭代刷新,用新路径长度取代旧路径长度,最终可以得到从起点到其他顶点的最短距离)第7步,从距离表中找到从A出发距离最短的点(B和C不用考虑),也就是顶点D。第8步,遍历顶点D,找到顶点D的邻接顶点E和F。从D到E的距离是1,所以A到E的距离是6+1=7,小于距离表中的11;从D到F的距离是2,所以从A到F的距离是6+2=8,小于距离表中的10。把这一信息刷新到表中:
第9步,从距离表中找到从A出发距离最短的点,也就是顶点E。第10步,遍历顶点E,找到顶点E的邻接顶点G。从E到G的距离是7,所以A到G的距离是7+7=14。把这一信息刷新到表中:
第11步,从距离表中找到从A出发距离最短的点,也就是顶点F。第10步,遍历顶点F,找到顶点F的邻接顶点G。从F到G的距离是3,所以A到G的距离是8+3=11,小于距离表中的14。把这一信息刷新到表中:
就这样,除终点以外的全部顶点都已经遍历完毕,距离表中存储的是从起点A到所有顶点的最短距离。显然,从A到G的最短距离是11。(路径:A-B-D-F-G)
下面附上算法的C++实现
- // dijstra.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
- //
- //利用状态机来描述 dijstra算法
- //寻求最短路径
- #include "pch.h"
- #include <iostream>
- using namespace std;
- typedef struct {
- char nextPointName;
- int distance;
- }NEXT_POINT;
- typedef struct {
- int curVaule;
- int expandFlag;
- char name;
- int linkNum;
- NEXT_POINT nextPoint[5];
- char route[10] = {'A'};
- }POINT;
- POINT A = { 1000,0,'A' ,2,'B',5,'C',2};
- POINT B = { 1000,0,'B' ,2,'D',1,'E',6};
- POINT C = { 1000,0,'C' ,2,'D',6,'F',8};
- POINT D = { 1000,0,'D' ,2,'E',1,'F',2};
- POINT E = { 1000,0,'E' ,1,'G',7};
- POINT F = { 1000,0,'F' ,1,'G',3};
- POINT G = { 1000,0,'G' };
- void Dijkstra(POINT* startPoint, POINT* endPoint, POINT* piontArray, int pointNum);
- int main()
- {
- POINT array[10] = { A,B,C,D,E,F,G };
- Dijkstra(&A,&G,array,7);
-
- cout << " 最短路径为 "<<G.route <<endl<<" 最短路径长度为 "<< G.curVaule << endl;
- system("pause");
- }
- void Dijkstra(POINT* startPoint, POINT* endPoint, POINT* piontArray,int pointNum) {
-
- POINT unexpandPoint[20] = {0};
-
- int leftNum = pointNum;
- POINT expandPoint=*(startPoint);
- int temp = 0;
- for (int i = 0; i < pointNum; ++i) {
- unexpandPoint[i] = piontArray[i];
- }
- unexpandPoint[0].curVaule = 0;
- while (1) {
- expandPoint = unexpandPoint[0];
- for (int i = 0; i < leftNum; ++i) {
- if (expandPoint.curVaule > unexpandPoint[i].curVaule) {
- expandPoint = unexpandPoint[i];
- temp = i;
- }
- }
- if (expandPoint.name == endPoint->name) {
- *(endPoint) = expandPoint;
- break;
- }
- for (int i = 0; i < leftNum; ++i) {
- if (i > temp) {
- unexpandPoint[i - 1] = unexpandPoint[i];
- }
- }
- temp = 0;
- leftNum--;
- for (int i = 0; i < expandPoint.linkNum; ++i) {
- for (int j = 0; j < leftNum; ++j) {
- if (expandPoint.nextPoint[i].nextPointName == unexpandPoint[j].name) {
- if (unexpandPoint[j].curVaule > expandPoint.nextPoint[i].distance + expandPoint.curVaule) {
- unexpandPoint[j].curVaule = expandPoint.nextPoint[i].distance+ expandPoint.curVaule;
- }
- if (unexpandPoint[j].curVaule > 1000) {
- unexpandPoint[j].curVaule -= 1000;
-
- }
- //路径更新
- for (int k = 0; k < 10; ++k) {
- unexpandPoint[j].route[k] = 0;
- }
- for (int k = 0; k < 10; ++k) {
- if (expandPoint.route[k] != 0) {
- unexpandPoint[j].route[k] = expandPoint.route[k];
- }
- else {
- unexpandPoint[j].route[k] = unexpandPoint[j].name;
- break;
- }
- }
- }
- }
- }
- }
- }
- #if 0
- ##网上查找到的关于 dajstra 算法的较精简的代码例程
- #include<iostream>
- #include<cstring>
- #define INF 10000000
- using namespace std;
- int temp[2005][2005], dis[1005];
- void dijkstra(int n)
- {
- int i, min, flag, j, vis[2005] = { 0 };
- for (i = 1; i <= n; i++) dis[i] = temp[1][i];
- for (i = 1; i < n; i++)
- {
- min = INF;
- flag = 0;
- for (j = 2; j <= n; j++)
- if (min > dis[j] && !vis[j])
- {
- min = dis[j];
- flag = j;
- }
- vis[flag] = 1;
- for (j = 2; j <= n; j++)
- {
- if (dis[j] > min + temp[flag][j] && !vis[j])
- dis[j] = min + temp[flag][j];
- }
- }
- }
- int main()
- {
- int t, i, n, k, m, diss;
- while (cin >> t >> n)
- {
- //memset(temp,INF,sizeof(temp));
- for (int i = 1; i <= 2000; i++) temp[i][i] = 0;
- for (int i = 1; i <= 2000; i++)
- for (int j = 1; j <= 2000; j++)
- temp[i][j] = INF;
- for (int i = 1; i <= t; i++)
- {
- cin >> k >> m >> diss;
- if (diss < temp[k][m])
- {
- temp[k][m] = diss;//双向导通
- temp[m][k] = diss;
- }
- }
- dijkstra(n);
- //for(int i=1;i<=t;i++) cout<<dis[i]<<endl;
- cout << dis[n] << endl;
- }
- return 0;
- }
- #endif
- typedef struct {
- float x[2]; /* state: [0]-angle [1]-diffrence of angle, 2x1 */
- float A[2][2]; /* X(n)=A*X(n-1)+U(n),U(n)~N(0,q), 2x2 */
- float H[2][2]; /* Z(n)=H*X(n)+W(n),W(n)~N(0,r), 1x2 */
- float q[2]; /* process(predict) noise convariance,2x1 [q0,0; 0,q1] */
- float r[2][2]; /* measure noise convariance */
- float p[2][2]; /* estimated error convariance,2x2 [p0 p1; p2 p3] */
- float gain[2][2]; /* 2x1 */
- float B[2];
- } kalman2_state;
- //z轴kalman滤波初始化,初始化时用
- // kalman2_init(&BaroAlt_klm);
- //输入气压计高度,速度和惯性坐标下的加速度---------输出高度和速度
- // kalman2_filter(&BaroAlt_klm, BaroAltoo, 0, az_c);
- void kalman2_init(kalman2_state *state)//, float *init_x, float (*init_p)[2]//×îºóÖ»Ðèµ÷ÊÔq[0],q[1];
- {
- // state->x[0] = init_x[0];
- // state->x[1] = init_x[1];
- // state->p[0][0] = init_p[0][0];
- // state->p[0][1] = init_p[0][1];
- // state->p[1][0] = init_p[1][0];
- // state->p[1][1] = init_p[1][1];
- state->x[0] = 0;
- state->x[1] = 0;
- state->p[0][0] = 1;
- state->p[0][1] = 0;
- state->p[1][0] = 0;
- state->p[1][1] = 1;
- // state->A = {{1, 0.1}, {0, 1}};
- state->A[0][0] = 1;
- state->A[0][1] = 0.01;//1;//t¿É±ä Á½¸öÎïÀíʱ¿ÌµÄ²î2ms PID_PIT.I*0.27;//0.0027
- state->A[1][0] = 0;
- state->A[1][1] = 1;
- // state->H = {1,0};
- state->H[0][0] = 1;
- state->H[0][1] = 0;//1
- state->H[1][0] = 0;
- state->H[1][1] = 0;
- // state->q = {{10e-6,0}, {0,10e-6}}; /* measure noise convariance */
- state->q[0] = 5 * 10e-8;//5;//0.0001;//10e-7;//10e-7;
- state->q[1] = 5 * 10e-8;//10e-6;//0.5;//0.0035;//5*10e-7;
- state->r[0][0] = 1 * 10e-7;//10e-4;//52.4586;//0.1;//10e-3;//10e-7; /* estimated error convariance */PID_ROL.D*
- state->r[0][1] = 0;
- state->r[1][0] = 0;
- state->r[1][1] = 4 * 10e-4;
- // state->B
- state->B[0] = state->A[0][1] * state->A[0][1] / 2.0;
- state->B[1] = state->A[0][1];
- }
- float kalman2_filter(kalman2_state *state, float x_weiyi, float x_speed, float a)//£¨¶þά¿¨¶ûÂüÂ˲¨£©Ö»±äÒ»¸ö£¬Ðè¸Ä½øÎ»ÒÆ¡¢ËÙ¶È,ÕæÕýµÄ¼ÓËÙ¶È£¨Ð޸ĺó£©
- {
- float temp0 = 0.0f;
- float temp1 = 0.0f;
- float temp0_0 = 0.0f;
- float temp0_1 = 0.0f;
- float temp1_0 = 0.0f;
- float temp1_1 = 0.0f;
- float temp00 = 0.0f;
- float temp01 = 0.0f;
- float temp10 = 0.0f;
- float temp11 = 0.0f;
- /* Step1: Predict X(k+1)= A*X(k) +B*U(k)*/
- state->x[0] = state->A[0][0] * state->x[0] + state->A[0][1] * state->x[1] + state->B[0] * a;//ת»»Íê×ø±ê·½¿ÉʹÓÃ
- state->x[1] = state->A[1][0] * state->x[0] + state->A[1][1] * state->x[1] + state->B[1] * a;
- /* Step2: Covariance Predict P(k+1)=A*P(k)*(A^T)+Q;*/
- state->p[0][0] = (state->p[0][0] + state->p[1][0] * state->A[0][1]) + (state->p[0][1] + state->p[1][1] * state->A[0][1])*state->A[0][1] + state->q[0];
- state->p[0][1] = state->p[0][1] + state->p[1][1] * state->A[0][1];//+state->q[0];
- state->p[1][0] = state->p[1][0] + state->p[1][1] * state->A[0][1];//+state->q[1];
- state->p[1][1] = state->p[1][1] + state->q[1];
- /* Step3: Gain Measurement : gain = p * H^T * [r + H * p * H^T]^(-1), H^T means transpose. µÚÈý¸ö¹«Ê½×ª»»*/
- temp0_0 = (state->p[0][0] + state->r[0][0])*(state->p[1][1] + state->r[1][1]) - (state->p[0][1] + state->r[0][1])*(state->p[1][0] + state->r[1][0]);//ÕýÈ·//r¶Ô½ÇÕó
- temp0_1 = (state->p[0][0] + state->r[0][0])*(state->p[1][1] + state->r[1][1]) - (state->p[0][1] + state->r[0][1])*(state->p[1][0] + state->r[1][0]);
- temp1_0 = (state->p[0][0] + state->r[0][0])*(state->p[1][1] + state->r[1][1]) - (state->p[0][1] + state->r[0][1])*(state->p[1][0] + state->r[1][0]);
- temp1_1 = (state->p[0][0] + state->r[0][0])*(state->p[1][1] + state->r[1][1]) - (state->p[0][1] + state->r[0][1])*(state->p[1][0] + state->r[1][0]);
- temp00 = state->p[1][1] / temp0_0;
- temp01 = -state->p[0][1] / temp0_1;
- temp10 = -state->p[1][0] / temp1_0;
- temp11 = state->p[0][0] / temp1_1;
- state->gain[0][0] = state->p[0][0] * temp00 + state->p[0][1] * temp10;
- state->gain[0][1] = state->p[0][0] * temp01 + state->p[0][1] * temp11;
- state->gain[1][0] = state->p[1][0] * temp00 + state->p[1][1] * temp10;
- state->gain[1][1] = state->p[1][0] * temp01 + state->p[1][1] * temp11;
- /* Step4: Status Update : x(n|n) = x(n|n-1) + gain(n) * [z_measure - H(n)*x(n|n-1)]*/
- state->x[0] = state->x[0] + state->gain[0][0] * (x_weiyi - state->x[0]) + state->gain[0][1] * (x_speed - state->x[1]); //ΪºÎÖ»ÓÃÒ»¸ö²ÎÊý
- state->x[1] = state->x[1] + state->gain[1][0] * (x_weiyi - state->x[0]) + state->gain[1][1] * (x_speed - state->x[1]);
- /* Step5: Covariance Update p: p(n|n) = [I - gain * H] * p(n|n-1) ¸üÐÂp*/
- temp0 = state->p[0][0];
- temp1 = state->p[0][1];
- state->p[0][0] = (1 - state->gain[0][0]) * state->p[0][0] - (state->gain[0][1] * state->p[1][0]);
- state->p[0][1] = (1 - state->gain[0][0]) * state->p[0][1] - (state->gain[0][1] * state->p[1][1]);
- state->p[1][0] = (1 - state->gain[1][1]) * state->p[1][0] - state->gain[1][0] * temp0;//state->p[0][0]
- state->p[1][1] = (1 - state->gain[1][1]) * state->p[1][1] - state->gain[1][0] * temp1;//state->p[0][1]
- return 1;
- }
复制代码 全部资料51hei下载地址:
Dijstra.rar
(3 KB, 下载次数: 9)
|