31.12.2013 Views

Lecture 9: Binary Chop What is Binary Chop about?

Lecture 9: Binary Chop What is Binary Chop about?

Lecture 9: Binary Chop What is Binary Chop about?

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Course: Software Engineering<br />

<strong>Lecture</strong> 9: <strong>Binary</strong> <strong>Chop</strong><br />

Aims and Objectives<br />

• Define the binary chop algorithm for searching sorted arrays.<br />

• Illustrate, through th<strong>is</strong> example,<br />

» the importance of loop invariants for program correctness<br />

» a problem solving method, called divide and conquer.<br />

<strong>Lecture</strong> 9: <strong>Binary</strong> <strong>Chop</strong> Slide Number 1<br />

Course: Software Engineering<br />

<strong>What</strong> <strong>is</strong> <strong>Binary</strong> <strong>Chop</strong> <strong>about</strong>?<br />

Problem: Given a sorted array A of integers and an integer x,<br />

find where<strong>about</strong>s in A the element x occurs.<br />

If A <strong>is</strong>n't sorted, there’d be little alternative to inspecting all<br />

the elements of A one by one until x <strong>is</strong> found.<br />

When A <strong>is</strong> sorted, we can be smarted!<br />

Rough idea:<br />

• Look at the element half way along A.<br />

• If th<strong>is</strong> <strong>is</strong> bigger than x, then x must be in the first half.<br />

• If it <strong>is</strong> smaller, then x must be in the last half.<br />

• Either way, we have cut the search area by a factor of 2.<br />

• Repeat th<strong>is</strong> until x <strong>is</strong> found.<br />

<strong>Lecture</strong> 9: <strong>Binary</strong> <strong>Chop</strong> Slide Number 2<br />

<strong>Binary</strong> chop <strong>is</strong> a very useful algorithm for searching sorted arrays. In th<strong>is</strong> lecture we will show<br />

the process of defining a specification for such algorithm, and the definition of the algorithm<br />

with the reasoning steps needed to prove its correctness with respect to the specification.<br />

The algorithm reflects a fundamental problem solving technique, called divide and conquer,<br />

which cons<strong>is</strong>ts of having a big problem difficult to solve, divide it into several parts, solve<br />

each (smaller) part separately (easier than the original), and hence conquer (i.e. solve) the<br />

original problem.<br />

1<br />

2


Course: Software Engineering<br />

Specification – first attempt<br />

// pre: Sorted(A)<br />

// post: A[result] = x<br />

int Search(int[] A, int x){<br />

…….<br />

}<br />

As usual, result denotes the value returned by the method.<br />

Course: Software Engineering<br />

First Problem – Suppose x <strong>is</strong> not in A?<br />

<strong>What</strong> answer would we like?<br />

» We could look for the boundary between the elements < x and<br />

those > x. Th<strong>is</strong> would allow, for instance, the method Search to be used for<br />

finding where<strong>about</strong>s in A a new element x could be inserted leaving A sorted.<br />

There are two ways of describing th<strong>is</strong> boundary using result<br />

Way 1: A[result] < x and A[result+1] > x<br />

Way 2: A[result–1] < x, and A[result] > x<br />

Look at the array boundaries:<br />

Way 1<br />

Way 2<br />

All elements of A are >x<br />

result = -1.<br />

result = 0<br />

All elements of A are < x<br />

result = (A.length) -1<br />

result = (A.length)<br />

Way 2 <strong>is</strong> our standard: result <strong>is</strong> the smallest index where the array<br />

element <strong>is</strong> > x (or A.length if all the elements are < x).<br />

<strong>Lecture</strong> 9: <strong>Binary</strong> <strong>Chop</strong> Slide Number 3<br />

<strong>Lecture</strong> 9: <strong>Binary</strong> <strong>Chop</strong> Slide Number 4<br />

We assume for the rest of th<strong>is</strong> lecture that the pre-condition Sorted(A) means implicitly that A <strong>is</strong><br />

not null and not empty.<br />

3<br />

Defining a specification of a method with parameters requires thinking <strong>about</strong> all the possible<br />

parameters’ values that can be passed to the method when it’s used in some other part of a program.<br />

So, in the previous slide we have initially thought of defining the result of the method Search to be<br />

the index of the element x in the array. A first problem that the method search could have in<br />

execution <strong>is</strong> when the given array does not include the variable x at all. The post-condition of the<br />

method doesn’t say anything <strong>about</strong> th<strong>is</strong> case. So if we were building the method search using the<br />

specification given in the previous slide our program would not necessarily provide a correct answer<br />

(if any at all!) We need to think then what we want our method to do for the particular case when the<br />

array A does not include x.<br />

A useful thing would be to provide the boundary within the array of where such element should have<br />

been included if it were there. Th<strong>is</strong> would for instance allow the method to be used in other methods<br />

that, for instance, need to include an element in a sorted array.<br />

In th<strong>is</strong> case, we can have two different definitions of post-conditions for Search, one which says that<br />

Search returns the index of an element which <strong>is</strong> smaller than x and such that the next element <strong>is</strong><br />

greater than x (way 1) or that Search returns the index of the first element found that <strong>is</strong> bigger than x<br />

and such that the previous one <strong>is</strong> an element smaller than x (way 2). How can now choose between<br />

these two different post-conditions? Again what we need to do <strong>is</strong> think <strong>about</strong> the possible extreme<br />

cases of values of the parameters. It can well be that the array includes all elements which are<br />

smaller than the given x, or that all its elements are bigger than x. In each of these two cases we need<br />

to see what the boundary values the variable result would assume. Looking at the table given above,<br />

it <strong>is</strong> clear that using (way 1) approach we would get into trouble when the array includes elements all<br />

smaller than x, because the result would be a negative index, Way 2 instead seems to give acceptable<br />

values for result in both extreme case.<br />

We therefore choose the second type of post-condition: The method will return the index of the<br />

smallest element included in A that <strong>is</strong> bigger than x, and in case all elements of A are smaller than x<br />

it will return the length of the array.<br />

4


Course: Software Engineering<br />

Second Problem – <strong>What</strong> <strong>about</strong> if x<br />

occurs more than once in the array?<br />

i. A <strong>is</strong> ordered, so all the occurrences will be together.<br />

» Would we like result to be the index of the first or the last?<br />

ii. Choose the first, so that result <strong>is</strong> the smallest index.<br />

iii. result defines boundary between elements < x and those =x.<br />

iv. Th<strong>is</strong> matches our choice for when x doesn’t occur at all.<br />

So in all possible cases…<br />

r <strong>is</strong> the smallest index where the array element <strong>is</strong> =x,<br />

or A.length if all the elements are < x.<br />

A:<br />

All elements x<br />

0 result (A.length)-1<br />

<strong>Lecture</strong> 9: <strong>Binary</strong> <strong>Chop</strong> Slide Number 5<br />

Course: Software Engineering<br />

SPECIFICATION – FINAL ATTEMPT<br />

int Search(int[] A, int x){<br />

//pre: Sorted(A) i.e.<br />

//i.e. ∀i, j.( 0


Course: Software Engineering<br />

A Rough Diagram<br />

Keep two variables, Left and Right, to show how far we’ve narrowed<br />

the search area. result must be between Left and Right.<br />

A:<br />

Rigth-Left >=1<br />

0<br />

All elements = x<br />

Right<br />

(A.length)-1<br />

Course: Software Engineering<br />

Producing the Code (1)<br />

• Loop Invariant:<br />

(0


Course: Software Engineering<br />

Producing the Code (2)<br />

• Initial<strong>is</strong>ation (establ<strong>is</strong>hing the invariant)<br />

Initially, set:<br />

Left =0;<br />

Right = A.length;<br />

If (A[Left] >= x) then return Left;<br />

// A[Left] < x;<br />

After th<strong>is</strong> initial<strong>is</strong>ation, the invariant <strong>is</strong> sat<strong>is</strong>fied:<br />

• The third line of the loop invariant <strong>is</strong> sat<strong>is</strong>fied, as there no integers i such that<br />

Right


Course: Software Engineering<br />

Producing the Code (4)<br />

• Re-establ<strong>is</strong>hing the invariant (continued)<br />

Three things need still to be proved:<br />

• 0


Course: Software Engineering<br />

Documentation<br />

• All serious programs have to be “documented”, i.e. there has to be a written<br />

explanation of what they do and how they [are supposed to] work.<br />

• Th<strong>is</strong> <strong>is</strong> usually incorporated as comments.<br />

• The comments in Search should show the level of detail that <strong>is</strong> most useful.<br />

• They shouldn’t give a full formal proof, but must show the most important<br />

steps.<br />

• If a formal correctness proof <strong>is</strong> required, the comments indicate how it<br />

would be constructed.<br />

• But even if not, the loop invariant gives a solid framework in which to<br />

understand the working of the program.<br />

• If there’s a suspicion of a m<strong>is</strong>take, or if someone else <strong>is</strong> trying to understand<br />

your code, the framework immediately suggests specific<br />

• Questions: e.g. Does the loop body re-establ<strong>is</strong>h the invariant? Is the<br />

variant decreased each time? Are array accesses OK?<br />

Course: Software Engineering<br />

THE CODE FOR BINARY CHOP<br />

int Search ([int[ ] A, intx){<br />

% Pre: Sorted(A)<br />

%Post:see slide 6<br />

int Left = 0; int Right = A.length; int Middle;<br />

if A[Left] >= x then return Left;<br />

While (Right-Left>1){ //A[Left] < x;<br />

% Loop invariant : see slide 8<br />

% Loop variant = Right – Left – 1<br />

Middle = (Left+Right) div 2; // Left < Middle < Right<br />

if (A[Middle]< x) Left = Middle;<br />

else (Right = Middle);}<br />

return Right<br />

}<br />

<strong>Lecture</strong> 9: <strong>Binary</strong> <strong>Chop</strong> Slide Number 13<br />

<strong>Lecture</strong> 9: <strong>Binary</strong> <strong>Chop</strong> Slide Number 14<br />

13<br />

14


Course: Software Engineering<br />

Conclusion<br />

• The usual pitfall with the binary chop algorithm lies in not<br />

being quite sure what the values of Left and Right are<br />

supposed to mean.<br />

• Making the specification and the loop invariant prec<strong>is</strong>e, and being<br />

careful <strong>about</strong> the difference between < and

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!