1. 程式人生 > >路徑規劃演算法之Bellman-Ford演算法

路徑規劃演算法之Bellman-Ford演算法

最近由於工作需要一直在研究Bellman-Ford演算法,這也是我第一次用C++編寫程式碼。

1、Bellman-Ford演算法總結

(1)Bellman-Ford演算法計算從源點(起始點)到任意一點的最短路徑的長度,初始化陣列m_Dist[m_Segment[i].m_StartPoint] = m_Maxdouble , m_Dist[m_Source]=0。

(2)對每一個路徑進行鬆弛運算

  如果m_Dist[m_Segment[j].m_EndPoint]>m_Dist[m_Segment[j].m_StartPoint]+m_Segment[j].m_Weight,那麼m_Dist[m_Segment[j].m_EndPoint]=m_Dist[m_Segment[j].m_StartPoint]+m_Segment[j].m_Weight進行鬆弛計算。若上述操作沒有對m_Dist進行更新,說明最短路徑已經查詢完畢,或者部分點不可達,跳出迴圈。否則執行下次迴圈;

  由於規定路徑不存在負權重的情況,所以對有負權重的情況這裡不進行說明。

註釋:m_Source是一條有向邊的起點,m_DestPoint是一條有向邊的終點;m_Dist(m_StartPoint,m_EndPoint)為節點m_StartPoint和節點m_EndPoint之間邊;m_Weight(m_StartPoint, m_EndPoint)為節點m_StartPoint和節點m_EndPoint之間的邊的權值;                                                                  m_Dist[m_Segment[i].m_StartPoint] 是指源節點到m_Segment[i].m_StartPoint節點的距離;

下面為本功能模組的程式碼,由於這只是車載系統中的一部分程式碼,與其他功能模組存在互相呼叫的情況,路徑資訊存在於SQLite資料庫找中,讀取資料庫是一個完整的功能模組,我這裡是直接呼叫就好了。由於這是本人第一次編寫C++程式,哪位大神覺得程式碼有很可以優化的部分,歡迎提出,進行優化!!!

#ifndef ROUTEPLAN_H
#define ROUTEPLAN_H


#include <qmap.h>
#include <QVector>
#include <QList>
#include <iostream>
using namespace
std; typedef struct { int m_StartPoint; //線的起始點 int m_EndPoint; //線的終點 double m_Weight; //線的權重 int m_SegmentNum; //有向邊編號 }PathPlaning_Segment; class RoutePlan:public QObject { Q_OBJECT public: const static int m_Maxnum = 10000; //最大邊數 const double m_Maxdouble = 99999999; //源點和某點不可達時的距離 int m_Nodenum; //節點的數目 int m_Edgenum; //邊的數目 int m_Source; //起始點 int m_DestPoint; //目的地 int m_RecvNum = 0; PathPlaning_Segment m_Segment[m_Maxnum]; //路徑陣列 int m_RelaxNum[m_Maxnum]; //鬆弛的路徑編號 int m_Dist[m_Maxnum]; //距離陣列 RoutePlan(); //初始化函式 void Init(int srcPoint, int destPoint ); //貝爾曼福特函式 void Bellman_Ford(); //返回路徑函式 QList<int> ReturnPath(); }; #endif // ROUTEPLAN_H #include "routeplan.h" RoutePlan::RoutePlan() { } /*********************************************************************** Description: 初始化函式 Arguments: int srcPoint 起始點 int destPoint 目標點 Returns: NULL Notes: 從“/home/map.zar”地圖檔案中讀取地圖資訊,賦值到本地 ************************************************************************/ void RoutePlan::Init(int srcPoint,int destPoint) { m_RouteManager = new RouteManager(); if(m_RouteManager->ReadRouteApplicationFile("/home/map.zar")) { m_Nodenum = m_RouteManager->ReturnSizeofPoint(); m_Edgenum = m_RouteManager->ReturnSizeofSegment(); m_Source = srcPoint; m_DestPoint = destPoint; int num = 0; QMap<int,PathApplication_Segments>:: const_iterator iter; QMap<int,PathApplication_Segments> seg = m_RouteManager->ReturnSegment(); for( iter=seg.constBegin(); iter!=seg.constEnd(); iter++) { m_Segment[num].m_StartPoint = iter.value().StartPointKey; m_Segment[num].m_EndPoint = iter.value().EndPointKey; m_Segment[num].m_Weight = iter.value().Length; m_Segment[num].m_SegmentNum = iter.key(); num++; } for(int i = 0;i<=m_Edgenum-1;i++) { m_Dist[m_Segment[i].m_StartPoint]=m_Maxdouble; } m_Dist[m_Source]=0; } Bellman_Ford(); } /*********************************************************************** Description: 貝爾曼福特函式 Arguments: NULL Returns: NULL Notes: 鬆弛路徑,記錄鬆弛的路徑編號,鬆弛後標記的路徑數量 ************************************************************************/ void RoutePlan::Bellman_Ford() { for(int i=0;i<=m_Nodenum-2;i++) { for(int j=0;j<=m_Edgenum-1;j++) { //鬆弛路徑 if(m_Dist[m_Segment[j].m_EndPoint]>m_Dist[m_Segment[j].m_StartPoint]+m_Segment[j].m_Weight) { m_Dist[m_Segment[j].m_EndPoint]=m_Dist[m_Segment[j].m_StartPoint]+m_Segment[j].m_Weight; m_RelaxNum[m_RecvNum] = m_Segment[j].m_SegmentNum; m_RecvNum++; } } } } /*********************************************************************** Description: 返回路徑函式 Arguments: NULL Returns: return lst 返回路徑編號 Notes: 鬆弛路徑,記錄鬆弛的路徑編號,鬆弛後標記的路徑數量 ************************************************************************/ QList<int> RoutePlan::ReturnPath() { QList<int> lst; for(int k = 0; k<m_RecvNum;k++) { for(int i = 0;i<m_RecvNum;i++) { for(int j=0;j<=m_Edgenum;j++) { if(m_RelaxNum[i] == m_Segment[j].m_SegmentNum) { if(m_DestPoint == m_Segment[j].m_EndPoint) { lst.push_front(m_Segment[j].m_SegmentNum); cout<<"m_SegmentNum = "<<m_Segment[j].m_SegmentNum<<endl; m_DestPoint = m_Segment[j].m_StartPoint; if(m_Segment[j].m_StartPoint == m_Source) { return lst; } } } } } } cout<<"there is not path form "<<m_Source<<" to "<<m_DestP