




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
Chapter9GraphsDefinitionofgraphsandsometerminologyGraphrepresentationsSomealgorithms9.1DefinitionandterminologiesDefinitionofgraphs:Graph=(V,E)V:nonemptyfiniteverticesetE:edgesetUndirectedGraph:Ifthetupledenotinganedgeisunordered,then(v1,v2)and(v2,v1)arethesameedge.9.1DefinitionandterminologiesDirectedgraph:Ifthetupledenotinganedgeisordered,then<v1,v2>and<v2,v1>aredifferentedges.v1:始點(diǎn)v2:終點(diǎn)9.1Definitionandterminologies
Example:V1V2V4V3V(G1)={V1,V2,V3,V4}E(G1)={(V1,V2),(V1,V3),(V1,V4),(V2,V3),(V2,V4),(V3,V4)}G1V1V2V(G2)={V1,V2,,V3}E(G2)={<V1,V2>,<V2,V1>,<V2,V3>}V3G29.1Definitionandterminologies
Wewillnotdiscussgraphsofthefollowingtypes多重圖9.1DefinitionandterminologiespletegraphInanundirectedgraphwithnnodes,thenumberofedges<=n*(n-1)/2.If“=“issatisfied,thenitiscalledacompleteundirectgraph.V2V4V3V19.1Definitionandterminologies
Inadirectedgraphwithnnodes,thenumberofedges<=n*(n-1).If“=“issatisfied,thenitiscalledacompletedirectedgraph.9.1Definitionandterminologies3.degreedvofvertexv,TD(v):isthenumberofedgesincidentonvertexv.Inadirectedgraph:in-degreeofvertexvisthenumberofedgesincidenttov,ID(v).out-degreeofvertexvisthenumberofedges incidentfromthev,OD(v).9.1Definitionandterminologies
TD(v)=ID(v)+OD(v)
Generally,iftherearenverticesandeedgesinagraph,thene=(TD(vi))/2v1v2v3ID(v2)=1OD(v2)=2TD(v2)=3i=1n9.1Definitionandterminologies4.SubgraphGraphG=(V,E),G’=(V’,E’),ifV’V,E’E,andtheverticesincidentontheedgesinE’areinV’,thenG’isthesubgraphofG.Forexample1Definitionandterminologies
Anotherexample:V2V4V3V1V2V3V1V19.1Definitionandterminologies5.path.AsequenceofverticesP=i1,i2,……ikisani1toik
path
inthegraphofgraphG=(V,E)ifftheedge(ij,ij+1)isinEforeveryj,1<=j<k.6.Simplepathandcycle
ASimplepathisapathinwhichallverticesexceptpossiblythefirstandlast,aredifferent.
ASimplecycleisasimplepathwiththesamestartandendvertex.9.1Definitionandterminologies
Anexampleofacycle
9.1Definitionandterminologies7.Connectedgraph&ConnectedcomponentInaundirectedgraph,ifthereisapathfromvertexv1tov2,thenv1andv2areconnected.Inaundirectedgraph,iftwoarbitraryverticesareconnected,thenthegraphisaconnectedgraph.9.1Definitionandterminologies
Examples:
Non-connectedgraphMaximumconnectedsubgraph(極大連通子圖)iscalledconnectedcomponent.9.1Definitionandterminologies8.StrongconnectedgraphandstronglyconnectedcomponentAdigraphisstronglyconnectediffitcontainsadirectedpathfromitojandfromjtoiforeverypairofdistinctverticesiandj.Themaximumstrongconnectedsubgraph(極大強(qiáng)連通子圖)ofanon-stronglyconnectedgraphiscalledstronglyconnectedconponent(強(qiáng)連通分量).9.1Definitionandterminologies9.NetworkWhenweightsandcostsareassignedtoedges,theresultingdataobjectiscalledweightedgraphandweighteddigraph.Thetermnetworkreferstoweightedconnectedgraphandweightedconnecteddigraph.9.1Definitionandterminologies
Exampleofanetwork
V1V3V2V4V552348611109.1Definitionandterminologies10.SpanningtreeAspanningtreeofaconnectedgraphisitsminimumconnectedsubgraph(極小連通子圖).Ann-vertexspanningtreehasn-1edges.Forexample:123412349.2ADTGraphandDigraph
AbstractDataTypeGraph{instancesasetVofverticesandasetEofedgesoperationsCreate(n):createanundirectedgraphwithnverticesandnoedgesExist(i,j):returntrueifedge(i,j)exists;falseotherwiseEdges():returnthenumberofedgesinthegraphVertices():returnthenumberofverticesinthegraphAdd(i,j):addtheedge(i,j)tothegraphDelete(i,j):deletetheedge(i,j)Degree(i):returnthedegreeofvertexiInDegree(i):synonymfordegreeOutDegree(i):synonymfordegree}9.3Representationofgraphsanddigraphs1.AdjacencyMatrixG=(V,E),V={V1,V2,……,Vn}thentheadjacencymatrixofgraphG:
A(i,j)=1if<i,j>,<j,i>Eor(i,j)E0otherwise9.3Representationofgraphsanddigraphs
Forexample:graphV1V2V3V4A(i,j)=01111011110011001)Adjacencymatrixofgraphisasymmetricmatrix2)A(i,j)=A(j,i)=di(degreeofvertexi)nj=1nj=19.3Representationofgraphsanddigraphs
DigraphV1V2V5V4V3A(i,j)=0100010001010101000100000
A(i,j)=dioutA(j,i)=diin
j=1nnj=19.3Representationofgraphsanddigraphs
Representationofnetworks,replace1withweights,otherswith∞W(i,j)ifi!=jand<i,j>,<j,i>Eor(i,j)E
∞otherwise
A(i,j)=9.3Representationofgraphsanddigraphs
Forexample:341286231495A(i,j)=∞1∞4∞
∞9235∞8∞
∞6∞
除以上的鄰接矩陣外,還要一個(gè)記錄各頂點(diǎn)信息的表,
一個(gè)當(dāng)前的邊數(shù)
其類說(shuō)明:
constintMaxNumEdges=50//最大邊數(shù)
constintMaxNumVertices=10//最大頂點(diǎn)數(shù)
template<classNameType,classDistType>classGraph
{private:
SeqList<NameType>VerticesList(MaxNumVertices)//頂點(diǎn)表
DistTypeEdge[MaxNumVertices][MaxNumVertices]//鄰接矩陣
intCurrentEdges;//當(dāng)前邊數(shù)
intFindVertex(Seqlist<NameType>&L;constNameType&Vertex){returnL.Find(Vertex);}
intGetVertexPos(constNameTyoe&Vertex)
{returnFindVertex(VerticesList);}
//給出了頂點(diǎn)Vertex在圖中的位置
V0
V1
V2
V3
.
.
dataMaxsize012n-1public:
Graph(constintsz=MaxNumEdges);
intGraphEmpty()const{returnVerticesList.IsEmpty();}
intGraphFull()const{returnVerticesList.IsFull()||
CurrentEdges==MaxNumEdges;}
intNumberofVertices(){returnVerticesList.last;}
intNumberofEdges(){returnCurrentEdges;}
NameTypeGetvalue(constinti)
{returni>=0&&i<VerticesList.last?VerticesList.data[i]:NULL;}
DistTypeGetweight(constintv1,constintv2);
intGetFirstNeighbor(constintv);
intGetNextNeighbor(constintv1,constintv2);
voidInsertVertex(constNameType&Vertex);
voidInsertEdge(constintv1,constintv2,DistTypeweight);
voidremoveVertex(constintv);
voidremoveEdge(cosntintv1,constintv2);
}
Constructor
template<classNameType,classDistType>
Graph<NameType,DistType>::Graph(intsz){for(inti=0;i<sz;i++)
for(intj=0;j<sz;j++)Edge[i][j]=0;
currentEdge=0;
}
求頂點(diǎn)V的第一個(gè)鄰接頂點(diǎn)的位置
template<classNameType,classDistType>intGraph<NameType,DistType>::GetFirstNeighbor(intv){if(v!=-1)
{for(intcol=0;col<CurrentVertices;col++)
if(Edge[v][col]>0&&Edge[v][col]<max)returncol;
}
return-1;
}9.3Representationofgraphsanddigraphs2.Linked-adjacencyListsreducethestoragerequirementifthenumberofedgesinthegraphissmall.V1V3V2V4430243011201201234
h
destlink
9.3Representationofgraphsanddigraphs
Digraph:V1V2V311346224311032016130123
h
destcostlink
26330220140111123
h又稱逆鄰接表
關(guān)于鄰接表的聲明
constintDefaultsize=10;
template<classNameType,classDistType>classGraph;
template<classDistType>structEdge//邊的定義{friendclassGraph<NameType,DistType>;
intdest;//邊的另一頂點(diǎn)在頂點(diǎn)表中的位置
DistTypecost;//邊上的權(quán)
Edge<DistType>*link;//下一條邊的鏈指針
Edge(){}
Edge(intD,DistTypeC):dest(D),cost(C),link(NULL){}
intoperate!=(constEdge<DistType>&E)const
{returndest!=E.dest;}}template<classNameType,classDistType>structVertex{friendclassEdge<DistType>;
friendclassGraph<NameType,DistType>;
NameTypedata;//頂點(diǎn)名字
Edge<DistType>*adj;//出邊表頭指針}邊的三個(gè)數(shù)據(jù)成員
dataadjNodeTable:destcostlink圖的類定義template<classNameType,classDistType>classGraph{private:
Vertex<NameType,DistType>*NodeTable;//頂點(diǎn)表
intNumVertices;//當(dāng)前頂點(diǎn)數(shù)
intMaxNumVertices;//最大頂點(diǎn)個(gè)數(shù)
intNumEdges;//當(dāng)前邊數(shù)
intGetVertexpos(constType&Vertex);
public:
Graph(intsz);
~Graph();
intGraphEmpty()const{returnNumVertices==0;}
intGraphFull()const
{returnNumVertices==MaxNumVertices;}intNumberOfVertices(){returnNumVertices;}
intNumberOfEdges(){returnNumEdges;}
NameTypeGetValue(constinti)
{returni>=0&&i<NumVertices?NodeTable[i].data:NULL;}
voidInsertVertex(constNameType&Vertex);
voidRemoveVertex(intv);
圖的私有數(shù)據(jù)成員
voidInsertEdge(intv1,intv2,DistTypeweight);
voidRemoveEdge(intv1,intv2);
DistTypeGetweight(intv1,intv2);
intGetFristNeighbor(intv);
intGetNextNeighbor(intv1,intv2);}
1)Constructortemplate<classNameType,classDistType>Graph<NameType,DistType>::
Graph(intsz=Defaultsize):NumVertices(0),MaxNumVertices(sz),NumEdge(0){intNumVertices,NumEdges,k,j;
NameTypename,tail,head;
DistTypeweight;
NodeTable=newVertex<NameType>[MaxNumVertices]
cin>>NumVertices;//輸入頂點(diǎn)數(shù)
for(inti=0;i<NumVertices;i++)
{cin>>name;
InsertVertex(name);}
cin>>NumEdges;//輸入邊數(shù)
for(i=0;i<NumEdges;i++)
{cin>>tail>>head>>weight;
k=GetVertexpos(tail);
j=GetVertexpos(head);
InsertEdge(k,j,weight);
}}
intGraph<NameType,DistType>::
GetVertexpos(constNameType&Vertex)
{for(inti=0;i<NumVertices;i++)
if(NodeTable[i].data==Vertex)returni;return–1;
}
2)給出頂點(diǎn)V的第一個(gè)鄰接頂點(diǎn)的位置
template<classNameType,classDistType>intGraph<NameType,DistType>::GetFirstNeighbor(intv){
if(v!=-1){Edge<DistType>*p=NodeTable[v].adj;
if(p!=NULL)returnpdest;
}
return–1}
template<classNameType,classDistType>intGraph<NameType,DistType>::GetNextNeighbor
(intv1,intv2){if(v1!=-1)
{Edge<DistType>*p=NodeTable[v1].adj;while(p!=NULL)
{if(pdest==v2&&plink!=NULL)
returnplinkdest;elsep=plink;}}return–1;}
3.鄰接多重表(adjacencymultilist)
在無(wú)向圖中,如果邊數(shù)為m,則在鄰接表表示中需2m個(gè)單位來(lái)存儲(chǔ).為了克服這一缺點(diǎn),采用鄰接多重表,每條邊用一個(gè)結(jié)點(diǎn)表示.V2V4
V1V3e1e2e4e3e5dataFirstoutV1V2V4V3020301
2123vertex1path1vertex2path2e1e2e3e4e5
對(duì)有向圖而言,需用鄰接表和逆鄰接表,如果把這兩
個(gè)表結(jié)合起來(lái)用有向圖的鄰接多重表(也稱為十字鏈表)
來(lái)表示一個(gè)有向圖.ADEBCe3e6e5e4e2e1A
B
C
12∧∧D
E
34∧∧23∧∧40∧∧01∧dataFirstinFirstout03∧
markv1v2p1p2e1e2e3e4e5e69.4圖的遍歷與連通性
圖的遍歷(GraphTraversal):
從圖中某一頂點(diǎn)出發(fā)訪問(wèn)圖中其余頂點(diǎn),且使每個(gè)頂點(diǎn)僅被訪問(wèn)一次.
遍歷二叉樹(shù):前序,中序,后序.
遍歷樹(shù):深度優(yōu)先遍歷(先根,后根)
廣度優(yōu)先遍歷遍歷森林:深度優(yōu)先遍歷(先根,中根,后根)
廣度優(yōu)先遍歷遍歷圖:深度優(yōu)先遍歷DFS(DepthFirstSearch)
廣度優(yōu)先遍歷BFS(BreadthFirstSearch)1.深度優(yōu)先搜索(depth-first-search)
思想:從圖中某個(gè)頂點(diǎn)V0出發(fā),訪問(wèn)它,然后選擇一個(gè)
V0鄰接到的未被訪問(wèn)的一個(gè)鄰接點(diǎn)V1出發(fā)深度優(yōu)先遍
歷圖,當(dāng)遇到一個(gè)所有鄰接于它的結(jié)點(diǎn)都被訪問(wèn)過(guò)了的
結(jié)點(diǎn)U時(shí),回退到前一次剛被訪問(wèn)過(guò)的擁有未被訪問(wèn)的
鄰接點(diǎn)W,再?gòu)腤出發(fā)深度遍歷,……直到連通圖中的所
有頂點(diǎn)都被訪問(wèn)過(guò)為止.
以有向圖為例:v1v2v6v5v4v3v8v7v1v2v6v5v4v3v8v7V1V2V4V8V5V3V6V7深度優(yōu)先生成樹(shù)
遞歸方法實(shí)現(xiàn)
算法中用一個(gè)輔助數(shù)組visited[]:0:未訪問(wèn)1:訪問(wèn)過(guò)了
假設(shè)圖為連通圖
主過(guò)程:
template<NameType,DistType>
voidGraph<NameType,DistType>::DFS(){int*visited=newint[NumVertices];
for(inti=0;i<NumVertices;i++)visited[i]=0;
DFS(0,visited);//從頂點(diǎn)0開(kāi)始深度優(yōu)先搜索
delete[]visited;}子過(guò)程:
template<NameType,DistType>voidGraph<NameType,DistType>:: DFS(intv,visited[]){cout<<GetValue(v)<<‘’;
visited[v]=1;
intw=GetFirstNeighbor(v);
while(w!=-1)
{if(!visited[w])DFS(w,visited);
w=GetNextNeighbor(v,w);
}}
用圖的抽象數(shù)據(jù)類型來(lái)實(shí)現(xiàn)
算法分析:
用鄰接表表示O(n+e)
用鄰接矩陣表示O(n2)
Javavoiddfs(Vertexv){v.visited=true;foreachwadjacenttovif(!w.visited)dfs(w);}//偽代碼2.廣度優(yōu)先遍歷(breadthsearch)思想:從圖中某頂點(diǎn)V0出發(fā),在訪問(wèn)了V0之后依次訪
問(wèn)v0的各個(gè)未曾訪問(wèn)過(guò)的鄰接點(diǎn),然后分別從這些鄰接
點(diǎn)出發(fā)廣度優(yōu)先遍歷圖,直至圖中所有頂點(diǎn)都被訪問(wèn)
到為止.例子
v1v2v6v5v4v3v8v7v1v2v6v5v4v3v8v7
算法同樣需要一個(gè)輔助數(shù)組visited[]表示頂點(diǎn)是否被訪問(wèn)過(guò).還需要一個(gè)隊(duì)列,記正在訪問(wèn)的這一層和上一層的頂點(diǎn).
算法顯然是非遞歸的.廣度優(yōu)先生成樹(shù)V1→V2→V3→V4→V5→V6→V7→V8
template<NameType,DistType>
voidGraph<NameType,DistType>::BFS(intv){int*visited=newint[NumVertices];
for(inti=0;i<NumVertices;i++)visited[i]=0;
cout<<GetValue(v)<<‘’;
visited[v]=1;
queue<int>q;
q.EnQueue(v);
while(!q.IsEmpty())
{v=q.DeQueue();
intw=GetFirstNeighbor(v);
while(w!=-1)
{if(!visited[w])
{cout<<GetValue(w)<<‘’;visited[w]=1;
q.EnQueue(w);
}
w=GetNextNeighbor(v,w);
}
}
delete[]visited;}
算法分析:每個(gè)頂點(diǎn)進(jìn)隊(duì)列一次且只進(jìn)一次,∴算法
中循環(huán)語(yǔ)句至多執(zhí)行n次。從具體圖的存儲(chǔ)結(jié)構(gòu)來(lái)看:
1)如果用鄰接表:循環(huán)總時(shí)間代價(jià)為d0+d1+…+dn-1=O(e)
其中di是頂點(diǎn)i的度
2)如果用鄰接矩陣:對(duì)每個(gè)被訪問(wèn)過(guò)的頂點(diǎn),循環(huán)檢測(cè) 矩陣中n個(gè)元素,∴時(shí)間代價(jià)為O(n2)3.連通分量
以上討論的是對(duì)一個(gè)無(wú)向的連通圖或一個(gè)強(qiáng)連通圖的
有向圖進(jìn)行遍歷,得到一棵深度優(yōu)先或廣度優(yōu)先生成樹(shù).但當(dāng)無(wú)向圖(以無(wú)向圖為例)為非連通圖時(shí),從圖的某一
頂點(diǎn)出發(fā)進(jìn)行遍歷(深度,廣度)只能訪問(wèn)到該頂點(diǎn)所在
的最大連通子圖(即連通分量)的所有頂點(diǎn).
例子:ABCDEFGHJIKLMNO非連通無(wú)向圖非連通圖的連通分量A,B,F,G,E,C,D
H,I,JABCDEFGHJIKLMNOK,L,O,M,N下面是利用深度優(yōu)先搜索求非連通圖的連通分量算法實(shí)際上只要加一個(gè)循環(huán)語(yǔ)句就行了.
Template<NameType,DistType>
voidGraph<NameType,DistType>::components(){int*visited=newint[NumVertices];
for(inti=0;i<NumVertices;i++)visited[i]=0;
for(i=0;i<NumVertices;i++)
if(!visited[i])
{DFS(i,visited);
ponent();
}
delete[]visited;
}
9.5最小生成樹(shù)
生成樹(shù)不唯一生成樹(shù)的代價(jià):TE(G)上諸邊的代價(jià)之和n個(gè)結(jié)點(diǎn)的生成樹(shù)有n-1條邊。1.生成樹(shù)的有關(guān)概念
生成樹(shù)的定義
設(shè)G=(V,E)是一個(gè)連通的無(wú)向圖(或是強(qiáng)連通有向圖)從圖G中的任一頂點(diǎn)出發(fā)作遍歷圖的操作,把遍歷走過(guò)的邊的集合記為TE(G),顯然G’=(V,TE)是G之子圖,G’被稱為G的生成樹(shù)(spanningtree),也稱為一個(gè)連通圖.
最小代價(jià)生成樹(shù)(minimun-costspanningtree)問(wèn)題的提出:如何找到一個(gè)網(wǎng)絡(luò)的最小生成樹(shù),即各邊權(quán)的總和為最小的生成樹(shù)實(shí)際例子:6個(gè)城市已固定,現(xiàn)從一個(gè)城市發(fā)出信息到每一個(gè)城市如何選擇或鋪設(shè)通信線路,使花費(fèi)(造價(jià))最低。前提:每條邊有代價(jià)
1423566551426356如果用廣度優(yōu)先,則12345661534=19最小代價(jià)生成=15兩個(gè)算法:Prim,Kruskal.它們都采用了逐步求解(Grandy)的策略。Grandy策略:設(shè):連通網(wǎng)絡(luò)N={V,E},V中有n個(gè)頂點(diǎn)。1)先構(gòu)造n個(gè)頂點(diǎn),0條邊的森林F={T0,T1,…..,Tn-1}2)每次向F中加入一條邊。該邊是一端在F的某棵樹(shù)Ti上而另一端不在Ti上的所有邊中具有最小權(quán)值的邊。這樣使F中兩棵樹(shù)合并為一棵,樹(shù)的棵數(shù)-13)重復(fù)n-1次
T0Tn-1
T1最小生成樹(shù)的類聲明:constintMAXINT=機(jī)器可表示的,問(wèn)題中不可能出現(xiàn)的大數(shù)classMinSpanTree;classMSTEdgeNode{friendclassMinSpanTree;private:inttail,head;intcost;};tailcosthead邊的結(jié)構(gòu):
classMinSpanTree{public:MinSpanTree(intSZ=NumVertices-1):MaxSize(SZ),n(0) {edgevalue=newMSTEdgeNode[MaxSize];}protected:MSTEdgeNode*edgevalue;//邊值數(shù)組
intMaxSize,n; //數(shù)組的最大元素個(gè)數(shù)和 //當(dāng)前個(gè)數(shù)};Kruskal算法1)把無(wú)向圖中的所有邊排序
1342521012986372367891012(1,2)(3,5)(3,4)(4,5)(2,3)(2,5)(1,4)(1,3)2)一開(kāi)始的最小生成樹(shù)為
T(V,TE)即由n個(gè)不同的連通分量組成
TE=3)在E中選一條代價(jià)最小的邊(u,v)加入T,一定要滿足(u,v)不和
TE中已有的邊構(gòu)成回路,EE-{(u,v)},TE=TE{(u,v)}4)一直到TE中加滿n-1條邊為止。13452134522134522313452236134522368
圖用鄰接矩陣表示,edge(邊的信息)
圖的頂點(diǎn)信息在頂點(diǎn)表Verticelist中
邊的條數(shù)為CurrentEdges
取最小的邊以及判別是否構(gòu)成回路,取最小的邊利用:最小堆(MinHeap)
判別是否構(gòu)成回路利用:并查集(DisjointSets)克魯斯卡爾算法
voidGraph<string,float>::Kruskal(MinSpanTree&T){MSTEdgeNodee;MinHeap<MSTEdgeNode>H(currentEdges);intNumVertices=VerticesList.Last,u,v;
UfsetsF(NumVertices);//建立n個(gè)單元素的連通分量
for(u=0;u<NumVertices;u++)for(v=u+1;v<NumVertices;v++)if(Edge[u][v]!=MAXINT) {e.tail=u;e.head=v;e.cost=Edge[u][v]; H.insert(e);}
intcount=1;//生成樹(shù)邊計(jì)數(shù)
while(count<NumVertices){H.RemoveMin(e);u=F.Find(e.tail);v=F.Find(e.head);if(u!=v){F.union(u,v);T.Insert(e);count++;}}}
java(偽代碼)publicvoidkruskal(){intedgesAccepted;DisjSets;priorityQueueh;Vertexu,v;SetTypeuset,vset;Edgee;
h=readGraphIntoHeapArray();h.buildHeap();s=newDisjSet(NUM_VERTICES);edgesAccepted=0;while(edgesAccepted<NUM_VERTICES–1){e=h.deleteMin();//Edgee=(u,v)uset=s.find(u);vset=s.find(v);if(uset!=vset){edgesAccepted++;s.union(uset,vset);}}}
算法分析:1)建立e條邊的最小堆。每插入一條邊,執(zhí)行一次
fiterup()算法:log2e
所以,總的建堆時(shí)間為O(elog2e)
檢測(cè)鄰接矩陣O(n2)2)構(gòu)造最小生成樹(shù)時(shí):
e次出堆操作:每一次出堆,執(zhí)行一次filterdown(),
總時(shí)間為O(elog2e)2e次find操作:O(elog2n)n-1次union操作:O(n)
所以,總的計(jì)算時(shí)間為O(elog2e+elog2n+n2+n)3.Prim算法設(shè):原圖的頂點(diǎn)集合V(有n個(gè)) 生成樹(shù)的頂點(diǎn)集合U(最后也有n個(gè)),一開(kāi)始為空
TE集合為{
}步驟: 1)U={1}任何起始頂點(diǎn),TE={} 2)每次生成(選擇)一條邊。這條邊是所有邊(u,v)
中代價(jià)(權(quán))最小的邊,
uU,vV-U TE=TE+[(u,v)]; U=U+[v] 3)當(dāng)UV用一開(kāi)始的例子:14235665514263561423566551426356123456U V-U5條中找最小1423566551426356132456U V-U8條中找最小14235665514263569條中找最小136245U V-U142356614263568條中找最小136425U V-U114235614263565條中找最小136425U V-U42356142351=15
具體實(shí)現(xiàn):1)圖采用鄰接矩陣2)設(shè)置了兩個(gè)輔助數(shù)組:改進(jìn)了實(shí)現(xiàn)效率(O(n2)).
最小生成樹(shù)不是唯一的.為什么?算法分析:1*(n-1)+2*(n-2)+……+(n-1)*(n-(n-1))=n-1+2n-4+3n-9+….+(n-1)*n-(n-1)2
=n+2n+3n+…+(n-1)*n-12-22-32-…(n-1)2
=n*(1+2+3+….+(n-1))-(12+22+32+….+(n-1)2)=O(n3)
Lowcost[]:存放生成樹(shù)頂點(diǎn)集合內(nèi)頂點(diǎn)到生成樹(shù)外各頂點(diǎn)的邊上的當(dāng)前最小權(quán)值;
nearvex[]:記錄生成樹(shù)頂點(diǎn)集合外各頂點(diǎn),距離集合內(nèi)那個(gè)頂點(diǎn)最近。從頂點(diǎn)0出發(fā)初始狀態(tài)Lowcost:
nearvex:0123456012345602810-1000000如果為-1則表示已加入生成樹(shù)頂點(diǎn)集合28161214182422102543265011)在Lowcost[]中選擇nearvex[i]-1,且lowcost[i]最小的邊用v標(biāo)記它。,則
選中的權(quán)值最小的邊為(nearvex[v],v),相應(yīng)的權(quán)值為lowcost[v]。例如在上面圖中第一次選中的v=5;則邊(0,5),是選中的權(quán)值最小
的邊,相應(yīng)的權(quán)值為lowcost[5]=10。反復(fù)做以下工作:2)將nearvex[v]改為-1,表示它已加入生成樹(shù)頂點(diǎn)集合。
將邊(nearvex[v],v,lowcost[v])加入生成樹(shù)的邊集合。3)修改。
取lowcost[i]=min{lowcost[i],Edge[v][i]},即用生成樹(shù)頂點(diǎn)集合外各頂
點(diǎn)i到剛加入該集合的新頂點(diǎn)v的距離(Edge[v][i])與原來(lái)它所到生成樹(shù)頂點(diǎn)
集合中頂點(diǎn)的最短距離lowcost[i]做比較,取距離近的,作為這些集合外頂
點(diǎn)到生成樹(shù)頂點(diǎn)集合內(nèi)頂點(diǎn)的最短
距離。
如果生成樹(shù)頂點(diǎn)集合外的頂點(diǎn)i到剛加入該集合新頂點(diǎn)v的距離比原來(lái)它
到生成樹(shù)頂點(diǎn)集合中頂點(diǎn)的最短距離還要近,則修改nearvex[i]:nearvex[i]=v
表示生成樹(shù)外頂點(diǎn)i到生成樹(shù)的內(nèi)頂點(diǎn)v當(dāng)前距離最短。-10000-100123456028100123456nearvexlowcost(0,5,10)1051234560UV-U00512346-10005-10012345602825100123456nearvexlowcost(5,4,25)105UV-U42510541236-1004-1-140123456028222510240123456nearvexlowcost(4,3,22)105UV-U425122
30543126-103-1-1-13012345602812222510180123456nearvexlowcost(3,2,12)105UV-U4251223212U0543216-12-1-1-1-13012345601612222510180123456nearvexlowcost(2,1,16)V-U10542502232121166-1-1-1-1-1-11012345601612222510140123456nearvexlowcost(1,6,14)054321UV-U1054250223212116614Prim(普里姆)算法voidgraph<string,float>::Prim(MinSpanTree&T){intNumVertices=VerticesList.last;float*lowcost=newfloat[NumVertices];int*nearvex=newint[NumVertices];
for(inti=1;i<NumVertices;i++){lowcost[i]=Edge[0][i];nearvex[i]=0;}
nearvex[0]=-1;
MSTEdgeNodee;
for(inti=1;i<NumVertices;i++){1.floatmin=MAXINT;intv=0;2.for(intj=1;j<NumVertices;j++)if(nearvex[j]!=-1&&lowcost[j]<min){v=j;min=lowcost[j];}
//forj,選擇最小的邊
3.
if(v){
e.tail=nearvex[v];e.head=v;e.cost=lowcost[v];
T.Insert(e);nearvex[v]=-1;
for(intj=1;j<NumVertices;j++) if(nearvex[j]!=-1&&Edge[v][j]<lowcost[j]) {lowcost[j]=Edge[v][j];nearvex[j]=v;}}//if}//fori}算法結(jié)構(gòu)為:時(shí)間復(fù)雜度:O(n2)求最小的n修改nnn思考題:這兩種算法分別適合那種情況?9.6最短路徑(shortestpath)三種算法:1)邊上權(quán)值為非負(fù)情況的從一個(gè)結(jié)點(diǎn)到其它各結(jié)點(diǎn)的最短路徑(單源最短路徑)(Dijkstra算法)2)邊上權(quán)值為任意值的單源最短路徑3)邊上權(quán)值為非負(fù)情況的所有頂點(diǎn)之間的最短路徑
設(shè)G=(V,E)是一個(gè)帶權(quán)圖(有向,無(wú)向),如果從頂點(diǎn)v到頂點(diǎn)w的一條路徑為(v,v1,v2,…,w),其路徑長(zhǎng)度不大于從v到w的所有其它路徑的長(zhǎng)度,則該路徑為從v到w的最短路徑。背景:交通網(wǎng)絡(luò)中,求各城鎮(zhèn)間的最短路徑。1.含非負(fù)權(quán)值的單源最短路徑(Dijkstra)問(wèn)題04123101003050201060V0 V1 10V0V3V2 50V0 V3 30V0V3V2V4 60如果按距離遞增的順序重新排列一下
經(jīng)過(guò) 終止距離V0
V1 10V0 V3 30V0V3 V2
50V0V3V2 V4 60012340103010005001020060001234
思想:按最短路徑長(zhǎng)度遞增的次序產(chǎn)生諸最短路徑。一開(kāi)始,在源點(diǎn)到直接有連線的諸頂點(diǎn)的path中找最小的,去掉該點(diǎn),然后找從源點(diǎn)到余下點(diǎn)中最短的path(這里可以不是直接連線,可以是經(jīng)過(guò)前面已找到的最短path的頂點(diǎn))V0SV1V2V3V4V-SV0V1SV2V3V4V-S算法思想:V0V1
V3SV2V4V-SV0V1
V3V2SV4V-S距離值數(shù)組:dist100-100-2600-1-250
0-3-2300-3300-31000-41000-4600-3-2-4900-3-401234路徑path00000320133-1000001234每次放由v0到達(dá)該頂點(diǎn)的前一頂點(diǎn)以下證明一下該算法的正確性,即證明:假設(shè)S是已求得的最短路徑的終點(diǎn)的集合,則可證明下一條最短路徑必然是從v0出發(fā),中間只經(jīng)過(guò)S中的頂點(diǎn)便可到達(dá)的那些頂點(diǎn)vx(vxV-S)的路徑中的一條。用反證法:設(shè)此路徑上存在一個(gè)頂點(diǎn)vpV-S,則說(shuō)明還存在一條終點(diǎn)不在S而長(zhǎng)度比此路徑短的路徑,這是不可能的。V0VlVtVpSV-SDijkstra算法constintNumVertices=6;classgraph{private:intEdge[NumVertices][NumVertices];intdist[NumVertices];intpath[NumVertices];intS[NumVertices];public:voidshortestpath(int,int);intchoose(int);};voidGraph::shortestpath(intn,intv){for(inti=0;i<n;i++){1.dist[i]=Edge[v][i];s[i]=0;2.if(i!=v&&dist[i]<MAXNUM)path[i]=v;elsepath[i]=-1;}
s[v]=1;dist[v]=0;for(i=0;i<n-1;i++){1.floatmin=MAXNUM;intu=v;2.for(intj=0;j<n;j++) if(!s[j]&&dist[j]<min){u=j;min=dist[j];}
3.s[u]=1;4.for(intw=0;w<n;w++)if(!s[w]&&Edge[u][w]<MAXNUM&& dist[u]+Edge[u][w]<dist[w]) {dist[w]=dist[u]+Edge[u][w];path[w]=u;}}//for}
算法分析:O(n2)求最小的n修改nnn2.邊上權(quán)值為任意值的單源最短路徑(貝爾曼—福特)
dijkstra算法在邊上權(quán)值為任意值的圖上是不能正常工作的。為什么?問(wèn)題出在程序的哪里?例子:012-575貝兒曼—福特提出了一個(gè)改進(jìn)的算法:構(gòu)造一個(gè)最短路徑長(zhǎng)度數(shù)組
dist1[u],dist2[u],...distn-1[u]其中:dist1[u]:是從源點(diǎn)v到終點(diǎn)u的只經(jīng)過(guò)一條邊的的最短路徑長(zhǎng)度,
dist1[u]=Edge[v][u]dist2[u]:是從源點(diǎn)v最多經(jīng)過(guò)兩條邊到達(dá)終點(diǎn)u
的最短路徑長(zhǎng)度;v0->v25v0->v17
dist3[u]:是從源點(diǎn)v最多經(jīng)過(guò)不構(gòu)成帶負(fù)長(zhǎng)度邊回路的三條邊 的最短路徑長(zhǎng)度;012-211不允許帶負(fù)權(quán)值的邊組成回路distn-1[u]:是從源點(diǎn)v最多經(jīng)過(guò)不構(gòu)成帶負(fù)長(zhǎng)度邊回路的n-1條 邊的最短路徑長(zhǎng)度;遞推公式:
dist1[u]=Edge[v][u]; distk[u]=min{distk-1[u],min{distk-1[j]+Edge[j][u]}} j=0,1,2,…,n-1...例子:-11253064631-255-1-23distk[0]distk[1]distk[2]distk[3]distk[4]distk[5]distk[6]13200060-110-3-2-130-2-150-2330-3-250-3550-30-420-2-1-450-1-40-5440-3-50-66570-3-5-60-64013500-3-2-1-4450-2-1-4-6voidGraph::BellmanFord(intn,intv){for(inti=0;i<n;i++){dist[i]=Edge[v][i];if(i!=v&&dist[i]<MAXNUM)path[i]=v;elsepath[i]=-1;}
for(intk=2;k<n;k++)for(intu=0;u<n;u++)if(u!=v) for(i=0;i<n;i++)
if(Edge[i][u]<>0&&Edge[i][u]<MAXNUM&& dist[u]>dist[i]+Edge[i][u]) {
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年文教用品市場(chǎng)調(diào)研報(bào)告
- 2025年飛艇項(xiàng)目深度研究分析報(bào)告
- 社區(qū)安全生產(chǎn)工作方案
- 企業(yè)財(cái)務(wù)數(shù)字化管理與風(fēng)險(xiǎn)控制解決方案研究報(bào)告
- 二手奢侈品銷售合作協(xié)議書(shū)
- 2025-2030年中國(guó)太陽(yáng)魚(yú)四去行業(yè)深度研究分析報(bào)告
- 體育場(chǎng)館運(yùn)營(yíng)合作合同
- 智能制造升級(jí)項(xiàng)目合同
- IT系統(tǒng)集成項(xiàng)目開(kāi)發(fā)協(xié)議
- 電子商務(wù)平臺(tái)商品質(zhì)量問(wèn)題免責(zé)協(xié)議
- 生產(chǎn)工藝的標(biāo)準(zhǔn)化與規(guī)范化
- 中醫(yī)養(yǎng)生與身心健康課件
- 1、現(xiàn)代生物技術(shù)的概念、涵蓋的領(lǐng)域
- 河道清淤培訓(xùn)課件
- 機(jī)械基礎(chǔ)全冊(cè)教案第四版
- 30題紀(jì)檢監(jiān)察位崗位常見(jiàn)面試問(wèn)題含HR問(wèn)題考察點(diǎn)及參考回答
- 重癥肺炎護(hù)理查房課件文件
- 《瘋狂動(dòng)物城》全本臺(tái)詞中英文對(duì)照
- 大班語(yǔ)言猴子過(guò)河教案反思
- 施耐德變頻器說(shuō)明書(shū)大全
- 同位語(yǔ)從句和定語(yǔ)從句
評(píng)論
0/150
提交評(píng)論