540 likes | 701 Views
Minimum Spanning Trees GHS algorithm. Based on “A distributed algorithm for minimum-weight spanning trees” , Gallager, Humblet, Spira 1983. גיא בניי ו-ירון יפה, אלגוריתמים מבוזרים, ינואר 2004. Model. Asynchronous network Network is represented by an undirected connected weighted graph
E N D
Minimum Spanning TreesGHS algorithm Based on “A distributed algorithm for minimum-weight spanning trees”, Gallager, Humblet, Spira 1983 גיא בניי ו-ירון יפה, אלגוריתמים מבוזרים, ינואר 2004
Model • Asynchronous network • Network is represented by an undirected connectedweighted graph • N processors represented by nodes • Distinct weights on edges (more on this, later) • A processor knows weight of edges connected to him • Messages can pass on an edge in both directions concurrently • Some of nodes have awaken • All nodes have same local algorithm • Messages arrive in-order with no errors
Reminder: what is MST? • Given a connected graph G(V,E), a spanning tree is a graph G’(V,E’) that is a tree (and ) • Each edge e of a graph has a weight associated with it, w(e) • Weight of a tree is sum of all edges in tree. • Minimum spanning tree (MST) is the spanning tree with minimum sum
Uses of Spanning Trees • Broadcasting a message in a network where there are different costs associated with edges (i.e. time delay) • Overcoming topological changes in networks • Finding a leader (i.e. the root of the minimum spanning tree)
Why do we need distinct edges? • Consider a 3-clique with equal weights on edges • Each node applies same algorithm • They can either decide to connect or not • The result might be a circle or three disconnected nodes… w w w
Do we really need distinct weights on edges? • Actually, we could settle for distinct node identities. Given an edge e=(v,v’) with weight w, we can just append v and v’ identities to the weight of w, we the lower identity first • Might require another 2*E messages • The appended weights have same ordering as before with ties broken by nodes
Some basics • A fragment of a MST is a subtree of an MST – that is a connected set of nodes and edges of an MST • Algorithm starts with each node as a fragment, and ends with the whole MST as fragment • e=(v,v’) is an outgoing edge from a fragment,if one of its vertices is in the fragment and other is not • A MOE of a fragment F, is the minimal weight outgoing edge from fragment
Lemma 1 • Given a fragment of MST, and e a MOE of the fragment, then joining e and it’s adjacent non fragment node to fragment yields another fragment of MST. • Proof: • Suppose added edge is not part of an MST that contains the fragment. Then adding e will cause a cycle formed by e and some MST edges • at least another edge, x, is an outgoing edge of fragment, with w(x)≥ w(e) • Deleting x from MST and adding e forms a new spanning tree which must be minimal if original was minimal • Hence, original fragment with e added is a fragment of a new MST
Lemma 2 • If all the edges of a connected graph have different weights then the MST is unique • Proof: • Suppose by contradiction there are 2 MST’s, T and T’ • Let e be the minimum edge, e T and e T’ • {e} U T’ must contain a cycle, and at least one edge e’ in cycle isn’t in T • Since edge weights are unique, w(e) < w(e’) • Thus {e} U T’ – {e’} yields a spanning tree with smaller weight than T’ • contradiction
MST Finding Algorithms • Start with one or more fragments consisting of single nodes • Using lemma 1 we can enlarge fragments in any order • Whenever 2 fragments have a common node, lemma 2 guarantees the union is a fragment • Standard algorithms correspond to order in which fragments enlarged and combined: • Prim – start with a single node and enlarge it • Kruskal – start with all nodes as fragments, and extend using smallest weight outgoing edge
GHS - overview • Maintain a partition of G=(V,E) into fragments • Start with each node as a fragment • Nodes in fragment cooperate to asynchronously find their MOE • When MOE is found try to combine with fragment at other side of the MOE • Terminate once only one fragment remains
Required features for efficient implementation • Fragment name: to find MOE of fragment, nodes must be able to test if an edge is outgoing or leads back to fragment, done by comparing fragment name • Combining small fragment to large ones: whenever 2 fragments combine, we must change name in at least one fragment – so smaller adopts larger name • How do we find large fragments? We can’t calculate fragment size as this would require constant updates (and larger communication Complexity) hence we need a different notion instead of size of fragment: a fragment's Level
Level of Fragment • A fragment containing 1 node is at level 0 • Suppose fragment F is at level L (≥0) has a MOE e, and fragment F’ at other side of e is at level L’: • absorb: L < L’ » F is immediately absorbed into F’, and combined fragment is at level L’ • merge: L= L’ and F’ also has e as MOE » F and F’ are combined into a new fragment with level L + 1. e is the “core” of new fragment • Otherwise- F waits until F’ is large enough to combine under above rules. • Why wait? • The problem is finding MOE, and communication involved is proportional to fragment size. So we reduce communication by letting small fragments join larger ones
Example: L=0 L=0 L=0 4 3 L=2 2 L=1 5 1 L=1 L=0 L=0
States in the Algorithm • A node can be in one of the following states: • Sleeping – initial state, before being awoken • Find – participating in finding a MOE in a fragment • Found – already found MOE, waits for change in level • Each node holds a state for each adjacent edge: • Branch – the edge is a branch of the fragment • Rejected – the edge is not a branch, but has been discovered to join two nodes of the fragment. • Basic – unknown yet. • Core – the edge that was used in the last merge (i.e. the MOE that connected 2 equal-level fragments). The weight of the core will be the ID of the fragment • Node Core’s – nodes connecting core
Local variables in each node • Each node stores these local variables: • nodes current state • state of edges • name of it’s fragment • level of it’s fragment • MOE • inbound edge – points to “father” of node in fragment • best-edge: edge from which candidate for new MOE arrived
Type of messages sent • test (fragment ID, fragment Level): is this edge an outgoing edge? • accept: positive response to test • reject: negative response to test • initialize (newID, newLevel, newState): begin new search for MOE, or change ID and Level. • connect(Level): found the MOE of fragment. Try joining adjacent fragment • report(weight): report upwards what you think MOE’s weight is • change-core: message from the core nodes to the node holding the MOE – try to connect
Finding the MOE • Finding the MOE in a zero-level fragment (single node): • find the minimum weight adjacent edge (trivial) • mark it as “branch” • send a “connect” message over it • Change state to “found”
Finding the MOE (cont.) • Let F be a new fragment of level L that has just been formed by merging two fragments of level L-1 that have same MOE, e • e becomes core of new fragment (=it’s name) • L is new level of fragment • 2 nodes adjacent to core send “initiate” message to other nodes in fragment • message contains new fragments name, and level • message is relayed outward on “branch” edges
Finding the MOE (cont.) • once a node in fragment gets message, state changes to “find” • If other fragments in level L-1 are waiting to connect to nodes of new level L fragment, initiate is passed to them too joining them to fragment • And is passed on to other L-1 fragments waiting to connect to previous L-1 levels and so forth • When a node gets the message “initiate” starts finding it’s MOE
Finding the MOE (cont.) • But how does node know which edge is outgoing? • The node picks it’s minimum-weight “basic” edge, and sends a “test” message over it • The “test” message carries the fragment’s ID and level • The node receiving “test” message: • Checks it’s own fragment’s ID*, if same, send message reject, and both nodes classify the edge as “rejected”. Then the sending node continues with the next minimum-weight “basic” edge. • If the receiving node has different ID, and it’s level is greater than or equal to that of the test message, it sends “accept” * Except if a node sends and then receives test message with the same ID on the same edge, it simply rejects the edge without the “reject” message. This reduces the communication complexity slightly.
Finding the MOE (cont.) • If the receiving node has different ID, and it’s level is less than that of the test message, it delays making any response until it’s own level increases sufficiently • The main reason for this delay is that after a low level fragment combines to a high level one, its nodes don’t know about the change for an uncertain time (until “initiate”). • Observations: • The fragment ID changes only when the fragment level increases • Furthermore, a given fragment ID will occur at only one fragment level • Conclusion: when node A sends an accept message as response to B’s test, then the fragment ID of A differs, and will continue to differ from B’s current fragment ID.
Finding the MOE (cont.) • Now, after every node in the fragment knows its own minimal outgoing edge, they need to coordinate to find the MOE of the whole fragment • The cooperation is done by sending the “report” message. • Each leaf node (node adjacent to only one fragment branch), sends the message “report” on its inbound branch. The message carries the node’s minimum-weight outgoing edge (or ∞ if none)
Finding the MOE (cont.) • Similarly, each other node of the fragment waits until it gets the “report” from all of the non-inbound branches, so it can decide what the MOE of its subtree is. After that, it sends “report” on its inbound branch, and saves the edge that leads to the MOE as “best-edge” • When a node sends “report” message, its state changes to “found” • When the two nodes adjacent to the core send “report” on the core itself, each of the core nodes can determine what and where the MOE is. If no MOE received (∞ from every core node), then we finished.
So we found MOE… • After finding the MOE, the path to it can be reproduced by the “best-edges” • The message “change-core” is sent on that path • When “change-core” reaches the node with the MOE (which now became the root of the fragment), it sends message “connect” over MOE, which carries the level of the fragment
Response to connect • If two fragments with same level L both sent “connect” over the same edge (same MOE for both fragments), then this edge becomes the core of a new fragment, with level L+1, and “initiate” message is sent with the new ID and level to spread the gospel • When the “connect” message was sent from a node in a low level fragment to a node in a higher level fragment, it responds immediately with message “initiate”, and absorbs the low-level fragment • if the receiver node had not sent “report” in this level, then the low-level fragment participates in finding the MOE • If the receiver node already sent “report”, new occupied fragment’s nodes will be initiated in “found” state, because the newly absorbed fragment can’t bring a new MOE
Outline of proof… • From lemma 1 and lemma 2 – sufficient to show that algorithm really finds MOE of fragments, and that it doesn’t reach a deadlock • The previous discussion should convince that the edge on which a message connect(L) is sent, is indeed the MOE of fragment L corresponding to all nodes that received in “initiate” fragment’s ID
No deadlocks… • Lets assume the algorithm has started but hasn’t finished, and lets look at set of fragments – except zero level fragments with sleeping nodes - in existence at any time • Each fragment has a MOE • Lets look at the lowest level of fragments, and that with smallest MOE • Any test message on that edge will either wake a sleeping node or will be responded immediately • Similarly, a connect message on that edge will either: • wake up a sleeping node • go to a higher level fragment and will be responded immediately with initiate • go to a fragment with same level and same MOE leading to a new higher level fragment
Communication cost analysis • number of levels: • each fragment of level L+1 is created by merging two fragment of level L • hence, a level L fragment has at least 2^L nodes • so, num of levels is maximum log2N • If number of nodes is initially unknown, we need at least E messages. If there is an edge over which no message is sent, any algorithm might fail
Communication cost analysis • an edge can be rejected only once – at most 2*E messages leading to rejection • When a node is any level except first and last it can: • receive at most 1 initiate message, 1 accept message • transmit at most – 1 test, 1 report, 1 (change-root | connect) • total of 5 *N* (log(N)-1) • At level 0, a node can: • receive at most 1 initiate • send at most 1 connect • total of 2N • At last level a node can send at most 1 report level • Total of 1N • All together bound by: 2*E + 5*N*logN
Time analysis – worst case 0 1 2 3 N-3 S S’ S originally awoken
Time analysis • It is preferable to wake up first all nodes (takes N-1 time units) • By time N all nodes are awaken and have sent connect messages • By time 2N all nodes are at level 1 • By induction: it takes at most 5lN-3N time units until all nodes are at level l • For l=1 see above… • Assume it true for l • At level l, each node can send at most n test messages which will be answered before 5lN-N. • The propagation of the report, change-root, connect and initiate messages can take at most 3N units, so by 5(l+1)N-3N the level l+1 is updated in all nodes. • l≤log2N, so the algorithm will be complete by time 5Nlog2N
The Algorithm • (1) Response to spontaneous awakening (can occur only at a node in the sleeping state) • execute procedure wakeup • (2) procedure wakeup • begin let m b adjacent edge of minimum weight; • SE(m)<-Branch; • LN<-0; • SN<-Found; • Find-count<-0; • send Connect(0) on edge m; • end
The Algorithm (cont.) • (3) Response to receipt of Connect (L) on edge j • begin if SM=Sleeping then execute procedure wakeup; • if L<LN • then begin SE(j)<-Branch; • send Initiate(LN,FN,SN) on edge j; • if SN=Find then find-count<-find-count+1; • end • else if SE(j)=Basic • then place received message on end of queue • else send Initiate(LN+1,w(j),Find) on edge j • end
The Algorithm (cont.) • (4) Response to receipt of Initiate(L,F,S) on edge j • begin LN<-L; FN<-F; in-branch<-j; • best-edge<-nil; best-wt<-∞; • for all i≠j such that SE(i)=Branch • do begin send Initiate(L,F,S) on edge i; • if S=Find then find-count<-find-count+1; • end • if S=Find then execute procedure test • end
The Algorithm (cont.) • (5) procedure test • if there are adjacent edges in the state Basic • then begin test-edge<-the minimum-weight edge in the state Basic; • send Test(LN,FN) on test-edge • end • else begin test-edge<-nil; • execute procedure report; • end
The Algorithm (cont.) • (6) Response to receipt of Test(L,F) on edge j • begin if SN=Sleeping then execute procedure wakeup; • if L>LN then place received message on end of queue • else if F≠FN then send Accept on edge j • else begin if SE(j)=Basic then SE(j)<-Rejected; • if test-edge≠j then Reject on edge j • else execute procedure test • end • end
The Algorithm (cont.) • (7) Response to receipt of Accept on edge j • begin test-edge<-nil; • if w(j)<best-wt • then begin best-edge<-j; best-wt<-w(j) end; • execute procedure report; • end
The Algorithm (cont.) • (8) Response to receipt of Reject on edge j • begin if SE(j)=Basic then SE(j)<-Rejected; • execute procedure test; • end • (9) procedure report • if find-count=0 and test-edge=nil • then begin SN<-Found; • send Report(best-wt) on in-branch • end
The Algorithm (cont.) • (10) Response to receipt of Report(w) on edge j • if j≠in-branch • then begin find-count<-find-count-1; • if w<best-wt then begin best-wt<-w; best-edge<-j; end • execute procedure report • end • else if SN=Find then place received message on end of queue • else if w>best-wt • then execute procedure change-root • else if w=best-wt=∞ then halt
The Algorithm (cont.) • (11) procedure change-root • if SE(best-edge)=Branch • then send Change-root on best-edge • else begin send Connect(LN) on best-edge; • SE(best-edge)<-Branch • end • (12) Response to receipt of Change-root • execute procedure change-root
Example… 1 1 0 2 9 5 12 14 8 8 3 4 3 6 initiate connect 2 10 5 13 11 9 6 4 7 7
Example… 1 1 0 2 9 5 12 14 8 8 3 4 3 connect test 6 L=1 2 10 5 13 11 9 6 4 7 7
Example… 1 1 0 2 9 5 12 14 8 8 test 3 4 3 6 L=1 initiate 2 10 5 13 11 connect 9 6 4 connect 7 7
Example… L=1 1 1 0 2 9 connect 5 12 14 8 8 3 4 3 6 L=1 reject 2 10 test 5 13 11 initiate 9 6 4 7 7
Example… L=1 1 1 0 initiate connect 2 9 5 12 14 8 8 test 3 4 3 6 2 10 5 13 11 test L=1 9 6 4 test 7 7
Example… L=1 1 1 0 L=1 2 9 5 12 14 8 8 3 4 3 6 2 10 5 13 11 L=1 9 6 4 initiate 7 7
Example… L=1 1 1 0 L=1 2 test 9 initiate 5 12 14 8 8 3 4 3 6 2 10 5 13 accept 11 L=1 L=1 9 6 4 reject report 7 7
Example… L=1 1 1 L=1 0 L=1 2 9 test reject 5 12 14 8 accept test 8 test initiate connect 3 accept test 4 3 6 report 2 10 5 13 11 test L=1 9 6 4 7 7
Example… L=1 1 1 L=1 0 accept 2 9 report accept test 5 12 14 8 8 reject accept connect 3 4 3 6 report 2 test 10 5 13 11 accept L=1 report L=1 9 6 4 7 7