<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
連結: Dijkstra演演算法及其C++實現參考這篇文章
graph類用於鄰接表建立和儲存有向圖。
graph.h:
#ifndef GRAPH_H #define GRAPH_H #include <iostream> #include <string> #include <vector> #include <stdlib.h> using namespace std; // 定義頂點 typedef struct EdgeNode { int adjvex; // 頂點下標 struct EdgeNode *next; // 下一條邊的指標 double cost; // 當前邊的代價 EdgeNode(); ~EdgeNode(); } EdgeNode; // 定義頂點表 typedef struct VexList { string Vexs; //用來儲存頂點資訊 EdgeNode *firstedge; //用來儲存當前頂點的下一個頂點 VexList(); ~VexList(); } VertexList; // 定義圖 typedef class GraphList { public: GraphList(); ~GraphList(); void PrintGraph(); // 列印圖 void CreateGraph(); // 構建圖 vector<VexList> VexList; int Vertexs, Edges; } GraphList; typedef GraphList* GraphListPtr; #endif
graph.cpp
#include <graph.h> EdgeNode::EdgeNode() { cost = 0; next = nullptr; } EdgeNode::~EdgeNode() { //cout << "delete Node" << endl; } VexList::VexList() { firstedge = nullptr; } VexList::~VexList() { //cout << "delete VexList" << endl; } GraphList::GraphList() { VexList.clear(); } GraphList::~GraphList() { //cout << "delete GraphList" << endl; } void GraphList::PrintGraph() { cout << "所建立的地圖如以下所示:" << endl; for (int i = 0; i< Vertexs; i++) { cout << VexList[i].Vexs; //先輸出頂點資訊 EdgeNode * e = VexList[i].firstedge; while (e) { //然後就開始遍歷輸出每個邊表所儲存的鄰接點的下標 if (e->cost == -1) { cout << "---->" << e->adjvex; } else { cout << "-- " << e->cost << " -->" << e->adjvex; } e = e->next; } cout << endl; } } void GraphList::CreateGraph() { EdgeNode *e = new EdgeNode(); cout << "請輸入頂點數和邊數:" << endl; cin >> Vertexs >> Edges; cout << "請輸入頂點的資訊:" << endl; for (int i = 0; i <Vertexs; ++i) { VertexList tmp; cin >> tmp.Vexs; tmp.firstedge = NULL; VexList.push_back(tmp); } for (int k = 0; k < Edges; ++k) { int i, j; //(Vi,Vj) double cost; cout << "請輸入邊(Vi,Vj)與 cost:" << endl; cin >> i >> j >> cost; if (VexList[i].firstedge == NULL) {//當前頂點i後面沒有頂點 e = new EdgeNode; e->adjvex = j; e->cost = cost; e->next = NULL; VexList[i].firstedge = e; } else { //當前i後面有頂點 EdgeNode *p = VexList[i].firstedge; while (p->next) { p = p->next; } e = new EdgeNode; e->adjvex = j; e->cost = cost; e->next = NULL; p->next = e; } } }
PathFinder類用於搜尋最短路徑
pathFinder.h
#ifndef PATH_FINDER_H #define PATH_FINDER_H #include <iostream> #include <graph.h> #include <queue> enum State{OPEN = 0, CLOSED, UNFIND}; // 定義dijkstra求解器 class DijNode { public: DijNode(); DijNode(double _val); ~DijNode() {}; double getCost() { return m_cost; } State getState() { return m_state; } void setCost(double _val) { m_cost = _val; } void setState(State _state) { m_state = _state; } int getIndex() { return m_index; } void setIndex(int _idx) { m_index = _idx; } void setPred(DijNode* _ptr) { preNode = _ptr; } DijNode* getPred() { return preNode; } VertexList Vertex; private: int m_index; double m_cost; // 起點到當前點的代價 State m_state; DijNode* preNode; // 儲存父節點 }; typedef DijNode* DijNodePtr; // 構造優先佇列用的 struct cmp { bool operator() (DijNodePtr &a, DijNodePtr &b) { return a->getCost() > b->getCost(); } }; class PathFinder { public: priority_queue<DijNodePtr, vector<DijNodePtr>, cmp > openList;//用優先佇列做openList,隊首元素為最小值 vector<DijNodePtr> m_path; // 存放最終路徑 PathFinder() { openList.empty(); m_path.clear(); } ~PathFinder() {}; void StoreGraph(GraphListPtr _graph); void Search(int start, int end); void retrievePath(DijNodePtr _ptr); vector<DijNodePtr> NodeList; private: GraphListPtr m_graph; /*vector<DijNodePtr> NodeList;*/ }; typedef PathFinder* PathFinderPtr; #endif
PathFinder.cpp
#include <PathFinder.h> DijNode::DijNode() { m_cost = -1; // -1表示未被探索過,距離為無窮,非負數表示已經被探索過 m_index = -1; m_state = UNFIND; // OPEN表示openlist, CLOSED表示在closeList中,UNFIND表示未探索過 preNode = nullptr; } DijNode::DijNode(double _val) { m_cost = _val; // -1表示未被探索過,非負數表示已經被探索過 m_index = -1; m_state = UNFIND; // OPEN表示openlist, CLOSED表示在closeList中,UNFIND表示未探索過 preNode = nullptr; } void PathFinder::StoreGraph(GraphListPtr _graph) { for (int i = 0; i < _graph->VexList.size(); ++i) { DijNodePtr node = new DijNode(); node->Vertex = _graph->VexList[i]; node->setIndex(i); NodeList.push_back(node); } } void PathFinder::Search(int start, int end) { // 搜尋起點 DijNodePtr m_start = NodeList[start]; m_start->setCost(0); m_start->setIndex(start); m_start->setState(OPEN); openList.push(m_start); int count = 0; while (!openList.empty()) { // 彈出openList中的隊首元素 DijNodePtr cur = openList.top(); cur->setState(CLOSED); // 加入closelist中 openList.pop(); // 遍歷隊首元素所有的邊 EdgeNode *e = cur->Vertex.firstedge; while (e != nullptr) { int _index = e->adjvex; double _cost = e->cost; //cout << "_cost = " << _cost << endl; // 如果節點在close list中,直接跳過 if (NodeList[_index]->getState() == CLOSED) { continue; } if (NodeList[_index]->getCost() == -1) { NodeList[_index]->setCost(cur->getCost() + _cost); // 更新代價 NodeList[_index]->setPred(cur); // 更新父節點 NodeList[_index]->setState(OPEN); // 加入open list中 openList.push(NodeList[_index]); } else if (cur->getCost() + _cost < NodeList[_index]->getCost()) { // 如果從當前節點到第_index個節點的距離更短,更新距離和父節點 NodeList[_index]->setCost(cur->getCost() + _cost); // 更新代價 NodeList[_index]->setPred(cur); // 更新父節點 NodeList[_index]->setState(OPEN); // 加入open list中 } e = e->next; } } cout << "最短距離為:" << NodeList[end]->getCost() << endl; retrievePath(NodeList[end]); } void PathFinder::retrievePath(DijNodePtr ptr) { while (ptr != nullptr) { m_path.push_back(ptr); ptr = ptr->getPred(); } reverse(m_path.begin(),m_path.end()); }
主函數
#include <graph.h> #include <PathFinder.h> int main() { cout << "構建地圖" << endl; GraphListPtr graph = new GraphList(); graph->CreateGraph(); cout << "n n"; graph->PrintGraph(); PathFinderPtr _solver = new PathFinder(); _solver->StoreGraph(graph); cout << "n n"; int start, end; cout << "輸入起點" << endl; cin >> start; cout << "輸入終點" << endl; cin >> end; cout << "n n"; _solver->Search(start, end); cout << "最短路徑為:"; for (int i = 0; i < _solver->m_path.size(); ++i) { cout << _solver->m_path[i]->Vertex.Vexs ; if (i < _solver->m_path.size() - 1) cout << "-->"; } cout << endl; system("pause"); return 0; }
以上就是C++實現Dijkstra演演算法的範例程式碼的詳細內容,更多關於C++ Dijkstra演演算法的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45