HOME 首頁
SERVICE 服務產(chǎn)品
XINMEITI 新媒體代運營
CASE 服務案例
NEWS 熱點資訊
ABOUT 關于我們
CONTACT 聯(lián)系我們
創(chuàng)意嶺
讓品牌有溫度、有情感
專注品牌策劃15年

    如何求最短路徑(如何求最短路徑數(shù)據(jù)結構)

    發(fā)布時間:2023-04-14 09:14:17     稿源: 創(chuàng)意嶺    閱讀: 50        

    大家好!今天讓創(chuàng)意嶺的小編來大家介紹下關于如何求最短路徑的問題,以下是小編對此問題的歸納整理,讓我們一起來看看吧。

    開始之前先推薦一個非常厲害的Ai人工智能工具,一鍵生成原創(chuàng)文章、方案、文案、工作計劃、工作報告、論文、代碼、作文、做題和對話答疑等等

    只需要輸入關鍵詞,就能返回你想要的內(nèi)容,越精準,寫出的就越詳細,有微信小程序端、在線網(wǎng)頁版、PC客戶端

    官網(wǎng):https://ai.de1919.com。

    創(chuàng)意嶺作為行業(yè)內(nèi)優(yōu)秀的企業(yè),服務客戶遍布全球各地,如需了解SEO相關業(yè)務請撥打電話175-8598-2043,或添加微信:1454722008

    本文目錄:

    如何求最短路徑(如何求最短路徑數(shù)據(jù)結構)

    一、求A到B之間的最短路徑,怎么獲取

    問題:從某頂點出發(fā),沿圖的邊到達另一頂點所經(jīng)過的路徑中,各邊上權值之和最小的一條路徑——最短路徑。解決最短路的問題有以下算法,Dijkstra算法,Bellman-Ford算法,F(xiàn)loyd算法和SPFA算法,另外還有著名的啟發(fā)式搜索算法A*,不過A*準備單獨出一篇,其中Floyd算法可以求解任意兩點間的最短路徑的長度。任意一個最短路算法都是基于這樣一個事實:從任意節(jié)點A到任意節(jié)點B的最短路徑不外乎2種可能,1是直接從A到B,2是從A經(jīng)過若干個節(jié)點到B。

    (1) 迪杰斯特拉(Dijkstra)算法按路徑長度(看下面表格的最后一行,就是next點)遞增次序產(chǎn)生最短路徑。先把V分成兩組:

    S:已求出最短路徑的頂點的集合

    V-S=T:尚未確定最短路徑的頂點集合

    將T中頂點按最短路徑遞增的次序加入到S中,依據(jù):可以證明V0到T中頂點Vk的最短路徑,或是從V0到Vk的直接路徑的權值或是從V0經(jīng)S中頂點到Vk的路徑權值之和(反證法可證,說實話,真不明白哦)。

    (2) 求最短路徑步驟

    初使時令 S={V0},T={其余頂點},T中頂點對應的距離值, 若存在<V0,Vi>,為<V0,Vi>弧上的權值(和SPFA初始化方式不同),若不存在<V0,Vi>,為Inf。

    從T中選取一個其距離值為最小的頂點W(貪心體現(xiàn)在此處),加入S(注意不是直接從S集合中選取,理解這個對于理解vis數(shù)組的作用至關重要),對T中頂點的距離值進行修改:若加進W作中間頂點,從V0到Vi的距離值比不加W的路徑要短,則修改此距離值(上面兩個并列for循環(huán),使用最小點更新)。

    重復上述步驟,直到S中包含所有頂點,即S=V為止(說明最外層是除起點外的遍歷)。

    二、最短路徑求最值12個模型詳解

    最短路徑求最值12個模型詳解見下:

    問題一:在直線 l 上求一點 P,使得 PA + PB 值最小 .

    作法:連接 AB,與直線 l 的交點即為 P 點 .

    原理:兩點之間線段最短 . PA + PB 最小值為 AB .

    問題二:(“將軍飲馬問題”)在直線 l 上求一點 P,使得 PA + PB 值最小 .

    作法:作點 B 關于直線 l 的對稱點 B',連接 AB' 與 l 的交點即為點 P.

    如何求最短路徑(如何求最短路徑數(shù)據(jù)結構)

    原理:兩點之間線段最短. PA + PB 最小值為 AB' .

    問題三:在直線 l1、l2 上分別求點 M、N,使得 △PMN 的周長最?。?/p>

    作法:分別作點 P 關于兩條直線的對稱點 P' 和 P'',連接 P'P'',與兩條直線的交點即為點 M,N.

    原理:兩點之間線段最短. PM + MN + PN 的最小值為線段 P'P'' 的長.

    問題四:在直線 l1、l2 上分別求點 M、N,使四邊形 PQMN 的周長最?。?/p>

    作法:分別作點 Q 、P 關于直線 l1、l2 的對稱點 Q' 和 P' 連接 Q'P',與兩直線交點即為點 M,N.

    原理:兩點之間線段最短. 四邊形 PQMN 周長的最小值為線段 Q'P' + PQ 的長.

    問題五:(“造橋選址問題”)直線 m∥n,在 m、n 上分別求點 M、N,使 MN⊥m,

    且 AM + MN + BN 的值最小.

    作法:將點 A 向下平移 MN 的長度單位得 A',連接 A'B,交 n 于點 N,過 N 作 NM⊥m 于 M .

    原理:兩點之間線段最短 . AM + MN + BN 的最小值為 A'B + MN .

    問題六:在直線 l 上求兩點 M , N (M 在左),使 MN = a , 并使 AM + MN + NB 的值最小 .

    作法:將點 A 向右平移 a 個長度單位得 A',作 A' 關于直線 l 的對稱點 A'',連接 A''B 交直線 l 于點 N,

    將 N 點向左平移 a 個單位得 M .

    原理:兩點之間線段最短 . AM + MN + NB 的最小值為 A''B + MN .

    問題七:在 l1 上求點 A,在 l2 上求點 B,使 PA + AB 值最小 .

    作法:作點 P 關于 l1 的對稱點 P',作 P'B⊥l2 于點 B,交 l1 于點 A .

    原理:點到直線,垂線段的距離最短 . PA + AB 的最小值為線段 P'B 的長 .

    問題八:A 為 l1上一定點,B 為 l2 上一定點,在 l2 上求點 M,在 l1上求點 N,

    使 AM + MN + NB 的值最小 .

    作法:作點 A 關于 l2 的對稱點 A' , 點 B 關于 l1 的對稱點 B',連接 A'B' 交 l2 于點 M,交 l1 于點 N.

    原理:兩點之間線段最短. AM + MN + NB 的最小值為線段 A'B' 的長.

    問題九:在直線 l 上求一點 P,使 | PA - PB | 的值最?。?/p>

    作法:連接 AB,作 AB 的中垂線與直線 l 的交點即為 P 點.

    原理:垂直平分上的點到線段兩端點的距離相等. | PA - PB | = 0 .

    問題十:在直線 l 上求一點 P,使 | PA - PB | 的值最大.

    作法:作直線 AB,與直線 l 的交點即為 P 點.

    原理:三角形任意兩邊之差小于第三邊. | PA - PB | ≤ AB , | PA - PB | 的最大值 = AB .

    問題十一:在直線 l 上求一點 P,使 | PA - PB | 的值最大.

    作法:作點 B 關于直線 l 的對稱點 B' 作直線 AB',與直線 l 的交點即為 P 點.

    原理:三角形任意兩邊之差小于第三邊. | PA - PB | ≤ AB' , | PA - PB | 的最大值 = AB' .

    問題十二:(“費馬點”)△ABC 中每一內(nèi)角都小于 120°,在 △ABC 內(nèi)求一點 P,

    使得 PA + PB + PC 的值最小 .

    作法:所求點為 “費馬點” ,即滿足 ∠APB = ∠BPC = ∠APC = 120° .

    以 AB 、 AC 為邊向外作等邊 △ABD、△ACE,連接 CD、BE 相交于點 P,點 P 即為所求 .

    原理:兩點之間線段最短 . PA + PB + PC 的最小值 = CD .

    三、數(shù)據(jù)結構求最短路徑

    用Dijkstra算法求從V1頂點到其他各頂點的最短距離和最短路徑的C語言程序如下

    #include <stdio.h>

    #include <string.h>

    #include <stdlib.h>

    #define N 6 // 頂點數(shù)

    #define INF 32767

    int adj_arr[N][N] = {{INF, 2, 3, INF, INF, INF},

                       {INF, INF, INF, 5, INF, INF},

                       {INF, INF, INF, 3, 10, INF},

                       {INF, INF, INF, INF, INF, 4},

                       {INF, INF, INF, INF, INF, INF},

                       {INF, INF, INF, INF, 2, INF}}; // 用一個全局二維數(shù)組存儲帶權有向圖的鄰接矩陣

    void shortest_path(int start, int end);

    void print_shortest_path(int* distance,int* path,int* used,int start,int end);

    int main(){

      int i;

      char s1[3];

      for(i=1;i<6;i++){

       shortest_path(0, i);

      }

      return 0;

    }

    void shortest_path(int start, int end){ // 基于Dijkstra算法的最短路徑函數(shù)

      int distance[N]; // 用于存放起始點到其余各點的最短距離

      int path[N]; // 用于存放起始點到其余各點最短路徑的前一個頂點

      int used[N] = { 0 }; // 用于標記該頂點是否已經(jīng)找到最短路徑

      int i, j, min_node, min_dis, pass_flag = 0;

      for(i = 0; i < N; i++){

          distance[i] = adj_arr[start][i]; // 初始化距離數(shù)組

          if(adj_arr[start][i] < INF){

              path[i] = start; // 初始化路徑數(shù)組

          }else{

              path[i] = -1;

          }

      }

      used[start] = 1;

      path[start] = start;

      for(i = 0; i < N; i++){

          min_dis = INF;

          for(j = 0; j < N; j++){

              if(used[j] == 0 && distance[j] < min_dis){

                  min_node = j;

                  min_dis = distance[j];

                  pass_flag++; // 標記是否存在通路

              }

          }

          if(pass_flag != 0){

              used[min_node] = 1;

              for(j = 0; j < N; j++){

                  if(used[j] == 0){

                      if(adj_arr[min_node][j] < INF && distance[min_node] + adj_arr[min_node][j] < distance[j]){

                          distance[j] = distance[min_node] + adj_arr[min_node][j];

                          path[j] = min_node;

                      }

                  }

              }

          }else{

              printf("沒有通路!n");

              return;

          }

      }

      print_shortest_path(distance, path, used, start, end);

      return;

    }

    void print_shortest_path(int* distance,int* path,int* used,int start,int end){ // 輸出最短距離并打印最短路徑

      int i = 0, pre, inverse_path[N];

      char s1[3],s2[3];

      sprintf(s1, "V%d", (start+1));

      sprintf(s2, "V%d", (end+1));

      printf("從%s頂點到%s頂點的最短距離: %dn", s1,  s2, distance[end]);

      inverse_path[i] = end;

      pre = path[end];

      if(pre == -1){

          printf("沒有通路!n");

      }else{

          while(pre != start){

              inverse_path[++i] = pre;

              pre = path[pre];

          }

          inverse_path[++i] = start;

          printf("從%s頂點到%s頂點的最短路徑:n", s1, s2);

          for(; i > 0; i--){

              sprintf(s1, "V%d", (inverse_path[i]+1));

              printf("%s -> ", s1);

          }

          sprintf(s1, "V%d", (inverse_path[i]+1));

          printf("%sn", s1);

      }

      return;

    }

    如何求最短路徑(如何求最短路徑數(shù)據(jù)結構)

    如何求最短路徑(如何求最短路徑數(shù)據(jù)結構)

    如何求最短路徑(如何求最短路徑數(shù)據(jù)結構)

    如何求最短路徑(如何求最短路徑數(shù)據(jù)結構)

    如何求最短路徑(如何求最短路徑數(shù)據(jù)結構)

    四、求出最短路徑,要過程,用Dijkstra算法。。。

    從v1開始遍歷

    v2 = 2;

    v3 = 5;

    v2較小所以跳到v2

    v3 = 4;

    v4 = 6;

    v5 = 8;

    v3較小所以跳到v3

    v4 = 5;

    v6 = 7;

    v4較小所以跳到v4

    v6 = 6;

    v7 = 9;

    v6較小所以跳到v6

    v7 = 8;

    所以最后結果v1 -> v7最短路徑為v1->v2->v3->v4->v6->v7,最短路徑長度為8

    以上就是關于如何求最短路徑相關問題的回答。希望能幫到你,如有更多相關問題,您也可以聯(lián)系我們的客服進行咨詢,客服也會為您講解更多精彩的知識和內(nèi)容。


    推薦閱讀:

    企業(yè)如何做廣告(企業(yè)如何做廣告策劃)

    怎么被傳媒公司簽約(如何被傳媒公司簽約)

    公眾號是如何盈利的(公眾號是怎么盈利的)

    杭州排屋戶型(杭州排屋戶型圖片)

    抖音怎么找那些賣的(陌陌上說的600一次敢約嗎)