當前位置:首頁 » 操作系統 » 演算法找東西

演算法找東西

發布時間: 2023-01-28 18:34:11

1. 高分求演算法:尋找與特定對象距離最近的對象

用現在的ID,X,Y三個元素來找最近點的話無論什麼辦法,都至少要與每個點進行一次距離的判斷,比較X或者Y也好,計算距離(當然這個距離是不用開平方的,與其他所有點的距離都不開平方也能比較相對的距離長短)也好,所以如果只有這三個元素的話,其實再怎麼改也不會有太大的優化的。

最好還是添加一些輔助信息,比較常用的就是以劃分網格的方法,將所有點分派在不同的網格中,然後以網格為基礎找最近點,這樣的話就要加一個網格的結構(以空間換時間),裡面存放的就是屬於這個網格的點的ID,通過編號規則可以很快的找最近的網格,然後再找裡面的點,這樣可以提高點查找速度。

呵呵,不好意思,沒想清楚就寫了:P,改一下,改一下,再加一步就好了

1.給點添加一個所屬網格的信息:
Class A
{
public int ID;
public int X;
public int Y;
publci int Index;//所屬網格編號
}
2.構造一個點鏈表,這是為了減少空間和方便處理而加的,後面的演算法里會感覺到用處
(為每個點對象建立一個點鏈表節點)
Class I
{
public A *pAObject; //指向一個點對象
publci I *pNextA; //指向下一個
}
3.構件一個網格信息結構
Class G
{
public int ID; //網格編號
public I *pAObjects; //指向一個點鏈表(至於這個是帶頭節點還是不帶頭節點的都一樣啦)
//這里用鏈表比較好
//第一,因為點可移動,那麼點對象個數可以隨意,可以發揮鏈表的擴展性
//第二,不需要取中間節點,也就沒有用到數組的長處
}
4.構建網格,比如以1000為長度(長度可以自己定義,關鍵是平衡空間和速度關系),建立正方形的網格,那麼(0,0)到(1000000,1000000)就是有1000*1000個網格(在給網格編號的時候最好有規律,那麼就能通過List或者其他數組容器的下標來獲得網格信息)
5.添加點的時候,先判斷屬於哪個網格,然後在點信息中添加網格編號,同時構建對應的點鏈表節點,並添加到所屬網格的鏈表中
6.最後就是查詢點了,首先獲得出發點中的所屬網格信息,看這個網格中是否有其他點:有,則一個個的判斷距離(距離的平方),那麼最近點一定在這些點裡面(如果點還是太多,那麼就考慮縮小網格的范圍);沒有,那就找所屬網格周邊8個網格中是否有點,有,則再找最近點,沒有就再往外擴(如果感覺網格太多,可以加大網格的范圍)
7.以找到的最近點到出發點的距離為基準,看看出發點到周邊網格在這個距離內會接觸到的(沒有在6中遍歷過的)有幾個網格,把這些網格中的點再查看有沒有更近的就行了

注:
1.如果還要優化就是加大網格的層次,可以用多層網格,這就會更復雜一點
2.在網格信息結構(G)中,因為點會移動,那麼刪點鏈表節點會有一個查找過程,如果覺得這個慢,那麼就在點對象結構體中加一個所屬點鏈表的指針:
class I;
Class A
{
public int ID;
public int X;
public int Y;
publci int Index;//所屬網格編號
publci I *pI;
}
....

呵呵,看了lipai006的回答,想了下似乎也是可以實現的,只要多花點內存就可以達到比較好的速度了,而且也不需要真的從X坐標出發這樣慢慢的以扇形擴展了啦,通過做一些輔助結構,就直接可以從出發點的X坐標出發,找同X不同Y中Y坐標與出發點最近的就行啦,循環結束條件就是X的擴展距離已經大於當前最小距離,因為再往外也肯定比當前最小距離大了。這個方法也就是要更復雜一些的輔助結構做索引,添加點的時候也要多做些事情,而且實現上的代碼相對網格方法復雜一些,但查找速度應該比網格會快一點,因為畢竟是直接找點去了,其實網格方法就是把一批點的X,Y坐標看成是一樣的,這樣先過濾一批而已,是個速度與復雜度的折中。

xx_lzj:劃分區域的目的就是為了使每個區域內的點不能太多,根據我的結構,每個區域有沒有點,一個bool判斷就夠了,不會存在太稀疏影響效率的事情,不過最壞的情況的確會退化到遍歷整個點空間,所以這個方法的時間復雜度仍然是O(n)。
你的方法其實和lipai006說的原理是差不多的(如果我對你們鏈表結構的猜想准確的話),無非就是通過X,Y坐標形成一個二維雙向鏈表,在形成這個鏈表的過程會比網格相對復雜一點,而且也不是像你想的只要判斷8個點就夠的,當只有一個點在中間,其他點分布成以這個點為圓心的圓周上時,按照貼主的要求,難道只有8個最近點嗎??在這個情況下,你的最壞復雜度還是O(n),但就如我說過的,這個方法的平均時間復雜度在參數上是會比網格的低一點,但是演算法本身的代碼復雜度上會高一點,而且在插入點的過程中的時間消耗會大一點而已。我覺得這是一個整體的過程,不能為了查找的快速犧牲太多其他的時間。
*************
xx_lzj:不好意思,你的鏈表我還有些不明白的地方:1.二維雙向鏈表每個節點有4個指針,你能否把這4個指針如何獲得的說一下,最好不要取邊界線上的點,取中間的一個點進行介紹。2.對於初始化和修改點坐標的時候,現有數據如果是鏈表結構(不是數組),如何能不依靠其他輔助數據進行折半查找?3.修改某個點坐標之後,根據你的鏈表結構,我感覺不是刪除、插入節點這么簡單的,能不能具體點說明。

2. 常見查找和排序演算法

查找成功最多要n 次,平均(n+1)/2次, 時間復雜度為O(n)
優點:既適用順序表也適用單鏈表,同時對表中元素順序無要求,給插入帶來方便,只需插入表尾即可。
缺點:速度較慢。

改進:在表尾設置一個崗哨,這樣不用去循環判斷數組下標是否越界,因為最後必然成立。

適用條件:

二分查找的判定樹不僅是二叉排序樹,而且是一棵理想平衡樹。 時間復雜度為O(lbn)

循環實現

遞歸實現

待排序的元素需要實現 Java 的 Comparable 介面,該介面有 compareTo() 方法,可以用它來判斷兩個元素的大小關系。

從數組中選擇最小元素,將它與數組的第一個元素交換位置。再從數組剩下的元素中選擇出最小的元素,將它與數組的第二個元素交換位置。不斷進行這樣的操作,直到將整個數組排序。

選擇排序需要 ~N2/2 次比較和 ~N 次交換,==它的運行時間與輸入無關==,這個特點使得它對一個已經排序的數組也需要這么多的比較和交換操作。

從左到右不斷 交換相鄰逆序的元素 ,在一輪的循環之後,可以讓未排序的最大元素上浮到右側。

在一輪循環中,如果沒有發生交換,那麼說明數組已經是有序的,此時可以直接退出。

每次都 將當前元素插入到左側已經排序的數組中 ,使得插入之後左側數組依然有序。

對於數組 {3, 5, 2, 4, 1},它具有以下逆序:(3, 2), (3, 1), (5, 2), (5, 4), (5, 1), (2, 1), (4, 1),插入排序每次只能交換相鄰元素,令逆序數量減少 1,因此插入排序需要交換的次數為逆序數量。

==插入排序的時間復雜度取決於數組的初始順序,如果數組已經部分有序了,那麼逆序較少,需要的交換次數也就較少,時間復雜度較低==。

對於大規模的數組,插入排序很慢,因為它只能交換相鄰的元素,每次只能將逆序數量減少 1。希爾排序的出現就是為了解決插入排序的這種局限性,它通過交換不相鄰的元素,每次可以將逆序數量減少大於 1。

希爾排序使用插入排序對間隔 h 的序列進行排序。通過不斷減小 h,最後令 h=1,就可以使得整個數組是有序的。

希爾排序的運行時間達不到平方級別,使用遞增序列 1, 4, 13, 40, ... 的希爾排序所需要的比較次數不會超過 N 的若干倍乘於遞增序列的長度。後面介紹的高級排序演算法只會比希爾排序快兩倍左右。

歸並排序的思想是將數組分成兩部分,分別進行排序,然後歸並起來。

歸並方法將數組中兩個已經排序的部分歸並成一個。

將一個大數組分成兩個小數組去求解。

因為每次都將問題對半分成兩個子問題,這種對半分的演算法復雜度一般為 O(NlogN)。

先歸並那些微型數組,然後成對歸並得到的微型數組。

取 a[l] 作為切分元素,然後從數組的左端向右掃描直到找到第一個大於等於它的元素,再從數組的右端向左掃描找到第一個小於它的元素,交換這兩個元素。不斷進行這個過程,就可以保證左指針 i 的左側元素都不大於切分元素,右指針 j 的右側元素都不小於切分元素。當兩個指針相遇時,將切分元素 a[l] 和 a[j] 交換位置。

快速排序是原地排序,不需要輔助數組,但是遞歸調用需要輔助棧。

快速排序最好的情況下是每次都正好將數組對半分,這樣遞歸調用次數才是最少的。這種情況下比較次數為 CN=2CN/2+N,復雜度為 O(NlogN)。

最壞的情況下,第一次從最小的元素切分,第二次從第二小的元素切分,如此這般。因此最壞的情況下需要比較 N2/2。為了防止數組最開始就是有序的,在進行快速排序時需要隨機打亂數組。

因為快速排序在小數組中也會遞歸調用自己,對於小數組,插入排序比快速排序的性能更好,因此在小數組中可以切換到插入排序。

最好的情況下是每次都能取數組的中位數作為切分元素,但是計算中位數的代價很高。一種折中方法是取 3 個元素,並將大小居中的元素作為切分元素。

對於有大量重復元素的數組,可以將數組切分為三部分,分別對應小於、等於和大於切分元素。

三向切分快速排序對於有大量重復元素的隨機數組可以在線性時間內完成排序。

快速排序的 partition() 方法,會返回一個整數 j 使得 a[l..j-1] 小於等於 a[j],且 a[j+1..h] 大於等於 a[j],此時 a[j] 就是數組的第 j 大元素。

可以利用這個特性找出數組的第 k 大的元素。

該演算法是線性級別的,假設每次能將數組二分,那麼比較的總次數為 (N+N/2+N/4+..),直到找到第 k 個元素,這個和顯然小於 2N。

堆中某個節點的值總是大於等於其子節點的值,並且堆是一顆完全二叉樹。

堆可以用數組來表示,這是因為堆是完全二叉樹,而完全二叉樹很容易就存儲在數組中。位置 k 的節點的父節點位置為 k/2,而它的兩個子節點的位置分別為 2k 和 2k+1。這里不使用數組索引為 0 的位置,是為了更清晰地描述節點的位置關系。

在堆中,當一個節點比父節點大,那麼需要交換這個兩個節點。交換後還可能比它新的父節點大,因此需要不斷地進行比較和交換操作,把這種操作稱為上浮。

類似地,當一個節點比子節點來得小,也需要不斷地向下進行比較和交換操作,把這種操作稱為下沉。一個節點如果有兩個子節點,應當與兩個子節點中最大那個節點進行交換。

將新元素放到數組末尾,然後上浮到合適的位置。

從數組頂端刪除最大的元素,並將數組的最後一個元素放到頂端,並讓這個元素下沉到合適的位置。

把最大元素和當前堆中數組的最後一個元素交換位置,並且不刪除它,那麼就可以得到一個從尾到頭的遞減序列,從正向來看就是一個遞增序列,這就是堆排序。

一個堆的高度為logN,因此在堆中插入元素和刪除最大元素的復雜度都為 logN。

對於堆排序,由於要對 N 個節點進行下沉操作,因此復雜度為 NlogN。

堆排序是一種原地排序,沒有利用額外的空間。

現代操作系統很少使用堆排序,因為它無法利用局部性原理進行緩存,也就是數組元素很少和相鄰的元素進行比較和交換。

計數排序的核心在於將輸入的數據值轉化為鍵存儲在額外開辟的數組空間中。作為一種線性時間復雜度的排序,==計數排序要求輸入的數據必須是有確定范圍的整數==。

當輸入的元素是 n 個 0 到 k 之間的整數時,它的==運行時間是 O(n + k)==。計數排序不是比較排序,排序的速度快於任何比較排序演算法。由於用來計數的數組C的長度取決於待排序數組中數據的范圍(等於待排序數組的最大值與最小值的差加上1),這使得計數排序對於數據范圍很大的數組,需要大量時間和內存。比較適合用來排序==小范圍非負整數數組的數組==。

桶排序是計數排序的升級版。它利用了函數的映射關系,高效與否的關鍵就在於這個映射函數的確定。為了使桶排序更加高效,我們需要做到這兩點:

同時,對於桶中元素的排序,選擇何種比較排序演算法對於性能的影響至關重要。

當輸入數據均勻分配到每一個桶時最快,當都分配到同一個桶時最慢。

實間復雜度N*K

快速排序是最快的通用排序演算法,它的內循環的指令很少,而且它還能利用緩存,因為它總是順序地訪問數據。它的運行時間近似為 ~cNlogN,這里的 c 比其它線性對數級別的排序演算法都要小。

使用三向切分快速排序,實際應用中可能出現的某些分布的輸入能夠達到線性級別,而其它排序演算法仍然需要線性對數時間。

3. 目標檢測演算法圖解:一文看懂RCNN系列演算法

姓名:王咫毅

學號:19021211150

【嵌牛導讀】CNN如此風靡,其衍生演算法也是層出不窮,各種衍生演算法也可以應用於各種應用場景,各類場合。本文則是了解每個衍生演算法的各個使用場景、原理及方法。

【嵌牛鼻子】RCNN 目標檢測

【嵌牛提問】RCNN系列演算法有何區別和聯系?

【嵌牛正文】

在生活中,經常會遇到這樣的一種情況,上班要出門的時候,突然找不到一件東西了,比如鑰匙、手機或者手錶等。這個時候一般在房間翻一遍各個角落來尋找不見的物品,最後突然一拍大腦,想到在某一個地方,在整個過程中有時候是很著急的,並且越著急越找不到,真是令人沮喪。但是,如果一個簡單的計算機演算法可以在幾毫秒內就找到你要找的物品,你的感受如何?是不是很驚奇!這就是對象檢測演算法(object detection)的力量。雖然上述舉的生活例子只是一個很簡單的例子,但對象檢測的應用范圍很廣,跨越多個不同的行業,從全天候監控到智能城市的實時車輛檢qian測等。簡而言之,物體檢測是強大的深度學習演算法中的一個分支。

在本文中,我們將深入探討可以用於對象檢測的各種演算法。首先從屬於RCNN系列演算法開始,即RCNN、 Fast RCNN和 Faster RCNN。在之後的文章中,將介紹更多高級演算法,如YOLO、SSD等。

1.解決對象檢測任務的簡單方法(使用深度學習)

下圖說明了對象檢測演算法是如何工作。圖像中的每個對象,從人到風箏都以一定的精度進行了定位和識別。

下面從最簡單的深度學習方法開始,一種廣泛用於檢測圖像中的方法——卷積神經網路(CNN)。如果讀者對CNN演算法有點生疏,建議 閱讀此文 。

這里僅簡要總結一下CNN的內部運作方式:

首先將圖像作為輸入傳遞到網路,然後通過各種卷積和池化層處理,最後以對象類別的形式獲得輸出。

對於每個輸入圖像,會得到一個相應的類別作為輸出。因此可以使用這種技術來檢測圖像中的各種對象。

1.首先,將圖像作為輸入;

2.然後,將圖像分成不同的區域;

3.然後,將每個區域視為單獨的圖像;

4.將所有這些區域傳遞給CNN並將它們分類為各種類別;

5.一旦將每個區域劃分為相應的類後,就可以組合所有這些區域來獲取具有檢測到的對象的原始圖像:

使用這種方法會面臨的問題在於,圖像中的對象可以具有不同的寬高比和空間位置。例如,在某些情況下,對象可能覆蓋了大部分圖像,而在其他情況下,對象可能只覆蓋圖像的一小部分,並且對象的形狀也可能不同。

基於此,需要劃分大量的區域,這會花費大量的計算時間。因此,為了解決這個問題並減少區域數量,可以使用基於區域的CNN,它使用提議方法選擇區域。

2.基於區域的卷積神經網路

2.1 RCNN的思想

RCNN演算法不是在大量區域上工作,而是在圖像中提出了一堆方框,並檢查這些方框中是否包含任何對象。RCNN 使用選擇性搜索從圖像中提取這些框。

下面介紹選擇性搜索以及它如何識別不同的區域。基本上四個區域形成一個對象:不同的比例、顏色、紋理和形狀。選擇性搜索在圖像中識別這些模式,並基於此提出各種區域。以下是選擇性搜索如何工作的簡要概述:

首先, 將圖像作為輸入:

然後,它生成初始子分段,以便獲得多個區域:

之後,該技術組合相似區域以形成更大的區域(基於顏色相似性、紋理相似性、尺寸相似性和形狀兼容性):

最後,這些區域產生最終的對象位置(感興趣的區域);

下面是RCNN檢測對象所遵循的步驟的簡要總結:

1.首先採用預先訓練的卷積神經網路;

2.重新訓練該模型模型——根據需要檢測的類別數量來訓練網路的最後一層(遷移學習);

3.第三步是獲取每個圖像的感興趣區域。然後,對這些區域調整尺寸,以便其可以匹配CNN輸入大小;

4.獲取區域後,使用SVM演算法對對象和背景進行分類。對於每個類,都訓練一個二分類SVM;

最後,訓練線性回歸模型,為圖像中每個識別出的對象生成更嚴格的邊界框;

[對上述步驟進行圖解分析]( http://www.robots.ox.ac.uk/~tvg/publications/talks/Fast-rcnn-slides.pdf ):

首先,將圖像作為輸入:

然後,使用一些提議方法獲得感興趣區域(ROI)(例如,選擇性搜索):

之後,對所有這些區域調整尺寸,並將每個區域傳遞給卷積神經網路:

然後,CNN為每個區域提取特徵,SVM用於將這些區域劃分為不同的類別:

最後,邊界框回歸(Bbox reg)用於預測每個已識別區域的邊界框:

以上就是RCNN檢測物體的全部流程。

2.2 RCNN的問題

從上節內容可以了解到RCNN是如何進行對象檢測的,但這種技術有其自身的局限性。以下原因使得訓練RCNN模型既昂貴又緩慢:

基於選擇性搜索演算法為每個圖像提取2,000個候選區域;

使用CNN為每個圖像區域提取特徵;

RCNN整個物體檢測過程用到三種模型:

CNN模型用於特徵提取;

線性svm分類器用於識別對象的的類別;

回歸模型用於收緊邊界框;

這些過程相結合使得RCNN非常慢,對每個新圖像進行預測需要大約40-50秒,這實際上使得模型在面對巨大的數據集時變得復雜且幾乎不可能應用。

好消息是存在另一種物體檢測技術,它解決了RCNN中大部分問題。

3.了解Fast RCNN

3.1Fast RCNN的思想

RCNN的提出者Ross Girshick提出了這樣的想法,即每個圖像只運行一次CNN,然後找到一種在2,000個區域內共享該計算的方法。在Fast RCNN中,將輸入圖像饋送到CNN,CNN生成卷積特徵映射。使用這些特徵圖提取候選區域。然後,使用RoI池化層將所有建議的區域重新整形為固定大小,以便將其饋送到全連接網路中。

下面將其分解為簡化概念的步驟:

1.首先將圖像作為輸入;

2.將圖像傳遞給卷積神經網路,生成感興趣的區域;

3.在所有的感興趣的區域上應用RoI池化層,並調整區域的尺寸。然後,每個區域被傳遞到全連接層的網路中;

4.softmax層用於全連接網以輸出類別。與softmax層一起,也並行使用線性回歸層,以輸出預測類的邊界框坐標。

因此,Fast RCNN演算法中沒有使用三個不同的模型,而使用單個模型從區域中提取特徵,將它們分成不同的類,並同時返回所標識類的邊界框。

對上述過程進行可視化講解:

將圖像作為輸入:

將圖像傳遞給卷積神經網路t,後者相應地返回感興趣的區域:

然後,在提取的感興趣區域上應用RoI池層,以確保所有區域具有相同的大小:

最後,這些區域被傳遞到一個全連接網路,對其進行分類,並同時使用softmax和線性回歸層返回邊界框:

上述過程說明了Fast RCNN是如何解決RCNN的兩個主要問題,即將每個圖像中的1個而不是2,000個區域傳遞給卷積神經網路,並使用一個模型來實現提取特徵、分類和生成邊界框。

3.2Fast RCNN的問題

Fast RCNN也存在一定的問題,它仍然使用選擇性搜索作為查找感興趣區域的提議方法,這是一個緩慢且耗時的過程,每個圖像檢測對象大約需要2秒鍾。

因此,又開發了另一種物體檢測演算法——Faster RCNN。

4.了解Faster RCNN

4.1. Faster RCNN的思想

Faster RCNN是Fast RCNN的修改版本,二者之間的主要區別在於,Fast RCNN使用選擇性搜索來生成感興趣區域,而Faster RCNN使用「區域提議網路」,即RPN。RPN將圖像特徵映射作為輸入,並生成一組提議對象,每個對象提議都以對象分數作為輸出。

以下步驟通常採用Faster RCNN方法:

1.將圖像作為輸入並將其傳遞給卷積神經網路,後者返回該圖像的特徵圖;

2.在這些特徵圖上應用RPN,返回提議對象及其分數;

3.在這些提議對象上應用RoI池層,以將所有提案降低到相同的大小;

4.最後,將提議傳遞到全連接層,該層在其頂部具有softmax層和線性回歸層,以對對象的邊界框進行分類和輸出;

這里簡要解釋一下RPN是如何運作的:

首先,Faster RCNN從CNN獲取特徵圖並將它們傳遞到區域提議網路。RPN在這些特徵圖上使用滑動窗口,每個窗口生成不同形狀和大小的k個方框( Anchor boxe):

方框是固定尺寸的邊界箱,具有不同的形狀和尺寸。對於每個方框,RPN預測兩件事:

預測錨是對象的概率;

用於邊界框回歸器調整錨點以更好地適合物體的形狀;

在有了不同形狀和大小的邊界框後,將其傳遞到RoI池層。對每個提案並對其進行裁剪,以便每個提案都包含一個對象。這就是RoI池層所做的事情,它為每個方框提取固定大小的特徵圖:

然後將這些特徵圖傳遞到全連接層,該層具有softmax和線性回歸層,最終對對象進行分類並預測已識別對象的邊界框。

4.2Faster RCNN的問題

上述討論過的所有對象檢測演算法都使用區域來識別對象,且網路不會一次查看完整圖像,而是按順序關注圖像的某些部分,這樣會帶來兩個復雜性的問題:

該演算法需要多次通過單個圖像來提取到所有對象;

由於不是端到端的演算法,不同的系統一個接一個地工作,整體系統的性能進一步取決於先前系統的表現效果。

鏈接: https://www.jianshu.com/p/51fc039ae7a4

4. 找零錢問題的貪心演算法

問題描述:
當前有面值分別為2角5分,1角,5分,1分的硬幣,請給出找n分錢的最佳方案(要求找出的硬幣數目最少)
問題分析:
根據常識,我們到店裡買東西找錢時,老闆總是先給我們最大面值的,要是不夠再找面值小一點的,直到找滿為止。如果老闆都給你找分數的或者幾角的,那你肯定不幹,另外,他也可能沒有那麼多零碎的錢給你找。其實這就是一個典型的貪心選擇問題。
問題的演算法設計與實現:
先舉個例子,假如老闆要找給我99分錢,他有上面的面值分別為25,10,5,1的硬幣數,為了找給我最少的硬幣數,那麼他是不是該這樣找呢,先看看該找多少個25分的, 99/25=3,好像是3個,要是4個的話,我們還得再給老闆一個1分的,我不幹,那麼老闆只能給我3個25分,由於還少給我24,所以還得給我2個10分的和4個1分。
具體實現
//找零錢演算法
//By falcon
//輸入:數組m,依次存放從大到小排列的面值數,n為需要找的錢數,單位全部為分
//輸出:數組num,對照數組m中的面值存放不同面值的硬幣的個數,即找錢方案

5. 常見演算法5、廣度優先搜索 Breadth-First Search

1、定義

廣度優先搜索 (Breadth-First Search)是最簡便的圖的搜索演算法之一,又稱 寬度優先搜索 ,這一演算法也是很多重要的圖演算法的原型。廣度優先搜索屬於一種盲目搜尋法,目的是系統地展開並檢查圖中的所有節點,以找尋結果。換句話說,它並不考慮結果的可能位置,徹底地搜索整張圖,直到找到結果為止。

2、應用

廣度優先搜索被用於解決 最短路徑問題(shortest-path problem)

廣度優先搜索讓你能夠找出兩樣東西之間的最短距離,不過最短距離的含義有很多!使用廣度優先搜索可以:

3、圖簡介

既然廣度優先搜索是作用於圖的一種演算法,這里對圖作一個簡單的介紹,先不深入了解。

圖由 節點 組成。一個節點可能與多個節點相連,這些節點被稱為鄰居。

廣度優先演算法的核心思想是:從初始節點開始,應用算符生成第一層節點,檢查目標節點是否在這些後繼節點中,若沒有,再用產生式規則將所有第一層的節點逐一擴展,得到第二層節點,並逐一檢查第二層節點中是否包含目標節點。若沒有,再用算符逐一擴展第二層的所有節點……,如此依次擴展,檢查下去,直到發現目標節點為止。即

廣度優先搜索使用隊列(queue)來實現,整個過程也可以看做一個倒立的樹形。

例:假如你需要在你的人際關系網中尋找是否有職業為醫生的人,圖如下:

而使用廣度優先搜索工作原理大概如下 :

1、Python 3 :

2、php

1、《演算法圖解》 https://www.manning.com/books/grokking-algorithms
2、SplQueue類: https://www.php.net/manual/zh/class.splqueue.php

6. 幾種常見的查找演算法之比較

二分法平均查找效率是O(logn),但是需要數組是排序的。如果沒有排過序,就只好先用O(nlogn)的預處理為它排個序了。而且它的插入比較困難,經常需要移動整個數組,所以動態的情況下比較慢。

哈希查找理想的插入和查找效率是O(1),但條件是需要找到一個良好的散列函數,使得分配較為平均。另外,哈希表需要較大的空間,至少要比O(n)大幾倍,否則產生沖突的概率很高。

二叉排序樹查找也是O(logn)的,關鍵是插入值時需要做一些處理使得它較為平衡(否則容易出現輕重的不平衡,查找效率最壞會降到O(n)),而且寫起來稍微麻煩一些,具體的演算法你可以隨便找一本介紹數據結構的書看看。當然,如果你用的是c語言,直接利用它的庫類型map、multimap就可以了,它是用紅黑樹實現的,理論上插入、查找時間都是O(logn),很方便,不過一般會比自己實現的二叉平衡樹稍微慢一些。

熱點內容
源碼和千鋒 發布:2025-09-17 10:58:53 瀏覽:24
memcache資料庫 發布:2025-09-17 10:23:01 瀏覽:67
安卓機如何鎖軟體 發布:2025-09-17 10:18:34 瀏覽:945
二手3系買哪個配置好 發布:2025-09-17 10:07:16 瀏覽:740
sqlserver2000xp 發布:2025-09-17 09:36:19 瀏覽:829
c9什麼時候升級安卓70 發布:2025-09-17 09:35:36 瀏覽:211
速演算法中 發布:2025-09-17 09:30:50 瀏覽:380
怎麼進網站伺服器 發布:2025-09-17 09:18:15 瀏覽:464
小火箭伺服器訂閱是什麼 發布:2025-09-17 09:01:40 瀏覽:738
c語言入門基礎 發布:2025-09-17 08:54:30 瀏覽:670