title: How do I balance a BK-Tree and is it necessary?
body: <p>I am looking into using an <a href="http://en.wikipedia.org/wiki/Edit_distance" rel="nofollow">Edit Distance</a> algorithm to implement a fuzzy search in a name database.</p>
  
  <p>I've found a data structure that will supposedly help speed this up through a divide and conquer approach - <a href="http://en.wikipedia.org/wiki/BK-tree" rel="nofollow">Burkhard-Keller Trees</a>.  The problem is that I can't find very much information on this particular type of tree.</p>
  
  <p><em>If I populate my BK-tree with arbitrary nodes, how likely am I to have a balance problem?</em></p>
  
  <p><em>If it is possibly or likely for me to have a balance problem with BK-Trees, is there any way to balance such a tree after it has been constructed?</em></p>
  
  <p><em>What would the algorithm look like to properly balance a BK-tree?</em></p>
  
  <p><strong>My thinking so far:</strong></p>
  
  <p>It seems that child nodes are distinct on distance, so I can't simply rotate a given node in the tree without re-calibrating the entire tree under it.  However, if I can find an optimal new root node this might be precisely what I should do.  I'm not sure how I'd go about finding an optimal new root node though.</p>
  
  <p>I'm also going to try a few methods to see if I can get a fairly balanced tree by starting with an empty tree, and inserting pre-distributed data.</p>
  
  <ul>
  <li>Start with an alphabetically sorted list, then queue from the middle. (I'm not sure this is a great idea because alphabetizing is not the same as sorting on edit distance).</li>
  <li>Completely shuffled data. (This relies heavily on luck to pick a "not so terrible" root by chance.  It might fail badly and might be probabilistically guaranteed to be sub-optimal).</li>
  <li>Start with an arbitrary word in the list and sort the rest of the items by their edit distance from that item.  Then queue from the middle. (I feel this is going to be expensive, and still do poorly as it won't calculate metric space connectivity between all words - just each word and a single reference word).</li>
  <li>Build an initial tree with any method, flatten it (basically like a pre-order traversal), and queue from the middle for a new tree. (This is also going to be expensive, and I think it may still do poorly as it won't calculate metric space connectivity between all words ahead of time, and will simply get a different and still uneven distribution).</li>
  <li>Order by name frequency, insert the most popular first, and ditch the concept of a balanced tree.  (This might make the most sense, as my data is not evenly distributed and I won't have pure random words coming in).</li>
  </ul>
  
  <p>FYI, I am not currently worrying about the name-synonym problem (Bill vs William).  I'll handle that separately, and I think completely different strategies would apply.</p>