婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

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

在SQL Server中實現(xiàn)最短路徑搜索的解決方法

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

開始

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

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

圖1.

解析:

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

圖2.

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

從上面可以看出第2種可能路徑,經(jīng)過的節(jié)點最少。

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

第1方法是,

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


圖3.

第2方法是,

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

圖4.

實現(xiàn):

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

這里提供有表RelactionGraph的create Insert數(shù)據(jù)的腳本:

復制代碼 代碼如下:

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作為中心進行搜索時候,作為能否循環(huán)搜索的標記
    @RelatedNode_WhileFlag bit=1 --以@RelatedNode作為中心進行搜索時候,作為能否循環(huán)搜索的標記

--如果直接找到兩個Node存在直接關(guān)系就直接返回
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作為中心向外擴展的各節(jié)點數(shù)據(jù)
if object_id('tempdb..#2') Is not null Drop Table #2 --臨時表#2,存儲的是以@RelatedNode作為中心向外擴展的各節(jié)點數(shù)據(jù)

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 數(shù)據(jù),就直接跳過后面的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) --判斷是否出現(xiàn)切點
     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:

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

下面是存儲過程的執(zhí)行:

復制代碼 代碼如下:

use TestDB

go

exec dbo.up_GetPath

        @Node = 'p',

@RelatedNode = 'j'

go

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

拓展:

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

小結(jié):

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

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

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

巨人網(wǎng)絡(luò)通訊聲明:本文標題《在SQL Server中實現(xiàn)最短路徑搜索的解決方法》,本文關(guān)鍵詞  在,SQL,Server,中,實現(xiàn),最短,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《在SQL Server中實現(xiàn)最短路徑搜索的解決方法》相關(guān)的同類信息!
  • 本頁收集關(guān)于在SQL Server中實現(xiàn)最短路徑搜索的解決方法的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    精品视频一区二区不卡| 成人中文字幕合集| 亚洲国产成人av网| 国产资源精品在线观看| 99免费精品视频| 国产无人区一区二区三区| 美国一区二区三区在线播放| 在线观看亚洲精品视频| 国产精品久久久久久户外露出 | 国产毛片一区二区| 欧美日韩一区二区在线视频| 国产清纯在线一区二区www| 青青草一区二区三区| 欧美丰满嫩嫩电影| 亚洲.国产.中文慕字在线| 成人免费视频一区| 日本一区二区久久| 91在线免费看| 亚洲欧美日韩国产综合| 色女孩综合影院| 亚洲午夜久久久久久久久久久| av在线不卡网| 污片在线观看一区二区| wwwwxxxxx欧美| 91国产视频在线观看| 午夜激情综合网| 久久久国产一区二区三区四区小说| 国产1区2区3区精品美女| 亚洲摸摸操操av| 91久久免费观看| 国产一区二区三区最好精华液| 亚洲色图一区二区三区| 欧美xingq一区二区| 一本色道久久加勒比精品| 黑人巨大精品欧美一区| 伊人一区二区三区| 久久综合九色综合欧美就去吻| 欧美艳星brazzers| 91丨九色丨黑人外教| 久久99国产精品免费网站| 国产精品毛片久久久久久久| 日韩三区在线观看| 欧美伦理电影网| 91在线观看美女| 粉嫩av一区二区三区粉嫩| 另类欧美日韩国产在线| 麻豆一区二区三区| 蜜臀av一区二区在线免费观看 | 国产精品18久久久久久久网站| 最好看的中文字幕久久| 久久久精品日韩欧美| 自拍偷拍亚洲综合| 亚洲成人免费影院| 91在线免费视频观看| 国产精品一区三区| 国产精品一级黄| 蜜桃视频在线一区| 国产精品一区二区不卡| 成人免费视频播放| 欧美综合欧美视频| 日韩亚洲欧美中文三级| 26uuu久久天堂性欧美| 久久九九全国免费| 亚洲丝袜美腿综合| 日韩av一二三| 国产成人精品午夜视频免费| 成人黄色电影在线| 欧美日韩高清不卡| 欧美电影免费观看完整版| 久久精品水蜜桃av综合天堂| 亚洲欧美二区三区| 精品一区二区三区蜜桃| caoporen国产精品视频| 日韩免费一区二区| 一区二区三区在线视频免费| 激情综合网激情| 91精品国产福利在线观看| 综合分类小说区另类春色亚洲小说欧美 | 国产网站一区二区| 婷婷丁香久久五月婷婷| 成人禁用看黄a在线| 欧美日韩成人激情| 国产欧美一区二区三区网站| 蜜臀av一区二区| 欧美一区二区三区免费在线看| 亚洲欧美一区二区久久| 国产高清一区日本| 久久精品男人天堂av| 免费在线观看一区| 欧美不卡一二三| 久久精品国产免费看久久精品| 一本一本大道香蕉久在线精品 | 欧美日韩国产综合一区二区 | 亚洲午夜精品17c| 91成人在线免费观看| 亚洲精品国久久99热| 国产精品 欧美精品| 综合av第一页| 日韩精品一区国产麻豆| 成人高清在线视频| 日韩中文字幕麻豆| 日本一区二区在线不卡| 91小视频免费看| 亚洲成人免费影院| 国产午夜精品一区二区三区嫩草 | 国产精品系列在线播放| 91在线码无精品| 亚洲一区自拍偷拍| 麻豆视频一区二区| 综合久久给合久久狠狠狠97色 | 日韩一区日韩二区| 欧美日韩国产小视频| 成人综合激情网| 蜜臀av国产精品久久久久 | 91精品国产乱| 91国产免费观看| 99国产精品视频免费观看| 国产成人在线免费| 精品精品国产高清一毛片一天堂| 自拍偷拍欧美激情| 91首页免费视频| 亚洲精品精品亚洲| 欧美影院一区二区| 天天av天天翘天天综合网| 在线观看日韩高清av| 亚洲国产成人va在线观看天堂| 91亚洲大成网污www| 九九精品视频在线看| 这里只有精品电影| 另类欧美日韩国产在线| 国产婷婷色一区二区三区四区| 色天天综合久久久久综合片| 99精品一区二区三区| 国产精品婷婷午夜在线观看| 成人av资源下载| 午夜免费欧美电影| 精品久久久久久久一区二区蜜臀| 国产一区美女在线| 国产精品久久久久久福利一牛影视| 99精品国产99久久久久久白柏| 亚洲成人久久影院| 国产偷国产偷精品高清尤物 | 日韩欧美在线一区二区三区| 在线不卡一区二区| 国产欧美精品区一区二区三区| 丝袜a∨在线一区二区三区不卡| 国产成+人+日韩+欧美+亚洲| 欧美高清一级片在线| 自拍偷拍欧美激情| 在线观看免费成人| 中文字幕一区二区三| 一本大道综合伊人精品热热| 国产精品国产三级国产有无不卡 | 国产精品视频免费| 亚洲一区二区三区在线看| 成人国产亚洲欧美成人综合网| 欧美大白屁股肥臀xxxxxx| 亚洲精品国产一区二区三区四区在线| 亚洲18女电影在线观看| 波波电影院一区二区三区| 欧美激情综合五月色丁香| 国产精品系列在线观看| 国产精品护士白丝一区av| 狠狠色狠狠色综合日日91app| 欧美精品1区2区3区| 激情综合色综合久久综合| 国产日韩欧美不卡| 在线影院国内精品| 精品一区二区在线播放| 伊人色综合久久天天人手人婷| 91麻豆精品国产91久久久使用方法 | 欧美三级在线看| 日本中文字幕不卡| 最新成人av在线| 91精品国产aⅴ一区二区| www.欧美亚洲| 懂色av一区二区三区免费看| 亚洲444eee在线观看| 亚洲精品欧美激情| 欧美韩国日本综合| 欧美成人猛片aaaaaaa| 一本一道综合狠狠老| 久久精品免费看| 亚洲自拍偷拍图区| 日韩女优电影在线观看| 丁香婷婷综合五月| 一区二区成人在线| 国产日本欧美一区二区| 欧美另类高清zo欧美| 国产成人综合在线观看| 一区二区三区中文字幕在线观看| 亚洲一区二区三区四区五区中文 | 亚洲一区二区三区四区五区中文| 欧美日韩性生活| 99riav一区二区三区| 免播放器亚洲一区| 亚洲va韩国va欧美va精品 | 久久久精品一品道一区| 久久99热这里只有精品| 亚洲精品欧美二区三区中文字幕|