欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++用Dijkstra(迪杰斯特拉)算法求最短路徑

 更新時(shí)間:2016年12月14日 11:28:11   投稿:daisy  
Dijkstra(迪杰斯特拉)算法是典型的最短路徑路由算法,用于計(jì)算一個(gè)節(jié)點(diǎn)到其他所有節(jié)點(diǎn)的最短路徑。主要特點(diǎn)是以起始點(diǎn)為中心向外層層擴(kuò)展,直到擴(kuò)展到終點(diǎn)為止。下面這篇文章就給大家介紹關(guān)于C++用Dijkstra算法(迪杰斯特拉算法)求最短路徑的方法,下面來(lái)一起看看吧。

算法介紹

迪杰斯特拉算法是由荷蘭計(jì)算機(jī)科學(xué)家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是從一個(gè)頂點(diǎn)到其余各頂點(diǎn)的最短路徑算法,解決的是有向圖中最短路徑問(wèn)題。迪杰斯特拉算法主要特點(diǎn)是以起始點(diǎn)為中心向外層層擴(kuò)展,直到擴(kuò)展到終點(diǎn)為止。Dijkstra算法能得出最短路徑的最優(yōu)解,但由于它遍歷計(jì)算的節(jié)點(diǎn)很多,所以效率低。

算法思想

按路徑長(zhǎng)度遞增次序產(chǎn)生算法:

 把頂點(diǎn)集合V分成兩組:

 ?。?)S:已求出的頂點(diǎn)的集合(初始時(shí)只含有源點(diǎn)V0)

 ?。?)V-S=T:尚未確定的頂點(diǎn)集合
  將T中頂點(diǎn)按遞增的次序加入到S中,保證:

  (1)從源點(diǎn)V0到S中其他各頂點(diǎn)的長(zhǎng)度都不大于從V0到T中任何頂點(diǎn)的最短路徑長(zhǎng)度

 ?。?)每個(gè)頂點(diǎn)對(duì)應(yīng)一個(gè)距離值

  S中頂點(diǎn):從V0到此頂點(diǎn)的長(zhǎng)度

  T中頂點(diǎn):從V0到此頂點(diǎn)的只包括S中頂點(diǎn)作中間頂點(diǎn)的最短路徑長(zhǎng)度

  依據(jù):可以證明V0到T中頂點(diǎn)Vk的,或是從V0到Vk的直接路徑的權(quán)值;或是從V0經(jīng)S中頂點(diǎn)到Vk的路徑權(quán)值之和

應(yīng)用舉例

(1)題目:編寫一個(gè)校園導(dǎo)游程序,為來(lái)訪的客人提供各種信息查詢服務(wù)。

    主要功能:1.設(shè)計(jì)學(xué)校的校園平面圖,所含景點(diǎn)不少于10個(gè):頂點(diǎn)表示景點(diǎn),邊表示路徑等;

         2.為客人提供圖中任意景點(diǎn)相關(guān)信息的查詢;

         3.為客人提供圖中任意景點(diǎn)的問(wèn)路查詢,即查詢?nèi)艘跃包c(diǎn)間的一條最短路徑。

      要求:1.設(shè)計(jì)一個(gè)主界面;

              2.設(shè)計(jì)功能菜單,供用戶選擇

              3.有一定的實(shí)用性。

(2)設(shè)計(jì)思路:

  1、該題主要有算法思路以及程序的邏輯思路,首先從邏輯思路講,進(jìn)入程序,首先設(shè)計(jì)一個(gè)主菜單,選項(xiàng)有景點(diǎn)信息查詢,最短路徑查詢以及顯示景點(diǎn)的平面視圖三個(gè)子菜單,然后根據(jù)用戶的輸入選擇的子菜單前的編號(hào),分進(jìn)入不同的子菜單;該功能是由if….else if…. 語(yǔ)句實(shí)現(xiàn)。在景點(diǎn)信息查詢和最短路徑查詢子菜單下還有二級(jí)子菜 單,都是列 出所有景點(diǎn)并在前面編號(hào),查詢景點(diǎn)信息時(shí),輸入景點(diǎn)前面的編號(hào)即可,查詢最短路徑時(shí),先輸入起點(diǎn)的編號(hào),再輸入終點(diǎn)的編號(hào)。而顯示景點(diǎn)視圖則調(diào)用景點(diǎn)平面圖函數(shù)即可顯 示。

  2、算法思路主要是迪杰斯特拉算法的思路,利用迪杰斯特拉算法求最短路徑。

  3、先定義好圖的儲(chǔ)存結(jié)構(gòu),本題采用鄰接矩陣的方式來(lái)表示圖,并在主函數(shù)中初始化該圖;

  4、定義三個(gè)全局一維數(shù)組,一個(gè)bool類型數(shù)組S[]用來(lái)記錄從v0到vi是否已經(jīng)確定了最短路徑,是則記S[i]=true ,否記S[i]= flase;一個(gè)int 類型數(shù)組Path[]用來(lái)記錄從v0到vi的當(dāng)前最短路徑上的vi的直接前驅(qū)頂點(diǎn)編號(hào),若v 到vi之間有邊則記Path[i] = v的編號(hào),否則記Path[i] = -1;最后一個(gè)數(shù)組D[]用來(lái)記錄從v0到vi之間的最短路徑長(zhǎng)度,存在則記v0到vi之間邊的權(quán)值或者權(quán)值和,否則記為MAX

  5、定義一個(gè)求最短路徑的函數(shù),傳入的參數(shù)為圖和起點(diǎn),首先進(jìn)行初始化工作,初始化S[]數(shù)組全為false,D[]數(shù)組初始化為起點(diǎn)到各個(gè)頂點(diǎn)的權(quán)值,Path[]數(shù)組初始化為起點(diǎn)是否與各頂點(diǎn)有邊,有則記v0否則記-1;

  6、然后進(jìn)行n-1次for循環(huán),找出vo到其余n-1個(gè)頂點(diǎn)之間的最短路徑,比較當(dāng)前D[]數(shù)組中最小值,找到最小值的編號(hào)v,該編號(hào)就是從v0出發(fā)到所有頂點(diǎn)中距離最短的頂點(diǎn)編號(hào),然后把S[v]的值置為true。說(shuō)明從v0出發(fā)到頂點(diǎn)v已經(jīng)找到最短路徑;

  7、接著就要更新D[]數(shù)組,因?yàn)镈[]數(shù)組是記錄最短路徑的,現(xiàn)在已經(jīng)找到了一個(gè)頂點(diǎn)的最短路徑,已該頂點(diǎn)v為中間點(diǎn),判斷從該頂點(diǎn)v出發(fā)到剩下的頂點(diǎn)的路徑長(zhǎng)度加上該點(diǎn)到v0的路徑長(zhǎng)度是否小于直接從v0出發(fā)到其余頂點(diǎn)的路徑長(zhǎng)度,如果小于,則更新D[i]為以該頂點(diǎn)v為中間點(diǎn)求得的路徑長(zhǎng)度。更新Path[i] = v;即i的前驅(qū)不再是v0而是v;

  8、循環(huán)(6)(7)兩步n-1次即可得到D[]數(shù)組,輸出D[]數(shù)組既是v0到所有頂點(diǎn)的最短路徑長(zhǎng)度;

(3)源代碼:

#include<iostream>
#include<fstream>
#include<string>
using namespace std;
/**
 *作者:Dmego
 *時(shí)間:2016-12-12
 */
#define MAX 1000000 //表示極大值∞
#define max 10
bool S[max]; //記錄從源點(diǎn)V0到終點(diǎn)Vi是否已經(jīng)確定為最短路徑,確定了記true,否則記false
int Path[max]; //記錄從源點(diǎn)V0到終點(diǎn)Vi的當(dāng)前最短路徑上終點(diǎn)Vi的直接前驅(qū)頂點(diǎn)序號(hào),若V0到Vi之間有邊前驅(qū)為V0否則為-1 
int D[max]; //記錄源點(diǎn)到終點(diǎn)之間最短路徑的長(zhǎng)度,存在記V0到Vi的邊的權(quán)值,否則記為MAX 
typedef struct
{
 string vexs[max]; //頂點(diǎn)表
 int arcs[max][max]; //鄰接矩陣 
 int vexnum, arcnum; //圖當(dāng)前點(diǎn)數(shù)和邊數(shù)

}AMGraph;
//利用迪杰斯特拉算法求最短路徑
void ShortestPath_DIJ(AMGraph &G, int v0)
{//使用迪杰斯特拉算法求有向網(wǎng)G中的V0 定點(diǎn)到其余頂點(diǎn)的最短路徑
 int n = G.vexnum;//頂點(diǎn)數(shù)
 for (int v = 0; v < n; v++)//n個(gè)頂點(diǎn)依次初始化
 {
 S[v] = false;//S初始化為空集
 D[v] = G.arcs[v0][v];//將v0到各個(gè)終點(diǎn)的最短路徑長(zhǎng)度初始化為邊上的權(quán)值
 if (D[v] < MAX)
  Path[v] = v0;//如果v0和v之間有邊,則將v的前驅(qū)初始化為v0
 else
  Path[v] = -1;//如果v0和v之間無(wú)邊,則將v的前驅(qū)初始化為-1
 }
 S[v0] = true; //將v0加入s
 D[v0] = 0;//源點(diǎn)到源點(diǎn)的權(quán)值為0
 //---------初始化結(jié)束,開始主循環(huán),每次求得v0到某個(gè)頂點(diǎn)的最短路徑,將v加到S數(shù)組
 for (int i = 1; i < n; i++)//依次對(duì)其余n-1個(gè)頂點(diǎn)進(jìn)行計(jì)算
 {
 int min = MAX;
 int v = v0;
 for (int w = 0; w < n; w++)
 {
  if (!S[w] && D[w] < min)
  {//選擇一條當(dāng)前最短路徑,終點(diǎn)為v
  v = w;
  min = D[w];
  }
  S[v] = true;//將v加到s集合中
  for (int w = 0; w < n; w++)
  {//更新從v0出發(fā)到集合V-S上所有頂點(diǎn)的最短路徑長(zhǎng)度
  if (!S[w] && (D[v] + G.arcs[v][w] < D[w]))
  {
   D[w] = D[v] + G.arcs[v][w];//更新D[w]
   Path[w] = v;//更改w的前驅(qū)為v
  }
  }
 }
 }
}
//背景函數(shù)
void backGround()
{
 cout << "|*****************************************************************|" << endl;
 cout << " |------------------------鐵大旅游景點(diǎn)圖-----------------|" << endl;
 cout << "|*****************************************************************|" << endl;
 cout << "|  ⑦      單位:米 |" << endl;
 cout << "|  九教       |" << endl;
 cout << "|  ◎     ⑧  |" << endl;
 cout << "|  ↗↖     九棟  |" << endl;
 cout << "| ③ 200╱ ╲     ◎  |" << endl;
 cout << "| 西 ↙ ╲ 150    ↗ ↖  |" << endl;
 cout << "| 操 ◎  ╲ ①  160 ╱ ╲ 200 |" << endl;
 cout << "| 場(chǎng) ↖150  ╲ 信息  ⑥ ╱  ╲ |" << endl;
 cout << "| ④ ↘ 140 ↘ 學(xué)院 200 基教 ↙ 230 ↘ |" << endl;
 cout << "| 體育館 ◎-------------→◎←--------------→◎←--------------→◎ |" << endl;
 cout << "|  ↖  ↗ ↖  ↗ ↖  ↗② |" << endl;
 cout << "|  100 ╲ ╱ ╲ 125 ╱ ╲ 150 ╱ 綜 |" << endl;
 cout << "|  ↘ ↙ 100 ╲ ╱135 ╲ ╱145 餐 |" << endl;
 cout << "|   ◎  ↘ ↙  ↘ ↙ |" << endl;
 cout << "|  ⑨ 沁園  ◎   ◎  |" << endl;
 cout << "|    ⑩ 翠園  ⑤ 春暉樓  |" << endl;
 cout << "|        |" << endl;
 cout << "|*****************************************************************|" << endl;

}
//主菜單
void menu()
{
 cout << "|*****************************************************************|" << endl;
 cout << "|----------------------------鐵大導(dǎo)游小程序-----------------------|" << endl;
 cout << " |*********************************************************|" << endl;
 cout << " |--------------------1-景點(diǎn)信息查詢--------------|" << endl;
 cout << " |--------------------2-最短路徑查詢--------------|" << endl;
 cout << " |--------------------3-顯示景點(diǎn)視圖--------------|" << endl;
 cout << " |-------------------4-退出導(dǎo)游程序------ --------|" << endl;
 cout << "|*****************************************************************|" << endl;
 cout << ">>>請(qǐng)選擇:";
}
//景點(diǎn)信息查詢二級(jí)菜單
void jmenu()
{
 cout << "|*****************************************************************|" << endl;
 cout << " |-------------------------景點(diǎn)信息查詢------------------------|" << endl;
 cout << " |***********************************************************|" << endl;
 cout << " |----------------------1-信息學(xué)院介紹-------------------| " << endl;
 cout << " |----------------------2-綜合餐廳介紹-------------------| " << endl;
 cout << " |----------------------3-西操場(chǎng)介紹---------------------| " << endl;
 cout << " |----------------------4-體育館介紹---------------------| " << endl;
 cout << " |----------------------5-春暉樓介紹---------------------| " << endl;
 cout << " |----------------------6-基教介紹-----------------------| " << endl;
 cout << " |----------------------7-九教介紹-----------------------| " << endl;
 cout << " |----------------------8-九棟介紹-----------------------| " << endl;
 cout << " |----------------------9-沁園介紹-----------------------| " << endl;
 cout << " |---------------------10-翠園介紹-----------------------| " << endl;
 cout << "|*****************************************************************|" << endl;
 cout << ">>>請(qǐng)要查詢的景點(diǎn)編號(hào):";
}
//最短路徑查詢二級(jí)菜單
void pmenu()
{
 cout << "|*****************************************************************|" << endl;
 cout << " |-------------------------最短路徑查詢------------------------|" << endl;
 cout << " |***********************************************************|" << endl;
 cout << " |---------------------1-信息學(xué)院-------------------| " << endl;
 cout << " | --------------------2-綜合餐廳-------------------| " << endl;
 cout << " |---------------------3-西操場(chǎng)---------------------| " << endl;
 cout << " |---------------------4-體育館---------------------| " << endl;
 cout << " |---------------------5-春暉樓---------------------| " << endl;
 cout << " |---------------------6-基教-----------------------| " << endl;
 cout << " |---------------------7-九教-----------------------| " << endl;
 cout << " |---------------------8-九棟-----------------------| " << endl;
 cout << " |---------------------9-沁園-----------------------| " << endl;
 cout << " |--------------------10-翠園-----------------------| " << endl;
 cout << "|*****************************************************************|" << endl;
 cout << ">>>請(qǐng)依次輸入起點(diǎn)編號(hào)和終點(diǎn)編號(hào):";
}
void main()
{
 //初始化操作
 AMGraph amg = { { "信息學(xué)院","綜合餐廳","西操場(chǎng)","體育館","春暉樓",
   "基教", "九教", "九棟", "沁園", "翠園" },
 //-1代表兩邊不相連,權(quán)值無(wú)限大
 //鄰接矩陣 /* 信 綜 西 體 春 基 教 棟 沁 翠*/ 
   {{MAX,MAX,MAX,140,MAX,200,150,MAX,100,125 },
   {MAX,MAX,MAX,MAX,145,230,MAX,100,MAX,MAX },
   {MAX,MAX,MAX,150,MAX,MAX,200,MAX,MAX,MAX },
   {140,MAX,150,MAX,MAX,MAX,MAX,MAX,100,MAX },
   {MAX,145,MAX,MAX,MAX,150,MAX,MAX,MAX,MAX },
   {200,230,MAX,MAX,150,MAX,MAX,160,MAX,135 },
   {150,MAX,200,MAX,MAX,MAX,MAX,MAX,MAX,MAX },
   {MAX,200,MAX,MAX,MAX,160,MAX,MAX,MAX,MAX },
   {100,MAX,MAX,100,MAX,MAX,MAX,MAX,MAX,MAX },
   {125,MAX,MAX,MAX,MAX,135,MAX,MAX,MAX,MAX }
   },10,14};
 int f, ff;
 int start, end;
 while (true)
 {
 cout << endl;
 menu();
 cin >> f;
 if (f == 1)
 {
  jmenu();
  cin >> ff;
       //景點(diǎn)信息從文件中讀取
  ifstream outfile("schooltravel.txt", ios :: out | ios :: binary);
  if (!outfile)
  {
  cerr << "讀取景點(diǎn)介紹文件失??!" << endl;
  abort();
  }
  string str[max];
  int i = 0;
  while (getline(outfile, str[i++]));
  cout << "|-----------------------景點(diǎn)介紹-------------------| " << endl;
  if (ff == 1)
  cout << str[0] << endl;
  else if (ff == 2)
  cout << str[1] << endl;
  else if (ff == 3)
  cout << str[2] << endl;
  else if(ff == 4)
  cout << str[3] << endl;
  else if (ff == 5)
  cout << str[4] << endl;
  else if (ff == 6)
  cout << str[5] << endl;
  else if (ff == 7)
  cout << str[6] << endl;
  else if (ff == 8)
  cout << str[7] << endl;
  else if (ff == 9)
  cout << str[8] << endl;
  else if (ff == 10)
  cout << str[9] << endl;
  cout << "|-------------------------------------------------|" << endl;
 }
 else if (f == 2)
 {
  pmenu();
  cin >> start >> end;
  ShortestPath_DIJ(amg, start - 1);
  int temp = end-1;
  int temp1, temp2;
  int flag[max], m = 0;
  cout << "從" << amg.vexs[start - 1] << "到" << amg.vexs[end - 1] << "最短路徑為:" ;
  while (temp!= -1)
  {
  flag[m++] = temp;
  temp1 = temp ;
  temp2 = Path[temp1];
  temp = temp2;
  }
  for (int i = m-1; i >= 0; i--)
  {
  cout <<amg.vexs[flag[i]] << "->";
  }
  cout << endl;
  cout << "最短路徑值為:" << D[end - 1] <<"米"<< endl;
 }
 else if (f == 3)
 {
  backGround();
 }
 else if (f == 4)
 {
  cout << ">>>退出成功!" << endl;
  exit(0);
 }
 }
}

(4)運(yùn)行截圖:

總結(jié)

以上就是關(guān)于C++用Dijkstra算法(迪杰斯特拉算法)求最短路徑的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流。

相關(guān)文章

  • C++中constexpr與模板元編程的基礎(chǔ)、常見問(wèn)題、易錯(cuò)點(diǎn)及其規(guī)避策略

    C++中constexpr與模板元編程的基礎(chǔ)、常見問(wèn)題、易錯(cuò)點(diǎn)及其規(guī)避策略

    C++編譯時(shí)計(jì)算允許程序在編譯階段完成計(jì)算任務(wù),constexpr與模板元編程是C編譯時(shí)計(jì)算的兩把利劍,它們不僅能夠提升程序的性能,還能增強(qiáng)代碼的健壯性和可維護(hù)性,通過(guò)避開本文闡述的易錯(cuò)點(diǎn),開發(fā)者可以更加得心應(yīng)手地運(yùn)用這些特性,編寫出既高效又優(yōu)雅的C代碼
    2024-06-06
  • C++?Boost?weak_ptr智能指針超詳細(xì)講解

    C++?Boost?weak_ptr智能指針超詳細(xì)講解

    智能指針是一種像指針的C++對(duì)象,但它能夠在對(duì)象不使用的時(shí)候自己銷毀掉。雖然STL提供了auto_ptr,但是由于不能同容器一起使用(不支持拷貝和賦值操作),因此很少有人使用。它是Boost各組件中,應(yīng)用最為廣泛的一個(gè)
    2022-11-11
  • 基于對(duì)話框程序中讓對(duì)話框捕獲WM_KEYDOWN消息的實(shí)現(xiàn)方法

    基于對(duì)話框程序中讓對(duì)話框捕獲WM_KEYDOWN消息的實(shí)現(xiàn)方法

    下面我們將通過(guò)程序給大家演示基于對(duì)話框的應(yīng)用程序?qū)M_KEYDOWN消息的捕獲。需要的朋友可以參考下
    2013-05-05
  • C++ string字符串的修改與替換方法詳析

    C++ string字符串的修改與替換方法詳析

    這篇文章主要給大家介紹了關(guān)于C++ string字符串修改與替換方法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • C語(yǔ)言 基本語(yǔ)法示例講解

    C語(yǔ)言 基本語(yǔ)法示例講解

    本篇文章主要講解C語(yǔ)言 基本語(yǔ)法,這里提供簡(jiǎn)單的示例和代碼來(lái)詳細(xì)講解C語(yǔ)言的基本語(yǔ)法,開始學(xué)習(xí)C語(yǔ)言的朋友可以看一下
    2016-08-08
  • C語(yǔ)言+MySQL實(shí)現(xiàn)推箱子游戲

    C語(yǔ)言+MySQL實(shí)現(xiàn)推箱子游戲

    經(jīng)典的推箱子是一個(gè)來(lái)自日本的古老游戲,目的是在訓(xùn)練你的邏輯思考能力。本文將通過(guò)C語(yǔ)言和MySQL實(shí)現(xiàn)推箱子這一經(jīng)典游戲,感興趣的可以了解一下
    2022-02-02
  • C++實(shí)現(xiàn)迷宮算法實(shí)例解析

    C++實(shí)現(xiàn)迷宮算法實(shí)例解析

    這篇文章主要介紹了C++實(shí)現(xiàn)迷宮算法實(shí)例解析,是一個(gè)比較經(jīng)典的C++算法,有一定的學(xué)習(xí)與借鑒價(jià)值,需要的朋友可以參考下
    2014-07-07
  • C++存儲(chǔ)鏈接性原理詳解

    C++存儲(chǔ)鏈接性原理詳解

    這篇文章主要為大家介紹了C++存儲(chǔ)鏈接性原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Qt中QZXing 的編譯與使用

    Qt中QZXing 的編譯與使用

    本文主要介紹了Qt中QZXing 的編譯與使用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 一文詳解C++ 智能指針的原理、分類及使用

    一文詳解C++ 智能指針的原理、分類及使用

    智能指針的本質(zhì)就是使用一個(gè)對(duì)象來(lái)接管一段開辟的空間,這篇文章就來(lái)給大家介紹介紹C++智能指針的原理,分類及使用方法,文中有詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-05-05

最新評(píng)論