[TopCoder Algorithm Tutorial] Binary Search

http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=binarySearch


Binary Search


What we can call the main theorem states that binary search can be used if and only if for all x in S, p(x) implies p(y) for all y > x. This property is what we use when we discard the second half of the search space. It is equivalent to saying that ¬p(x) implies ¬p(y) for all y < x (the symbol ¬ denotes the logical not operator), which is what we use when we discard the first half of the search space.


If the condition in the main theorem is satisfied, we can use binary search to find the smallest legal solution, i.e. the smallest x for which p(x) is true. The first part of devising a solution based on binary search is designing a predicate which can be evaluated and for which it makes sense to use binary search: we need to choose what the algorithm should find. We can have it find either the first x for which p(x) is true or the last x for which p(x) is false. ... The second part is proving that binary search can be applied to the predicate. This is where we use the main theorem, verifying that the conditions laid out in the theorem are satisfied.


... many problems can't be modeled as searching for a particular value, but it's possible to define and evaluate a predicate such as"Is there an assignment which costs x or less?", when we're looking for some sort of assignment with the lowest cost. ... This is called reducing the original problem to a decision (yes/no) problem.


One important thing to remember before beginning to code is to settle on what the two numbers you maintain (lower and upper bound) mean. A likely answer is a closed interval which surely contains the first x for which p(x) is true. All of your code should then be directed at maintaining this invariant: it tells you how to properly move the bounds, which is where a bug can easily find its way in your code, if you're not careful.


... Keep your eye out for overflow errors all around, especially in calculating the median.


binary_search(lo, hi, p):
   while lo < hi:
      mid = lo + (hi-lo)/2
      if p(mid) == true:
         hi = mid
      else:
         lo = mid+1
          
   if p(lo) == false:
      complain                // p(x) is false for all x in S!
      
   return lo         // lo is the least x for which p(x) is true


If we wanted to find the last x for which p(x) is false, we would devise (using a similar rationale as above) something like:

WARNING: Mind the BUG below!


// warning: there is a nasty bug in this snippet!
//The solution is to change mid = lo + (hi-lo)/2 to mid = lo + (hi-lo+1)/2, i.e. so that it rounds up instead of down.
binary_search(lo, hi, p):
   while lo < hi:
      mid = lo + (hi-lo)/2    // note: division truncates
      if p(mid) == true:
         hi = mid-1
      else:
         lo = mid
          
   if p(lo) == true:
      complain                // p(x) is true for all x in S!
      
   return lo         // lo is the greatest x for which p(x) is false


Just remember to always test your code on a two-element set where the predicate is false for the first element and true for the second.


You may also wonder as to why mid is calculated using mid = lo + (hi-lo)/2 ... Coding the calculation this way ensures that the number divided is always positive and hence always rounds as we want it to.


SUMMARY

  • Design a predicate which can be efficiently evaluated and so that binary search can be applied
  • Decide on what you're looking for and code so that the search space always contains that (if it exists)
  • If the search space consists only of integers, test your algorithm on a two-element set to be sure it doesn't lock up
  • Verify that the lower and upper bounds are not overly constrained: it's usually better to relax them as long as it doesn't break the predicate


TopCoder Problems

Simple
AutoLoan - SRM 258
SortEstimate - SRM 230

Moderate
UnionOfIntervals - SRM 277
Mortgage - SRM 189
FairWorkload - SRM 169 (Example used in tutorial.Solution available.)
HairCuts - SRM 261

Harder
PackingShapes - SRM 270
RemoteRover - SRM 235
NegativePhotoresist - SRM 210
WorldPeace - SRM 204
UnitsMoving - SRM 278
Parking - SRM 236
SquareFree - SRM 190
Flags - SRM 147


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值