33

As seen on Introduction to Algorithms (http://mitpress.mit.edu/algorithms), the exercise states the following:

Input: Array A[1..n] and a value v

Output: Index i, where A[i] = v or NIL if v does not found in A

Write pseudocode for LINEAR-SEARCH, which scans through the sequence, looking for v. Using a loop invariant, prove that your algorithm is correct. (Make sure that your loop invariant fulfills the three necessary properties – initialization, maintenance, termination.)

I have no problem creating the algorithm, but what I don't get is how can I decide what's my loop invariant. I think I understood the concept of loop invariant, that is, a condition that is always true before the beginning of the loop, at the end/beginning of each iteration and still true when the loop ends. This is usually the goal, so for example, at insertion sort, iterating over j, starting at j = 2, the A[1..j-1] elements are always sorted. This makes sense to me. But for a linear search? I can't think of anything, it just sounds too simple to think of a loop invariant. Did I understand something wrong? I can only think of something obvious like (it's either NIL or between 0 and n). Thanks a lot in advance!

Student
  • 769
  • 1
  • 6
  • 11
Clash
  • 4,485
  • 9
  • 42
  • 63

7 Answers7

19

After you have looked at index i, and not found v yet, what can you say about v with regard to the part of the array before i and with regard to the part of the array after i?

Svante
  • 46,788
  • 11
  • 77
  • 118
  • v is not from 1 to i but could be after i, can this be a loop invariant? – Clash Apr 07 '11 at 17:31
  • ok, that wouldnt make sense... how about, v is not from [1...i], but this wouldn't be valid for the initialization of the loop, as i=1 and I cannot guarantee that v is not the first element. But I can't use negative bounds either, right? – Clash Apr 07 '11 at 17:37
  • Clash, take a look at my answer below. – Larry Watanabe Apr 07 '11 at 17:44
  • 1
    @Clash: Your first attempt does look sensible. My hint would better be formulated as "Before you look at `A[i]` ...", so that the invariant holds at the _start_ of the loop. – Svante Apr 07 '11 at 17:54
  • for a new variable k < i, all the elements from A until index k are not v But I still find it weird, as if i is 0, this would mean k=-1, which does not exist in A... is there a way to formulate this better? Or is it no problem, that k=-1? Can I then say, A[0...i-1] is not v? Even though it would be representing an impossible vector (for i=0)? Like A[0 ... -1] – Clash Apr 07 '11 at 20:44
  • 1
    @Clash: Your exercise text seems to imply a 1-based array. `i` then goes from `1` to `n`. If you initialize `i` to `1`, then check `A[i]`, and finally increase `i`, your loop invariant holds for any array index smaller than `i`. If there is no valid array index smaller than `i`, it trivially holds—anything is true for the empty set. – Svante Apr 07 '11 at 22:49
  • 6
    @Clash: that's not really a problem. Remember, this is pseudocode and math, not actual code on actual machines. If you assume the notation A[l...u] represents `{ A[i], ∀i i>=l ∧ i <= u }`, then A[0...-1] would represent an empty set. Saying that v is not on the empty set is true, so it holds at the beginning. – R. Martinho Fernandes Apr 08 '11 at 08:52
  • Great, that was my doubt. Thanks guys! – Clash Apr 08 '11 at 18:15
17
LINEAR-SEARCH(A, ν)
1  for i = 1 to A.length
2      if A[i] == ν 
3          return i
4  return NIL 

Loop invariant: at the start of the ith iteration of the for loop (lines 1–4),

∀ k ∈ [1, i) A[k] ≠ ν.  

Initialization:

i == 1 ⟹ [1, i) == Ø ⟹ ∀ k ∈ Ø A[k] ≠ ν,

which is true, as any statement regarding the empty set is true (vacuous truth).

Maintenance: let's suppose the loop invariant is true at the start of the ith iteration of the for loop. If A[i] == ν, the current iteration is the final one (see the termination section), as line 3 is executed; otherwise, if A[i] ≠ ν, we have

∀ k ∈ [1, i) A[k] ≠ ν and A[i] ≠ ν ⟺ ∀ k ∈ [1, i+1) A[k] ≠ ν,

which means that the invariant loop will still be true at the start of the next iteration (the i+1th).

Termination: the for loop may end for two reasons:

  1. return i (line 3), if A[i] == ν;
  2. i == A.length + 1 (last test of the for loop), in which case we are at the beginning of the A.length + 1th iteration, therefore the loop invariant is

    ∀ k ∈ [1, A.length + 1) A[k] ≠ ν ⟺ ∀ k ∈ [1, A.length] A[k] ≠ ν
    

    and the NIL value is returned (line 4).

In both cases, LINEAR-SEARCH ends as expected.

Joyce
  • 171
  • 1
  • 3
8

In the case of linear search, the loop variant will be the backing store used for saving the index(output) .

Lets name the backing store as index which is initially set to NIL.The loop variant should be in accordance with three conditions :

  • Initialization : This condition holds true for index variable.since, it contains NIL which could be a result outcome and true before the first iteration.
  • Maintenance : index will hold NIL until the item v is located. It is also true before the iteration and after the next iteration.As, it will be set inside the loop after comparison condition succeeds.
  • Termination : index will contain NIL or the array index of the item v.

.

ani07
  • 148
  • 1
  • 9
5

Loop invariant would be

forevery 0 <= i < k, where k is the current value of the loop iteration variable, A[i] != v

On loop termination:

if A[k] == v, then the loop terminates and outputs k

if A[k] != v, and k + 1 == n (size of list) then loop terminates with value nil

Proof of Correctness: left as an exercise

Larry Watanabe
  • 9,690
  • 9
  • 39
  • 45
  • Does this hold true for the initialization? 0 <= i < k would mean that i at the initialization is empty, null or something like that? – Clash Apr 07 '11 at 18:19
  • I can't prove it because I don't have your code. But, I would have an if-then-else statement inside my loop saying something like if A[i[ == v, return i. Then I could prove the initialization case for my code: k = 0. Either A[i] == v, in which case my loop terminatees and outputs k. Conversely, if A[i] != v, the for all 0 <= i <= 0, A[i] != v. – Larry Watanabe Apr 07 '11 at 22:56
  • `0 <= i < k` holds for the initial iteration of the loop since you will get an empty array, which, in fact, does not include `v`, hence the condition is true _before the initial execution of the loop_. – fnisi Jun 05 '19 at 09:02
2

Assume that you have an array of length i, indexed from [0...i-1], and the algorithm is checking if v is present in this array. I'm not totally sure, but I think, the loop invariant is as follows: If j is the index of v, then [0..j-1] will be an array that does not have v.

Initialization : Before iterating from 0..i-1, the current array checked (none), does not consist of v.

Maintenance : On finding v at j, array from [0..j-1] will be an array without v.

Termination : As the loop terminates on finding v at j, [0..j-1] will be an array without j.

If the array itself does not have v, then j = i-1, and the above conditions will still hold true.

1

The invariant for linear search is that every element before i is not equal to the search key. A reasonable invariant for binary search might be for a range [low, high), every element before low is less than the key and every element after high is greater or equal. Note that there are a few variations of binary search with slightly different invariants and properties - this is the invariant for a "lower bound" binary search which returns the lowest index of any element equal to or greater than the key.

Source:https://www.reddit.com/r/compsci/comments/wvyvs/what_is_a_loop_invariant_for_linear_search/

Seems correct to me.

Prashant N
  • 11
  • 1
0

The LS algorithm that I wrote is-

LINEARSEARCH(A, v)
  for i=0 to A.length-1
    if(A[i] == v)
      return i
  return NIL

I made my own assumptions for loop invariant for checking correctness of Linear Search:

  1. At Initialisation- at i = 0, we are searching for v at i = 0.

  2. At successive iterations- we are looking for v till i < A.length-1

  3. At termination- i = A.length and till A.length we kept looking for v.

Bhargav Rao
  • 41,091
  • 27
  • 112
  • 129