Distributed Minimum Spanning Tree Gallagher, Humblet

Download Report

Transcript Distributed Minimum Spanning Tree Gallagher, Humblet

Distributed Minimum Spanning Tree
Gallagher, Humblet, Spira (1983)
pseudocode adaptation by
Kenneth J. Goldman
September 2002
Two integers:
Process State
•
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
Protocol Message Types
1.
Wakeup -- starts the protocol at a sleeping node
2.
Initiate(core,level) -- broadcast new core/level and start MWOE search
in a fragment
3.
Test(core,level) -- sent on edge E to see if E leads to another fragment
4.
Accept -- response to a Test message indicating a different fragment
5.
Reject -- response to a Test message indicating the same fragment
6.
Report(cost) -- sent up the tree to inform parent of MWOE of subtree
7.
ChangeRoot -- sent from core toward MWOE of fragment, tells the
node with the MWOE to connect across it
8.
Connect(core,level) -- sent over MWOE to combine fragments
9.
Inform(core,level) -- broadcast new core/level to an absorbed fragment
10. AllDone -- broadcast from core to inform nodes of termination
Protocol Message Contents
Each message contains:
1.
Integer type (WAKEUP, INITIATE, TEST, ACCEPT, REJECT, etc.)
2.
The sender node name
3.
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.