成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

七夕都怎么找和女神的最近距離?

開發(fā) 前端
對于Dijkstra算法,很多人可能感覺熟悉而又陌生,可能大部分人比較了解bfs和dfs,而對dijkstra和floyd算法可能知道大概是圖論中的某個(gè)算法,但是可能不清楚其中的作用和原理,又或許,你曾經(jīng)感覺它很難,那么,這個(gè)時(shí)候正適合你重新認(rèn)識它。

[[417618]]

本文轉(zhuǎn)載自微信公眾號「bigsai」,作者bigsai。轉(zhuǎn)載本文請聯(lián)系程序員bigsai公眾號。

前言

大家好,我是bigsai,今天給大家講講Dijkstra算法,下次拿著這個(gè)算法找女神少繞路,有女朋友的可以試試行不行的通。

對于Dijkstra算法,很多人可能感覺熟悉而又陌生,可能大部分人比較了解bfs和dfs,而對dijkstra和floyd算法可能知道大概是圖論中的某個(gè)算法,但是可能不清楚其中的作用和原理,又或許,你曾經(jīng)感覺它很難,那么,這個(gè)時(shí)候正適合你重新認(rèn)識它。

Dijkstra是啥?

其實(shí)Dijkstra(迪科斯徹)是一個(gè)人,被稱為結(jié)構(gòu)程序設(shè)計(jì)之父,他提出goto有害論、信號量、原語等,創(chuàng)造解決銀行家算法、哲學(xué)家進(jìn)餐問題、Dijkstra算法等等,在1972年獲得圖靈獎(計(jì)算機(jī)界諾?爾獎),今天咱們就學(xué)習(xí)Dijkstra算法。

Dijkstra算法干啥的?

Dijkstra是用來求單源最短路徑的,也就是在一個(gè)圖中,從一個(gè)點(diǎn)計(jì)算到達(dá)其他點(diǎn)的最短距離,再形象一點(diǎn),就是比如七夕你捧著鮮花去找女神,有點(diǎn)距離,在不堵?沒紅綠燈情況下怎么找到一條最短的路徑:

這不是一眼就能看出來嘛!還要什么算法?enum,如果路徑很多像這樣呢?

就拿上圖來說,如果各條路?度都已知,那么可以使用dijkstra算法計(jì)算你到圖中所有節(jié)點(diǎn)的最短距離(不過你想要的就是和女神的距離最近)。不過這個(gè)單源最短路徑你可能產(chǎn)生一些疑惑:

單源什么意思?

一個(gè)源頭,從一個(gè)頂點(diǎn)出發(fā),Dijkstra算法只能求一個(gè)頂點(diǎn)到其他點(diǎn)的最短距離而不能任意兩點(diǎn)。

和bfs求的最短路徑有什么區(qū)別?

bfs求的與其說是路徑,不如說是次數(shù)。因?yàn)閎fs他是按照隊(duì)列一次一次進(jìn)行加入相鄰的點(diǎn),而兩點(diǎn)之間沒有權(quán)值或者權(quán)值相等(代價(jià)相同)。bfs求最短路徑一般無權(quán)值路徑(只代表聯(lián)通性)或者權(quán)值相等,僅僅用次數(shù)就能表示路徑?短的情況,最典型的就是迷宮問題bfs搜索移動一次路徑為1就加一次。

Dijkstra在處理具體實(shí)例的應(yīng)用還是很多的,因?yàn)榫唧w的問題其實(shí)帶權(quán)更多一些。比如一個(gè)城市有多個(gè)鄉(xiāng)鎮(zhèn),鄉(xiāng)鎮(zhèn)可能有道路,也可能沒有,整個(gè)鄉(xiāng)鎮(zhèn)需要聯(lián)通,如果想計(jì)算每個(gè)鄉(xiāng)鎮(zhèn)到a鎮(zhèn)的最短路徑,那么Dijkstra就派上了用場。

算法分析

對于一個(gè)算法,首先要理解它的運(yùn)行流程,對于Dijkstra算法而言,首先要知道其適用條件和環(huán)境:

一個(gè)連通圖,若干節(jié)點(diǎn)(節(jié)點(diǎn)可能有數(shù)值),但是路徑一定有權(quán)值并且不能為負(fù)(否則Dijkstra就不適用)。

Dijkstra的核心思想是貪心算法的思想,那什么是貪心呢?

貪心算法(又稱貪婪算法)是指,在對問題求解時(shí),總是做出在當(dāng)前看來是最好的選擇。也就是說,不從整體最優(yōu)上加以考慮,他所

做出的是在某種意義上的局部最優(yōu)解。

貪心算法不是對所有問題都能得到整體最優(yōu)解,關(guān)鍵是貪心策略的選擇,選擇的貪心策略必須具備無后效性,即某個(gè)狀態(tài)以前的過程不會影響以后的狀態(tài),只與當(dāng)前狀態(tài)有關(guān)。

對于貪心算法,在很多情況都能用到,下面舉2個(gè)不恰當(dāng)?shù)睦?

1 .上學(xué)時(shí),每周只能帶5個(gè)蘋果,你想帶最多,那么選五個(gè)蘋果你每次都選最大的那個(gè)五次下來你就選的最重的那個(gè)。

2 .錢幣找零,指定幣值和相應(yīng)的數(shù)量,用最少的數(shù)量湊?某金額。利用貪心策略,優(yōu)先選擇面值大的錢幣,直到湊?總金額。

3 .活動選擇問題,知道多個(gè)活動開始時(shí)間、結(jié)束時(shí)間,想在一個(gè)時(shí)間內(nèi)參加最多活動,按照活動結(jié)束時(shí)間遞增排序即可。

上面的策略雖然沒有很強(qiáng)的理論數(shù)學(xué)依據(jù),或者不太好說明,更像一種事實(shí)規(guī)律經(jīng)驗(yàn),并且對于貪心問題具體處理上大部分都需要排序,還可能會遇到規(guī)則繁雜的類排序。那么我們的Dijkstra是如何貪心的呢?對于一個(gè)點(diǎn),求圖中所有點(diǎn)的最短路徑,如果沒有正確的方法胡亂想確實(shí)很難算出來,并且如果暴力匹配復(fù)雜度呈指數(shù)級上升不適合解決實(shí)際問題。那么我們該怎么想呢?

首先,Dijkstra算法實(shí)現(xiàn)上需要這些前提:

  • Dijkstra處理的是帶正權(quán)值的有權(quán)圖,那么就需要一個(gè)二維數(shù)組(如果空間大用List數(shù)組)存儲各個(gè)點(diǎn)到點(diǎn)之間邊的權(quán)值大小 (鄰接矩陣或者鄰接表存儲) ,各個(gè)點(diǎn)距離初始化為無窮大。
  • 需要一個(gè)boolean數(shù)組判斷哪些點(diǎn)已經(jīng)確定最短?度路徑,那些點(diǎn)沒有確定。用一個(gè) int數(shù)組記錄距離(在算法執(zhí)行過程有些點(diǎn)最短路徑可能被多次更新)。
  • 需要優(yōu)先隊(duì)列加入已經(jīng)確定點(diǎn)的周圍點(diǎn)。每次拋出從起點(diǎn)最短路徑的那個(gè)點(diǎn),直到所有點(diǎn)路徑確定最短為止。

簡單的概括流程為:

第一步一般從選定點(diǎn)開始拋入優(yōu)先隊(duì)列(路徑一般為0),boolean數(shù)組標(biāo)記0的位置(最短為0) , 然后0周圍連通的點(diǎn)拋入優(yōu)先隊(duì)列中(可能是node類),并把各個(gè)點(diǎn)的距離記錄到對應(yīng)數(shù)組內(nèi),此時(shí)周圍點(diǎn)只是等待調(diào)度可能是最短距離,也可能被更新。(如果小于就更新,大于就不動,初始第一次是無窮肯定會更新),第一次就結(jié)束了。

從等待調(diào)度隊(duì)列中拋出距離最近的那個(gè)點(diǎn)B(第一次就是0周圍鄰居)。這個(gè)點(diǎn)距離一定是最近可以確定的(所有權(quán)值都是正的,點(diǎn)的距離只能越來越?,而它的路徑是所有可能中的最小的)標(biāo)記這個(gè)點(diǎn)為true表示已經(jīng)確定,并且將這個(gè)點(diǎn)的鄰居加入隊(duì)列(下一次等待調(diào)度點(diǎn)為隊(duì)列中原有的和這個(gè)點(diǎn)周圍未確定的鄰居),并同時(shí)判斷是否更新B點(diǎn)鄰居?度,如果小于則更新!

重復(fù)二的操作,直到所有點(diǎn)都確定。

算法實(shí)現(xiàn)

代碼實(shí)現(xiàn)上面有些繁瑣,但是也不是很復(fù)雜,這里給個(gè)Dijkstra算法實(shí)現(xiàn)代碼:

  1. package 圖論; 
  2.  
  3. import java.util.ArrayDeque; 
  4. import java.util.Comparator; 
  5. import java.util.PriorityQueue; 
  6. import java.util.Queue; 
  7. import java.util.Scanner; 
  8.  
  9. public class dijkstra { 
  10.     static class node 
  11.     { 
  12.         int x; //節(jié)點(diǎn)編號 
  13.         int lenth;//長度 
  14.         public node(int x,int lenth) { 
  15.             this.x=x; 
  16.             this.lenth=lenth; 
  17.         } 
  18.     } 
  19.  
  20.     public static void main(String[] args) { 
  21.  
  22.         int[][] map = new int[6][6];//記錄權(quán)值,順便記錄鏈接情況,可以考慮附加鄰接表 
  23.         initmap(map);//初始化 
  24.         boolean bool[]=new boolean[6];//判斷是否已經(jīng)確定 
  25.         int len[]=new int[6];//長度 
  26.         for(int i=0;i<6;i++) 
  27.         { 
  28.             len[i]=Integer.MAX_VALUE; 
  29.         } 
  30.         Queue<node>q1=new PriorityQueue<node>(com); 
  31.         len[0]=0;//從0這個(gè)點(diǎn)開始 
  32.         q1.add(new node(0, 0)); 
  33.         int count=0;//計(jì)算執(zhí)行了幾次dijkstra 
  34.         while (!q1.isEmpty()) { 
  35.             node t1=q1.poll(); 
  36.             int index=t1.x;//節(jié)點(diǎn)編號 
  37.             int length=t1.lenth;//節(jié)點(diǎn)當(dāng)前點(diǎn)距離 
  38.             bool[index]=true;//拋出的點(diǎn)確定 
  39.             count++;//其實(shí)執(zhí)行了6次就可以確定就不需要繼續(xù)執(zhí)行了  這句可有可無,有了減少計(jì)算次數(shù) 
  40.             for(int i=0;i<map[index].length;i++) 
  41.             { 
  42.                 if(map[index][i]>0&&!bool[i]) 
  43.                 { 
  44.                     node node=new node(i, length+map[index][i]); 
  45.                     if(len[i]>node.lenth)//需要更新節(jié)點(diǎn)的時(shí)候更新節(jié)點(diǎn)并加入隊(duì)列 
  46.                     { 
  47.                         len[i]=node.lenth; 
  48.                         q1.add(node); 
  49.                     } 
  50.                 } 
  51.             } 
  52.         }        
  53.         for(int i=0;i<6;i++) 
  54.         { 
  55.             System.out.println(len[i]); 
  56.         } 
  57.     } 
  58.     static Comparator<node>com=new Comparator<node>() { 
  59.  
  60.         public int compare(node o1, node o2) { 
  61.             return o1.lenth-o2.lenth; 
  62.         } 
  63.     }; 
  64.  
  65.     private static void initmap(int[][] map) { 
  66.         map[0][1]=2;map[0][2]=3;map[0][3]=6; 
  67.         map[1][0]=2;map[1][4]=4;map[1][5]=6; 
  68.         map[2][0]=3;map[2][3]=2; 
  69.         map[3][0]=6;map[3][2]=2;map[3][4]=1;map[3][5]=3; 
  70.         map[4][1]=4;map[4][3]=1; 
  71.         map[5][1]=6;map[5][3]=3;     
  72.     } 

當(dāng)然,dijkstra算法比較靈活,實(shí)現(xiàn)方式也可能有點(diǎn)區(qū)別,但是思想是不變的:一個(gè)貪心思路。dijkstra執(zhí)行一次就能夠確定一個(gè)點(diǎn),所以只需要執(zhí)行點(diǎn)的總和次數(shù)即可完成整個(gè)算法。

一句話概況一下,就是從一個(gè)點(diǎn)開始找周圍最短的一個(gè),更新相應(yīng)數(shù)據(jù),再找已經(jīng)確定直接連接的第二個(gè)最短點(diǎn)、第三個(gè)一直到所有點(diǎn)確定,dijkstra算法就完成了。

 

責(zé)任編輯:武曉燕 來源: bigsai
相關(guān)推薦

2023-11-27 17:03:45

syncGo

2022-02-28 19:32:27

I/O磁盤

2015-01-19 09:13:39

CloudStack云計(jì)算架構(gòu)虛擬機(jī)管理

2011-03-02 15:10:43

國產(chǎn)數(shù)據(jù)庫

2010-10-07 20:57:37

2013-04-23 09:15:59

Windows 8.1

2015-06-04 16:35:00

2023-08-22 21:39:25

2011-05-06 15:28:00

SMB數(shù)據(jù)中心

2009-09-29 11:23:53

互聯(lián)網(wǎng)

2021-08-23 10:49:02

鴻蒙HarmonyOS應(yīng)用

2013-07-16 14:36:43

天河2號超級計(jì)算機(jī)國防科技大學(xué)

2021-08-20 14:26:17

鴻蒙HarmonyOS應(yīng)用

2019-04-30 10:08:22

Windows 功能系統(tǒng)

2018-03-05 08:56:10

物聯(lián)網(wǎng)無線通信終端設(shè)備

2023-11-29 11:28:21

智能視覺

2022-03-21 18:27:38

Linux計(jì)算機(jī)函數(shù)

2017-09-19 12:08:13

Google

2012-08-24 10:49:51

備份恢復(fù)

2021-08-23 11:03:54

鴻蒙HarmonyOS應(yīng)用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 精品久久久一区二区 | 99久久中文字幕三级久久日本 | 国产精品久久国产精品 | 黄色片免费看 | h视频亚洲 | 99在线观看视频 | av网站推荐 | 国产精品久久777777 | 国产乱码精品一区二区三区忘忧草 | 一区二区高清在线观看 | 精品伊人 | 国产综合视频 | 天啪| 国产精品视频二区三区 | 九九久久久 | 久久久久久九九九九 | 精品国产不卡一区二区三区 | 男女羞羞在线观看 | 一区二区日韩 | 欧美一级二级三级视频 | 国产精品久久久久一区二区 | 午夜视频一区 | 青青草国产在线观看 | 伊人免费网 | 精品久久久久久久久久久 | 激情黄色在线观看 | 久久精品欧美一区二区三区麻豆 | 欧美日韩在线精品 | 日韩精品在线播放 | 在线一区观看 | 九九九视频精品 | 国产在线视频网 | 午夜成人免费视频 | 成人午夜网站 | 国产高潮好爽受不了了夜色 | 日韩一二三| 欧美一区二区三区在线免费观看 | 俺去俺来也www色官网cms | 亚洲精品黄| 精品在线看 | 日韩欧美一区在线 |