180 likes | 311 Views
Distributed Minimum Spanning Tree Gallagher, Humblet, Spira (1983). pseudocode adaptation by Kenneth J. Goldman September 2002. Two integers: status: SLEEPING, SEARCHING, or FOUND (initially SLEEPING) level: the level number of this fragment (initially 0) Three lists of incident edges:
E N D
Distributed Minimum Spanning TreeGallagher, Humblet, Spira (1983) pseudocode adaptation by Kenneth J. Goldman September 2002
Two integers: • status: SLEEPING, SEARCHING, or FOUND (initially SLEEPING) • level: the level number of this fragment (initially 0) • Three lists of incident edges: • basicEdges (initially all incident edges, sorted lowest to highest cost) • rejectedEdges (edges determined not to be in the MST, initially empty) • branchEdges (edges in the MST, initially empty) • Three nodes: • core: the root of the fragment (initially yourself) • parent: the parent node in t (initially null) • minChild: the child reporting the minimum edge so far (initially null) • Additional bookkeeping: • deferredTests: a list of pending Test messages (initially empty) • mwoe: int cost of minimum weight outgoing edge found so far Process State
Protocol Message Types • Wakeup -- starts the protocol at a sleeping node • Initiate(core,level) -- broadcast new core/level and start MWOE search in a fragment • Test(core,level) -- sent on edge E to see if E leads to another fragment • Accept -- response to a Test message indicating a different fragment • Reject -- response to a Test message indicating the same fragment • Report(cost) -- sent up the tree to inform parent of MWOE of subtree • ChangeRoot -- sent from core toward MWOE of fragment, tells the node with the MWOE to connect across it • Connect(core,level) -- sent over MWOE to combine fragments • Inform(core,level) -- broadcast new core/level to an absorbed fragment • AllDone -- broadcast from core to inform nodes of termination
Protocol Message Contents • Each message contains: • Integer type (WAKEUP, INITIATE, TEST, ACCEPT, REJECT, etc.) • The sender node name • Data fields (depending on message, some are omitted): • core – a node name (the core of the sending node’s fragment) • level –an integer (the level number of sending node’s fragment) • cost – an integer (the cost of an edge in the subtree)
M = Wakeup() if SLEEPING // MWOE is the lowest cost basic edge Edge E = the first edge in basicEdges; send "Connect(core,level)" over E; Note: If the node is not sleeping, M is ignored.
M = Initiate(core,level) over E status = SEARCHING; this.core = M.core; this.level = M.level; processDeferredTests(); // when level increases parent = M.sender; mwoe = INFINITY; minChild = null; let waitingForReport contain all branch edges (besides E, if sender != self) send "Initiate(core,level)" over all branch edges (besides E, if sender != self) while (there are basicEdges and mwoe > cost(first basicEdge)) { send "Test(core,level)" over first basicEdge wait for a response (Accept or Reject) }
When Initiate loop is completed and waitingForReport is empty if (parent != self) { status = FOUND; send "Report(mwoe)" to parent; } else if (mwoe < INFINITY) { send "ChangeRoot" to self; } else { send "AllDone" on all branchEdges; }
M = Test(core,level) over E if (this.core == core) // in same fragment send back "Reject" along E; else if (this.level >= level) // another fragment send back "Accept" along E; else // don't know yet put the message into deferredTests;
processDeferredTests() for each message M in deferredTests { if (this.core == M.core) { send "Reject" to M.sender; remove M from deferredTests; } else if (this.level >= level) { send "Accept" to M.sender; remove M from deferredTests; } } Note: This is called whenever the level increases.
M = Accept() over E if (cost(E) < mwoe) { minChild = null; mwoe = cost(E); } Note: Sender is in a different fragment.
M = Reject() over E move E brom basicEdge to rejectedEdges; Note: Sender is already in the same fragment, so E must be an internal edge (not a tree edge).
M = Report(cost) over E remove E from waitingForReport; if (cost < mwoe) { minChild = other endpoint of E; mwoe = cost; }
M = ChangeRoot() over E status = FOUND; if (minChild != null) { send "ChangeRoot" to minChild; } else { move first basicEdge to branchEdge; send "Connect(core,level)" across that edge; }
M = Connect(core,level) over E move E from basicEdges to branchEdges; if (this.level > M.level) { // ABSORB the other if (status == FOUND) // already have MWOE send Inform(core,level) over E; else { // status is SEARCHING add E to waitingForReport; send Initiate(core,level) over E; } } else {// equal levels, so MERGE with the other this.core = maximum end point of E (neighbor) this.level++; processDeferredTests(); // since level changed if (this.core == this) // WE'RE THE NEW CORE send Initiate(this.core,this.level) to self; }
M = Inform(core,level) over E this.core = core; this.level = level; processDeferredTests(); send "Inform(core,level)" over all other branch edges (besides E);
M = AllDone() over E send "AllDone" along all tree edges besides E; The algorithm is finished at this point… Use branchEdges as the edges of the tree. Use the core as the root of the tree.