最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SPFA 算法實(shí)例講解

 更新時(shí)間:2017年07月14日 08:51:54   投稿:jingxian  
下面小編就為大家?guī)?lái)一篇SPFA 算法實(shí)例講解。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧

適用范圍:給定的圖存在負(fù)權(quán)邊,這時(shí)類似Dijkstra等算法便沒有了用武之地,而Bellman-Ford算法的復(fù)雜度又過高,SPFA算法便 派上用場(chǎng)了。 我們約定有向加權(quán)圖G不存在負(fù)權(quán)回路,即最短路徑一定存在。當(dāng)然,我們可以在執(zhí)行該算法前做一次拓?fù)渑判?,以判斷是否存在?fù)權(quán)回路,但這不是我們討論的重 點(diǎn)。

算法思想:我們用數(shù)組d記錄每個(gè)結(jié)點(diǎn)的最短路徑估計(jì)值,用鄰接表來(lái)存儲(chǔ)圖G。我們采取的方法是動(dòng)態(tài)逼近法:設(shè)立一個(gè)先進(jìn)先出的隊(duì)列用來(lái)保存待優(yōu)化的 結(jié)點(diǎn),優(yōu)化時(shí)每次取出隊(duì)首結(jié)點(diǎn)u,并且用u點(diǎn)當(dāng)前的最短路徑估計(jì)值對(duì)離開u點(diǎn)所指向的結(jié)點(diǎn)v進(jìn)行松弛操作,如果v點(diǎn)的最短路徑估計(jì)值有所調(diào)整,且v點(diǎn)不在 當(dāng)前的隊(duì)列中,就將v點(diǎn)放入隊(duì)尾。這樣不斷從隊(duì)列中取出結(jié)點(diǎn)來(lái)進(jìn)行松弛操作,直至隊(duì)列空為止

期望的時(shí)間復(fù)雜度O(ke), 其中k為所有頂點(diǎn)進(jìn)隊(duì)的平均次數(shù),可以證明k一般小于等于2。

實(shí)現(xiàn)方法:

建立一個(gè)隊(duì)列,初始時(shí)隊(duì)列里只有起始點(diǎn),再建立一個(gè)表格記錄起始點(diǎn)到所有點(diǎn)的最短路徑(該表格的初始值要賦為極大值,該點(diǎn)到他本身的路徑賦為 0)。然后執(zhí)行松弛操作,用隊(duì)列里有的點(diǎn)作為起始點(diǎn)去刷新到所有點(diǎn)的最短路,如果刷新成功且被刷新點(diǎn)不在隊(duì)列中則把該點(diǎn)加入到隊(duì)列最后。重復(fù)執(zhí)行直到隊(duì)列 為空。

判斷有無(wú)負(fù)環(huán):

如果某個(gè)點(diǎn)進(jìn)入隊(duì)列的次數(shù)超過N次則存在負(fù)環(huán)(SPFA無(wú)法處理帶負(fù)環(huán)的圖)

首先建立起始點(diǎn)a到其余各點(diǎn)的

最短路徑表格

首先源點(diǎn)a入隊(duì),當(dāng)隊(duì)列非空時(shí):

1、隊(duì)首元素(a)出隊(duì),對(duì)以a為起始點(diǎn)的所有邊的終點(diǎn)依次進(jìn)行松弛操作(此處有b,c,d三個(gè)點(diǎn)),此時(shí)路徑表格狀態(tài)為:

在松弛時(shí)三個(gè)點(diǎn)的最短路徑估值變小了,而這些點(diǎn)隊(duì)列中都沒有出現(xiàn),這些點(diǎn)
需要入隊(duì),此時(shí),隊(duì)列中新入隊(duì)了三個(gè)結(jié)點(diǎn)b,c,d

隊(duì)首元素b點(diǎn)出隊(duì),對(duì)以b為起始點(diǎn)的所有邊的終點(diǎn)依次進(jìn)行松弛操作(此處只有e點(diǎn)),此時(shí)路徑表格狀態(tài)為:

在最短路徑表中,e的最短路徑估值也變小了,e在隊(duì)列中不存在,因此e也要
入隊(duì),此時(shí)隊(duì)列中的元素為c,d,e

隊(duì)首元素c點(diǎn)出隊(duì),對(duì)以c為起始點(diǎn)的所有邊的終點(diǎn)依次進(jìn)行松弛操作(此處有e,f兩個(gè)點(diǎn)),此時(shí)路徑表格狀態(tài)為:

在最短路徑表中,e,f的最短路徑估值變小了,e在隊(duì)列中存在,f不存在。因此
e不用入隊(duì)了,f要入隊(duì),此時(shí)隊(duì)列中的元素為d,e,f

隊(duì)首元素d點(diǎn)出隊(duì),對(duì)以d為起始點(diǎn)的所有邊的終點(diǎn)依次進(jìn)行松弛操作(此處只有g(shù)這個(gè)點(diǎn)),此時(shí)路徑表格狀態(tài)為:

在最短路徑表中,g的最短路徑估值沒有變?。ㄋ沙诓怀晒Γ?,沒有新結(jié)點(diǎn)入隊(duì),隊(duì)列中元素為f,g

隊(duì)首元素f點(diǎn)出隊(duì),對(duì)以f為起始點(diǎn)的所有邊的終點(diǎn)依次進(jìn)行松弛操作(此處有d,e,g三個(gè)點(diǎn)),此時(shí)路徑表格狀態(tài)為:


在最短路徑表中,e,g的最短路徑估值又變小,隊(duì)列中無(wú)e點(diǎn),e入隊(duì),隊(duì)列中存在g這個(gè)點(diǎn),g不用入隊(duì),此時(shí)隊(duì)列中元素為g,e

隊(duì)首元素g點(diǎn)出隊(duì),對(duì)以g為起始點(diǎn)的所有邊的終點(diǎn)依次進(jìn)行松弛操作(此處只有b點(diǎn)),此時(shí)路徑表格狀態(tài)為:

在最短路徑表中,b的最短路徑估值又變小,隊(duì)列中無(wú)b點(diǎn),b入隊(duì),此時(shí)隊(duì)列中元素為e,b
隊(duì)首元素e點(diǎn)出隊(duì),對(duì)以e為起始點(diǎn)的所有邊的終點(diǎn)依次進(jìn)行松弛操作(此處只有g(shù)這個(gè)點(diǎn)),此時(shí)路徑表格狀態(tài)為:

在最短路徑表中,g的最短路徑估值沒變化(松弛不成功),此時(shí)隊(duì)列中元素為b

隊(duì)首元素b點(diǎn)出隊(duì),對(duì)以b為起始點(diǎn)的所有邊的終點(diǎn)依次進(jìn)行松弛操作(此處只有e這個(gè)點(diǎn)),此時(shí)路徑表格狀態(tài)為:

在最短路徑表中,e的最短路徑估值沒變化(松弛不成功),此時(shí)隊(duì)列為空了

最終a到g的最短路徑為14

java代碼

package spfa負(fù)權(quán)路徑;
 
import java.awt.List;
import java.util.ArrayList;
import java.util.Scanner;
public class SPFA {
 /**
  * @param args
  */
 public long[] result;   //用于得到第s個(gè)頂點(diǎn)到其它頂點(diǎn)之間的最短距離
 //數(shù)組實(shí)現(xiàn)鄰接表存儲(chǔ)
 class edge{
  public int a;//邊的起點(diǎn)
  public int b;//邊的終點(diǎn)
  public int value;//邊的值
  public edge(int a,int b,int value){
   this.a=a;
   this.b=b;
   this.value=value;
  }
 }
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  SPFA spafa=new SPFA();
  Scanner scan=new Scanner(System.in);
  int n=scan.nextInt();
  int s=scan.nextInt();
  int p=scan.nextInt();
  edge[] A=new edge[p];
  for(int i=0;i<p;i++){
   int a=scan.nextInt();
   int b=scan.nextInt();
   int value=scan.nextInt();
   A[i]=spafa.new edge(a,b,value);
  }
  if(spafa.getShortestPaths(n,s,A)){
   for(int i=0;i<spafa.result.length;i++){
    System.out.println(spafa.result[i]+" ");
   }
  }else{
   System.out.println("存在負(fù)環(huán)");
  }
 }
 /*
  * 參數(shù)n:給定圖的頂點(diǎn)個(gè)數(shù)
  * 參數(shù)s:求取第s個(gè)頂點(diǎn)到其它所有頂點(diǎn)之間的最短距離
  * 參數(shù)edge:給定圖的具體邊
  * 函數(shù)功能:如果給定圖不含負(fù)權(quán)回路,則可以得到最終結(jié)果,如果含有負(fù)權(quán)回路,則不能得到最終結(jié)果
  */
 private boolean getShortestPaths(int n, int s, edge[] A) {
  // TODO Auto-generated method stub
  ArrayList<Integer> list = new ArrayList<Integer>();
  result=new long[n];
  boolean used[]=new boolean[n];
  int num[]=new int[n];
  for(int i=0;i<n;i++){
   result[i]=Integer.MAX_VALUE;
   used[i]=false;
  }
  result[s]=0;//第s個(gè)頂點(diǎn)到自身距離為0
  used[s]=true;//表示第s個(gè)頂點(diǎn)進(jìn)入數(shù)組隊(duì)
  num[s]=1;//表示第s個(gè)頂點(diǎn)已被遍歷一次
  list.add(s); //第s個(gè)頂點(diǎn)入隊(duì)
  while(list.size()!=0){
   int a=list.get(0);//獲取數(shù)組隊(duì)中第一個(gè)元素
   list.remove(0);//刪除數(shù)組隊(duì)中第一個(gè)元素
   for(int i=0;i<A.length;i++){
   //當(dāng)list數(shù)組隊(duì)的第一個(gè)元素等于邊A[i]的起點(diǎn)時(shí)
    if(a==A[i].a&&result[A[i].b]>(result[A[i].a]+A[i].value)){
     result[A[i].b]=result[A[i].a]+A[i].value;
     if(!used[A[i].b]){
      list.add(A[i].b);
      num[A[i].b]++;
      if(num[A[i].b]>n){
       return false;
      }
      used[A[i].b]=true;//表示邊A[i]的終點(diǎn)b已進(jìn)入數(shù)組隊(duì)
     }
    }
   }
   used[a]=false; //頂點(diǎn)a出數(shù)組對(duì)
  }
  return true;
 }
}

以上這篇SPFA 算法實(shí)例講解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java編程Post數(shù)據(jù)請(qǐng)求和接收代碼詳解

    Java編程Post數(shù)據(jù)請(qǐng)求和接收代碼詳解

    這篇文章主要介紹了Java編程Post數(shù)據(jù)請(qǐng)求和接收代碼詳解,涉及enctype的三種編碼,post與get等相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • IntelliJ IDEA 中必有得插件和配置

    IntelliJ IDEA 中必有得插件和配置

    這篇文章主要介紹了IntelliJ IDEA 中必有得插件和配置,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Java?9?中的模塊Module系統(tǒng)

    Java?9?中的模塊Module系統(tǒng)

    Java?9?引入的模塊是在Java包(package)的基礎(chǔ)上又引入的一個(gè)新的抽象層,基于package這一點(diǎn)很重要,這里需要強(qiáng)調(diào)一下,接下來(lái)通過本文給大家介紹Java?9?中的模塊Module系統(tǒng),感興趣的朋友一起看看吧
    2022-03-03
  • jdk動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理詳解

    jdk動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理詳解

    本篇文章主要介紹了深度剖析java中JDK動(dòng)態(tài)代理機(jī)制 ,動(dòng)態(tài)代理避免了開發(fā)人員編寫各個(gè)繁鎖的靜態(tài)代理類,只需簡(jiǎn)單地指定一組接口及目標(biāo)類對(duì)象就能動(dòng)態(tài)的獲得代理對(duì)象
    2021-07-07
  • java信號(hào)量控制線程打印順序的示例分享

    java信號(hào)量控制線程打印順序的示例分享

    這篇文章主要介紹了java信號(hào)量控制線程打印順序的示例,如ABCABC這樣輸出線程,大家參考使用吧
    2014-01-01
  • mybatisplus自動(dòng)填充屬性值的實(shí)現(xiàn)步驟

    mybatisplus自動(dòng)填充屬性值的實(shí)現(xiàn)步驟

    MyBatis-Plus提供自動(dòng)填充的功能,幫助自定設(shè)置這些字段的值,提升開發(fā)效率,本文就來(lái)介紹一下如何使用,感興趣的可以了解一下
    2023-12-12
  • Javaweb 500 服務(wù)器內(nèi)部錯(cuò)誤的解決

    Javaweb 500 服務(wù)器內(nèi)部錯(cuò)誤的解決

    這篇文章主要介紹了Javaweb 500 服務(wù)器內(nèi)部錯(cuò)誤的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2020-09-09
  • xxl-job 帶參數(shù)執(zhí)行和高可用部署方法

    xxl-job 帶參數(shù)執(zhí)行和高可用部署方法

    這篇文章主要介紹了xxl-job 帶參數(shù)執(zhí)行和高可用部署,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • java?數(shù)組越界判斷和獲取數(shù)組長(zhǎng)度的實(shí)現(xiàn)方式

    java?數(shù)組越界判斷和獲取數(shù)組長(zhǎng)度的實(shí)現(xiàn)方式

    這篇文章主要介紹了java?數(shù)組越界判斷和獲取數(shù)組長(zhǎng)度的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • JVM(Java?Virtual?Machine,Java虛擬機(jī))的作用詳解

    JVM(Java?Virtual?Machine,Java虛擬機(jī))的作用詳解

    JVM是Java語(yǔ)言實(shí)現(xiàn)“一次編寫,到處運(yùn)行”特性的基石,也是Java平臺(tái)的核心組成部分,其主要作用包括平臺(tái)無(wú)關(guān)性、內(nèi)存管理、運(yùn)行Java程序、安全性以及性能優(yōu)化,通過這些功能,JVM確保了Java程序的可移植性、高效性和安全性
    2025-03-03

最新評(píng)論

哈尔滨市| 连城县| 洮南市| 雅江县| 宜章县| 天等县| 方山县| 夏邑县| 淮安市| 石狮市| 晋城| 麻阳| 尼勒克县| 秦皇岛市| 沭阳县| 新建县| 遂溪县| 广灵县| 六枝特区| 牙克石市| 鹤庆县| 海原县| 江川县| 莆田市| 四会市| 南阳市| 习水县| 自治县| 余干县| 凤山市| 勃利县| 华安县| 台前县| 龙里县| 都安| 喜德县| 泸水县| 寻乌县| 浦县| 万荣县| 闵行区|