欧美阿v视频在线大全_亚洲欧美中文日韩V在线观看_www性欧美日韩欧美91_亚洲欧美日韩久久精品

主頁 > 知識庫 > 在SQL Server中實現最短路徑搜索的解決方法

在SQL Server中實現最短路徑搜索的解決方法

熱門標簽:浙江穩定外呼系統供應商 美團地圖標注商戶認證注冊 電銷外呼系統軟件功能 承德地圖標注公司名需要花錢嗎 北京400電話辦理多少錢 榕城市地圖標注 慶陽地圖標注 咸陽電腦外呼系統運營商 怎么給高德做地圖標注

開始

這是去年的問題了,今天在整理郵件的時候才發現這個問題,感覺頂有意思的,特記錄下來。

在表RelationGraph中,有三個字段(ID,Node,RelatedNode),其中Node和RelatedNode兩個字段描述兩個節點的連接關系;現在要求,找出從節點"p"至節點"j",最短路徑(即經過的節點最少)。

圖1.

解析:

了能夠更好的描述表RelationGraph中字段Node和 RelatedNode的關系,我在這里特意使用一個圖形來描述,
如圖2.

圖2.

在圖2,可清晰的看出各個節點直接如何相連,也可以清楚的看出節點"p"至節點"j"的的幾種可能路徑。

從上面可以看出第2種可能路徑,經過的節點最少。

為了解決開始的問題,我參考了兩種方法,

第1方法是,

參考單源最短路徑算法:Dijkstra(迪杰斯特拉)算法,主要特點是以起始點為中心向外層層擴展,直到擴展到終點為止。


圖3.

第2方法是,

針對第1種方法的改進,就是采用多源點方法,這里就是以節點"p"和節點"j"為中心向外層擴展,直到兩圓外切點,如圖4. :

圖4.

實現:

在接下來,我就描述在SQL Server中,如何實現。當然我這里采用的前面說的第2種方法,以"P"和"J"為始點像中心外層層擴展。

這里提供有表RelactionGraph的create Insert數據的腳本:

復制代碼 代碼如下:

use TestDB    

go

if object_id('RelactionGraph') Is not null drop table RelactionGraph

create table RelactionGraph(ID int identity,Item nvarchar(50),RelactionItem nvarchar(20),constraint PK_RelactionGraph primary key(ID))

go

create nonclustered index IX_RelactionGraph_Item on RelactionGraph(Item) include(RelactionItem)

create nonclustered index IX_RelactionGraph_RelactionItem on RelactionGraph(RelactionItem) include(Item)

go

insert into RelactionGraph (Item, RelactionItem ) values

    ('a','b'),('a','c'),('a','d'),('a','e'),

    ('b','f'),('b','g'),('b','h'),

    ('c','i'),('c','j'),

    ('f','k'),('f','l'),

    ('k','o'),('k','p'),

    ('o','i'),('o','l')

go


編寫一個存儲過程up_GetPath
復制代碼 代碼如下:

use TestDB
go
--Procedure:
if object_id('up_GetPath') Is not null
    Drop proc up_GetPath
go
create proc up_GetPath
(
    @Node nvarchar(50),
    @RelatedNode nvarchar(50)
)
As
set nocount on

declare
    @level smallint =1, --當前搜索的深度
    @MaxLevel smallint=100, --最大可搜索深度
    @Node_WhileFlag bit=1, --以@Node作為中心進行搜索時候,作為能否循環搜索的標記
    @RelatedNode_WhileFlag bit=1 --以@RelatedNode作為中心進行搜索時候,作為能否循環搜索的標記

--如果直接找到兩個Node存在直接關系就直接返回
if Exists(select 1 from RelationGraph where (Node=@Node And RelatedNode=@RelatedNode) or (Node=@RelatedNode And RelatedNode=@Node) ) or @Node=@RelatedNode
begin
    select convert(nvarchar(2000),@Node + ' --> '+ @RelatedNode) As RelationGraphPath,convert(smallint,0) As StopCount
    return
end

--

if object_id('tempdb..#1') Is not null Drop Table #1 --臨時表#1,存儲的是以@Node作為中心向外擴展的各節點數據
if object_id('tempdb..#2') Is not null Drop Table #2 --臨時表#2,存儲的是以@RelatedNode作為中心向外擴展的各節點數據

create table #1(
    Node nvarchar(50),--相對源點
    RelatedNode nvarchar(50), --相對目標
    Level smallint --深度
    )

create table #2(Node nvarchar(50),RelatedNode nvarchar(50),Level smallint)

insert into #1 ( Node, RelatedNode, Level )
    select Node, RelatedNode, @level from RelationGraph a where a.Node =@Node union --正向:以@Node作為源查詢
    select RelatedNode, Node, @level from RelationGraph a where a.RelatedNode = @Node --反向:以@Node作為目標進行查詢
set @Node_WhileFlag=sign(@@rowcount)

insert into #2 ( Node, RelatedNode, Level )
    select Node, RelatedNode, @level from RelationGraph a where a.Node =@RelatedNode union --正向:以@RelatedNode作為源查詢
    select RelatedNode, Node, @level from RelationGraph a where a.RelatedNode = @RelatedNode --反向:以@RelatedNode作為目標進行查詢
set @RelatedNode_WhileFlag=sign(@@rowcount)

--如果在表RelationGraph中找不到@Node 或 @RelatedNode 數據,就直接跳過后面的While過程
if not exists(select 1 from #1) or not exists(select 1 from #2)
begin
    goto While_Out
end

 
while not exists(select 1 from #1 a inner join #2 b on b.RelatedNode=a.RelatedNode) --判斷是否出現切點
     and (@Node_WhileFlag|@RelatedNode_WhileFlag)>0 --判斷是否能搜索
     And @level@MaxLevel --控制深度
begin
    if @Node_WhileFlag >0
    begin    
        insert into #1 ( Node, RelatedNode, Level )
            --正向
            select a.Node,a.RelatedNode,@level+1
                From RelationGraph a
                where exists(select 1 from #1 where RelatedNode=a.Node And Level=@level) And
                    Not exists(select 1 from #1 where Node=a.Node)            
            union
            --反向
            select a.RelatedNode,a.Node,@level+1
                From RelationGraph a
                where exists(select 1 from #1 where RelatedNode=a.RelatedNode And Level=@level) And
                    Not exists(select 1 from #1 where Node=a.RelatedNode)

        set @Node_WhileFlag=sign(@@rowcount)

    end

    
    if @RelatedNode_WhileFlag >0
    begin        
        insert into #2 ( Node, RelatedNode, Level )
            --正向
            select a.Node,a.RelatedNode,@level+1
                From RelationGraph a
                where exists(select 1 from #2 where RelatedNode=a.Node And Level=@level) And
                    Not exists(select 1 from #2 where Node=a.Node)
            union
            --反向
            select a.RelatedNode,a.Node,@level+1
                From RelationGraph a
                where exists(select 1 from #2 where RelatedNode=a.RelatedNode And Level=@level) And
                    Not exists(select 1 from #2 where Node=a.RelatedNode)
        set @RelatedNode_WhileFlag=sign(@@rowcount)
    end

    select @level+=1
end

While_Out:

--下面是構造返回的結果路徑
if object_id('tempdb..#Path1') Is not null Drop Table #Path1
if object_id('tempdb..#Path2') Is not null Drop Table #Path2

;with cte_path1 As
(
select a.Node,a.RelatedNode,Level,convert(nvarchar(2000),a.Node+' -> '+a.RelatedNode) As RelationGraphPath,Convert(smallint,1) As PathLevel From #1 a where exists(select 1 from #2 where RelatedNode=a.RelatedNode)
union all
select b.Node,a.RelatedNode,b.Level,convert(nvarchar(2000),b.Node+' -> '+a.RelationGraphPath) As RelationGraphPath ,Convert(smallint,a.PathLevel+1) As PathLevel
    from cte_path1 a
        inner join #1 b on b.RelatedNode=a.Node
            and b.Level=a.Level-1
)
select * Into #Path1 from cte_path1

;with cte_path2 As
(
select a.Node,a.RelatedNode,Level,convert(nvarchar(2000),a.Node) As RelationGraphPath,Convert(smallint,1) As PathLevel From #2 a where exists(select 1 from #1 where RelatedNode=a.RelatedNode)
union all
select b.Node,a.RelatedNode,b.Level,convert(nvarchar(2000),a.RelationGraphPath+' -> '+b.Node) As RelationGraphPath ,Convert(smallint,a.PathLevel+1)
    from cte_path2 a
        inner join #2 b on b.RelatedNode=a.Node
            and b.Level=a.Level-1
)
select * Into #Path2 from cte_path2

;with cte_result As
(
select a.RelationGraphPath+' -> '+b.RelationGraphPath As RelationGraphPath,a.PathLevel+b.PathLevel -1 As StopCount,rank() over(order by a.PathLevel+b.PathLevel) As Result_row
    From #Path1 a
        inner join #Path2 b on b.RelatedNode=a.RelatedNode
            and b.Level=1
    where a.Level=1
)    
select distinct RelationGraphPath,StopCount From cte_result where Result_row=1
go

上面的存儲過程,主要分為兩大部分,第1部分是實現如何搜索,第2部分實現如何構造返回結果。其中第1部分的代碼根據前面的方法2,通過@Node 和 @RelatedNode 兩個節點向外層搜索,每次搜索返回的節點都保存至臨時表#1和#2,再判斷臨時表#1和#2有沒有出現切點,如果出現就說明已找到最短的路徑(經過多節點數最少),否則就繼續循環搜索,直到循環至最大的搜索深度(@MaxLevel smallint=100)或找到切點。要是到100層都沒搜索到切點,將放棄搜索。這里使用最大可搜索深度@MaxLevel,目的是控制由于數據量大可能會導致性能差,因為在這里數據量與搜索性能成反比。代碼中還說到一個正向和反向搜索,主要是相對Node 和 RelatedNode來說,它們兩者互為參照對象,進行向外搜索使用。

下面是存儲過程的執行:

復制代碼 代碼如下:

use TestDB

go

exec dbo.up_GetPath

        @Node = 'p',

@RelatedNode = 'j'

go

你可以根據需要來,賦予@Node 和 @RelatedNode不同的值。

拓展:

前面的例子,可擴展至城市的公交路線,提供兩個站點,搜索經過這兩個站點最少站點公交路線;可以擴展至社區的人際關系的搜索,如一個人與另一個人想認識,那么他們直接要經過多少個人才可以。除了人與人直接有直接的朋友、親戚關聯,還可以通過人與物有關聯找到人與人關聯,如幾個作家通過出版一個本,那么就說明這幾個人可以通過某一本書的作者列表中找到他們存在共同出版書籍的關聯,這為搜索兩個人認識路徑提供參考。這問題可能會非常大復雜,但可以這樣的擴展。

小結:

這里只是找兩個節點的所有路徑中,節點數最少的路徑,在實際的應用中,可能會碰到比這里更復雜的情況。在其他的環境或場景可能會帶有長度,時間,多節點,多作用域等一些信息。無論如何,一般都要參考一些原理,算法來實現。

您可能感興趣的文章:
  • SQLServer地址搜索性能優化
  • 在SQL Server 2005所有表中搜索某個指定列的方法
  • sqlserver中在指定數據庫的所有表的所有列中搜索給定的值
  • SQL Server 全文搜索功能介紹

標簽:貴州 昭通 重慶 上海 新鄉 拉薩 呼和浩特 江蘇

巨人網絡通訊聲明:本文標題《在SQL Server中實現最短路徑搜索的解決方法》,本文關鍵詞  在,SQL,Server,中,實現,最短,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《在SQL Server中實現最短路徑搜索的解決方法》相關的同類信息!
  • 本頁收集關于在SQL Server中實現最短路徑搜索的解決方法的相關信息資訊供網民參考!
  • 推薦文章
    欧美阿v视频在线大全_亚洲欧美中文日韩V在线观看_www性欧美日韩欧美91_亚洲欧美日韩久久精品
  • <rt id="w000q"><acronym id="w000q"></acronym></rt>
  • <abbr id="w000q"></abbr>
    <rt id="w000q"></rt>
    欧美在线观看视频一区二区 | jizz中文字幕| 国产精品成人99一区无码| 右手影院亚洲欧美| 免费看91的网站| 日韩一区二区三区四区 | 欧美精品在欧美一区二区少妇| 微拍福利一区二区| 欧美一区国产二区| 国产精品另类一区| 亚洲成av人片一区二区三区 | 一区二区成人在线视频| 日韩综合小视频| 国产黄人亚洲片| 日本欧美肥老太交大片| 精品精品欲导航| 国产精品美日韩| 国产成人av电影免费在线观看| 国产一二三av| 欧美日韩亚洲综合一区| 国产欧美精品区一区二区三区 | 精品日韩成人av| 久久国内精品视频| 99久久久无码国产精品性波多 | 中文字幕国产一区二区| 青青草原综合久久大伊人精品| 91丨porny丨首页| 黄色av免费播放| 91精品国产色综合久久| 亚洲女人****多毛耸耸8| 精品影视av免费| 国产大尺度视频| 五月天婷婷色综合| 亚洲精品一区在线观看| 性做久久久久久久久| 国产精品扒开腿做爽爽爽a片唱戏| 7777精品伊人久久久大香线蕉超级流畅| 午夜影院久久久| 亚洲乱码国产乱码精品精大量| 欧美精品一区在线观看| 国产成人一区二区精品非洲| 色94色欧美sute亚洲线路一ni| 国产日韩亚洲欧美综合| 日韩极品在线观看| 亚洲一级片在线播放| 国产精品久久久久久亚洲伦| 韩国精品主播一区二区在线观看 | 国产午夜精品久久久久久免费视| 国产精品66部| 在线免费观看日本欧美| 五月婷婷久久丁香| 91论坛在线播放| 日韩亚洲电影在线| 国产成人精品网址| 欧美日韩国产影片| 伊人婷婷欧美激情| 亚洲精品久久久久久| 欧美在线|欧美| 蜜桃91丨九色丨蝌蚪91桃色| 蜜臀av一区二区三区有限公司| 欧美韩国日本一区| 久久久久亚洲av成人网人人软件| 久久综合九色综合97_久久久| 精品一区二区在线免费观看| 9.1人成人免费视频网站| 国产精品久久久久久久久快鸭 | 国产一区二区精品久久91| 成人无码av片在线观看| 亚洲色图欧洲色图| 亚洲成人激情小说| 欧美日韩精品二区第二页| 精品一区二区日韩| 欧洲精品在线观看| 国产在线不卡视频| 欧美日韩专区在线| 国产精品夜夜嗨| 欧美日韩精品电影| 成人美女视频在线看| 永久免费看片直接| 免费看污片的网站| 亚洲色图视频免费播放| 一区二区精品免费| 国产日韩欧美综合在线| 手机在线成人av| 自拍偷拍国产精品| 国产手机在线观看| 亚洲一区中文日韩| 无码人妻精品一区二区三| 中文字幕第一区| 欧洲女同同性吃奶| 国产亚洲综合av| 亚洲欧美日本一区| 久久久亚洲高清| av一二三不卡影片| 欧美精品v日韩精品v韩国精品v| 国产成人亚洲综合a∨婷婷图片| 日韩一区二区精品葵司在线| 在线免费观看一区| 欧美乱妇一区二区三区不卡视频| 粉嫩一区二区三区性色av| 欧美综合亚洲图片综合区| 国产精品一二三四五| 精品区一区二区| 久久久久久久人妻无码中文字幕爆| 国产精品国产三级国产三级人妇| 无码一区二区三区在线| 午夜精品福利在线| 欧美丝袜自拍制服另类| 美国十次综合导航| 欧美人xxxx| 亚洲午夜精品在线观看| 最新热久久免费视频| 天天插天天射天天干| 欧美激情综合五月色丁香 | 91蜜桃视频在线| 国产精品国产a级| 天堂网中文在线观看| 久久99精品久久久久| 日韩你懂的在线播放| 国产99精品国产| 国产午夜精品久久久久久久| 无码少妇精品一区二区免费动态| 蜜桃久久精品一区二区| 欧美成人精品福利| 亚洲成av人片在线观看无| 夜夜夜精品看看| 91官网在线观看| 成人18视频日本| 精品国产乱码久久| 制服丝袜第一页在线观看| 天堂成人国产精品一区| 在线不卡中文字幕| 久久久久成人精品无码中文字幕| 亚洲成人三级小说| 5566中文字幕一区二区电影| 国产香蕉精品视频| 亚洲国产成人高清精品| 波多野结衣家庭教师在线观看| 亚洲午夜电影网| 精品视频免费在线| 成人做爰www看视频软件| 水野朝阳av一区二区三区| 日韩一二三区不卡| 一级片视频免费看| 国产成人综合视频| 1000部国产精品成人观看| 91搞黄在线观看| 亚洲精品乱码久久久久久蜜桃图片| 日韩精品国产欧美| 精品国产免费一区二区三区四区| 91l九色lporny| 国产夫妻精品视频| 亚洲天堂中文字幕| 精品视频在线免费| 国产精品三级在线观看无码| 国内外成人在线视频| 国产精品区一区二区三| 色综合久久久久久久| 麻豆91免费看| 亚洲国产精品v| 色噜噜久久综合| 亚洲激情 欧美| 国产综合久久久久久鬼色| 国产精品久久久久毛片软件| 欧美视频一区在线| 伊人网综合视频| 国产精品自在在线| 亚洲美女视频在线| 日韩一卡二卡三卡| 刘亦菲国产毛片bd| 欧美性猛交乱大交| 蜜臀久久99精品久久久画质超高清| 久久精品人人爽人人爽| 91黄视频在线观看| 国产伦精品一区二区三区妓女| 国产精品一区不卡| 一区二区成人在线视频| xf在线a精品一区二区视频网站| 丝袜美腿小色网| 中文字幕第3页| 国产suv精品一区二区6| 亚洲动漫第一页| 国产色91在线| 欧美日韩激情在线| 色撸撸在线视频| 久久久久无码国产精品一区李宗瑞| 久久爱另类一区二区小说| 成人免费小视频| 欧美电影免费观看高清完整版在线观看| 天堂网中文在线观看| 日本五十肥熟交尾| 高清久久久久久| 日本在线不卡一区| 亚洲同性gay激情无套| 欧美xxxxx裸体时装秀| 色哟哟一区二区| 国产一级久久久久毛片精品 | 国产欧美精品一区二区三区四区| 欧美日韩精品一区视频| 日本成人精品视频|