Network Formation Protocols for General ZigBee Networks
Theorem 1 The BDDTF problem is NP-complete
3.3 Algorithms for the BDDTF Problem
We propose two algorithms to reduce orphan routers in a ZigBee network. In our algorithms, we will repeatedly generate several BFS trees from Gr. For each tree, we may decide to truncate some nodes if the tree is not conformed to the ZigBee definition. The truncation is done based on nodes’ association priorities in the tree. Below, we show how such priorities are defined.
Given a BFS tree T in Gr:
3
BFS tree link Communication link
B
Figure 3.2: Examples of priority assignment in our algorithm.
• A node x has a higher priority than another node y if the subtree rooted at x in T has more nodes than the subtree rooted at y.
• If the subtrees rooted at nodes x and y have the same number of nodes, the one with less potential parents has a higher priority. A node regards a neighbor as a potential parent if this neighbor has a smaller hop count distance to the root in T than itself.
The above definitions are based on the considerations of address space utilization. The first rule is so defined because node x may have a better utilization. The second rule is so defined because a node with less potential parents may encounter difficulty to attach to the network. For example, in Fig. 3.2, if Rm = 3, the coordinator will choose nodes A, B, and C as its child routers since they have larger subtrees. Similarly, B will choose D, E, and F as its child routers. However, if Rm = 2, the coordinator will choose A and B as its child routers. Further, B will choose D and E as its child routers. Node F is not selected because it has more (two) potential parents and thus has a higher probability to be connected in later stages of the formation.
3.3.1 Centralized Span-and-Prune Algorithm
Given a graph Gr = (Vr, Er), our goal is to find a tree T = (VT, ET) from Gr conforming to the ZigBee tree definition. The algorithm consists of a sequence of iterations. Initially, T contains only the coordinator t. Then in each iteration, there are two phases: Span and Prune.
In the Span phase, we will pick a node in T , say x, and span from x a subtree T to include as many nodes not yet in T as possible. Then we attach T to T to form a larger tree. However, the new tree may not satisfy the ZigBee definition. So in the Prune phase, some of the newly added nodes in T may be trimmed. The resulting tree is then passed to the next iteration for another Span and Prune phases. This is repeated until no more nodes can be added. Each node in the network will be spanned at most once. To keep track of the nodes yet to be spanned, a queue Q will be maintained. The algorithm is presented below.
1. Initially, let queue Q contains only one node t. Let the depth of t to zero. Also, let the initial tree T = ({t}, ∅).
2. (Span Phase) Check if Q is empty. If so, the algorithm is terminated and T is the final ZigBee tree. Otherwise, let x= dequeue(Q) and construct a spanning tree Tfrom x as follows. Assuming the depth of x in T to be depth(x), we try to span a subtree from x with height not exceeding Lm− depth(x) in Gr in a breadth-first manner by including as many nodes in Vr− VT ∪ {x} as possible. Let the resulting tree be T.
3. (Prune Phase) Attach Tto T by joining node x. Still, name the new tree T . Since some of the nodes in T may violate the Rm parameter, we traverse nodes in T from x in a breadth-first manner to trim T .
(a) When visiting a node, say y, set y as “traversed” and check the number of children of y. If y has more than Rm children, we will compute their priorities based on T (refer to the definitions of nodes’ priorities in a tree given in the beginning of this section). Only the Rm highest prioritized children will remain in T , and the other children will be pruned from T .
(b) When each node, say y, that is pruned in step 3(a) or 3(b), let tree(y) be the pruned subtree rooted at y. Since tree(y) is pruned, we will try to attach yto another node n in T if n satisfies the following conditions: 1) n is neighboring to y but not a descendant of y, 2) n is not traversed yet, and 3) depth(n)+1+height(tree(y)) ≤ Lm. If so, we will connect the subtree tree(y) to node n. If there are multiple such candidates, the one with a lower depth is connected first. If no such node n can be found, y prunes all its children. Then for each pruned child, we recursively perform this step 3(b) to try to reconnect it to T. This is repeated until no further reconnection is possible.
4. After the above pruning, call the resulting tree T . For nodes that are newly added into T in step 3, insert them into queue Q in such a way that nodes with lower depth values are inserted first (these nodes will go through Span and Prune phases again). Then, go back to step 2.
To summarize, step 3(a) is to prune those nodes violating the Rm constraint. In order to allow more vertices to join the network, step 3(b) tries to recursively reconnect those pruned subtrees to T. Step 4 prepares newly joining nodes in Q for possible spanning in step 2.
Fig. 3.3 illustrates an example. When being traversed, y decides to prune y and keep A, B, and C as children. Step 3(b) will try to reconnect yto C or D, which are the neighbors of y in T and are not traversed. In this example, only C can be considered because connecting to D violates the depth constraint Lm.
The computational complexity of this algorithm is analyzed as follows. The iteration from step 2 to step 4 will be executed at most |Vr| times. In each iteration, the complexity of constructing the tree T in step 2 is O(N2), where N = |Vr| − |VT|. Step 3 checks all nodes in T and will be executed at most O(N) times. For a run in Step 3 (assume visiting node y), the cost contains: 1) In step 3(a), y can use a linear search method to find Rm highest prioritized children and the computational cost is O(D), where D is the degree of Gr. 2) Since the subtree size of y is at most O(N) and a pruned node checks at most O(D) neighbors
y
A
depth: Lm-3
depth: Lm-2
depth: Lm-1
depth: Lm
C y'
B
D x
t
T
Figure 3.3: An example of the Span-and-Prune algorithm.
to find its new parent, the cost of step 3(b) in a run is O(ND). So, in one iteration, the time complexity of step 3 will be O(N(D + ND)) = O(N2D). Step 4 sorts new nodes of T according to their depth values, so the time complexity is O(N2). The complexity in each iteration is O(N2 + N2D+ N2) = O(N2D) = O(|Vr|2D). Since there are at most |Vr| iterations, the overall time complexity of this algorithm is|Vr| × O(|Vr|2D) = O(|Vr|3D). In practice, the value of N may degrade quickly. So, after several iterations, the time complexity of an iteration will be close to O(1).
3.3.2 Distributed Depth-then-Breadth-Search Algorithm
The above Span-and-Prune algorithm is a centralized one. In this section, we present a distrib-uted algorithm, which does a depth-first search followed by a breadth-first-like search. The depth-first search tries to form some long, thin backbones, which are likely to pass through high-node-density areas. Then from these backbones, we span the tree in a breadth-first-like manner. The algorithm is presented below.
1. (Depth Probing) Given a graph Gr = (Vr, Er), the coordinator t needs to probe the
depth of the tree first. A Probe(sender addr, current depth, Lm) packet is used for this purpose. The Probe packets are flooded in a BFS-like manner, until a depth Lm is reached. Note that following the definition of ZigBee, before the final tree is determined, nodes will use their 64-bit MAC addresses to communicate with each other in this stage.
This algorithm begins by the coordinator t flooding a Probe( Addr(t), 0, Lm) packet in the network, where Addr(t) is t’s address. When a node v receives a Probe(sender addr, current depth, Lm) packet, it does the following:
(a) If this is the first time v receiving a Probe() packet, v sets its parent par(v) = sender addr and its depth depth(v) = current depth + 1. If depth(v) < Lm, v rebroadcasts a Probe(Addr(v), depth(v), Lm) packet.
(b) If this is not the first time v receiving a Probe() packet, it checks if depth(v) >
current depth+1 is true. If so, a shorter path leading to the coordinator is found. So v sets its parent par(v) = sender addr and its depth depth(v) = current depth+1.
If depth(v) < Lm, v rebroadcasts a Probe(Addr(v), depth(v), Lm) packet.
Note that to ensure reliability, a node may periodically rebroadcast its Probe() packet.
And each node can know the number of its potential parents by the Probe() packet.
2. (Probe Response) After the above probing, a BFS-like tree is formed. Each node then reports to its parent a Report() packet containing (i) the size of the subtree rooted by itself and (ii) the height of the subtree rooted by itself. In addition, each node v will compute a tallest child(v), which records the child of v whose subtree is the tallest among all child subtrees.
3. (Backbone Formation) After the coordinator t receives all its children’s reports, it will choose at most Rm children with the larger subtree sizes as backbone nodes. This is done by sending a Backbone() message to each of the selected children. When a node v receiving a Backbone() message, it further invites its child with the tallest sub-tree, i.e., node tallest child(v), into the backbone by sending a Backbone() packet to
tallest child(v). After this phase, t has constructed a backbone with up to Rm subtrees, each as a long, thin linear path.
4. (BFS-like Spanning) After the above backbone formation, the coordinator can broadcast beacons to start the network. A node can broadcast beacons only if it has successfully joined the network as a router (according to ZigBee, this is achieved by exchanging Association Request and Association Response with its parent). In our rule, a backbone node must associate to its parent on the backbone, and its parent must accept the request.
For each non-backbone node, it will compete with each other in a distributed manner by its association priority, where the association priority is defined by the size of the subtree rooted by this node in the BFS-like tree formed in step 1. A non-backbone node sends its association requests by specifying its priority. A beacon sender should wait for association requests for a period of time and sorts the received requests by their priorities. Then the beacon sender can accept the higher-priority ones until its capacity (Rm) is full.
Compared to the ZigBee protocol, this algorithm requires nodes to broadcast two extra packets (Probe() and Report() packet) to accomplish step 1 and step 2. Also, in step 3, an extra Backbone() packet is needed.