3

With different values in a collection, will this algorithm (pseudeocode) ever terminate?

while (curElement != average(allElements))
{
    curElement = average(allElements);
    nextElement();
}

Note that I'm assuming that we will re-start from the beginning if we're at the end of the array.

El Ronnoco
  • 11,753
  • 5
  • 38
  • 65
Franz
  • 11,353
  • 8
  • 48
  • 70
  • 2
    What does nextElement() do and is the allElements() collection constant? – Roy Dictus Feb 10 '12 at 09:48
  • how you are calculating `average(allElements)` – Fahim Parkar Feb 10 '12 at 09:49
  • It depends on your values in that collection. average(allElements) will return fractional values or absolute? – Shashank Kadne Feb 10 '12 at 09:49
  • @RoyDictus: It's supposed to be pseudocode. Just imagine that nextElement() moves the pointer curElement to the next element of the collection, or to the beginning if we're at the end. – Franz Feb 10 '12 at 09:51
  • @RoyDictus: Oh, and allElements will be changed when curElement is set. – Franz Feb 10 '12 at 09:51
  • Your last sentence does already give you the answer: It might not terminate depending on the actual values (at least for *n* > 1 elements). – Gumbo Feb 10 '12 at 09:53
  • @Gumbo: Why? The loop will terminate if the current element equals the average of the collection. – Franz Feb 10 '12 at 09:55
  • @Franz And what if there is no such element? Just think of `(1, 3)` where the average is 2. – Gumbo Feb 10 '12 at 09:57
  • It obviously does not terminate in the case that all elements are equal. – Michael Foukarakis Feb 10 '12 at 10:01
  • I think you want `curElement = nextElement()` [typo?] in the loops, otherwise - the answer is trivial: if you enter the loop once -you exit immidiately, since currElement is defined to be the average – amit Feb 10 '12 at 10:01
  • @amit: no, nextElement() advances curElement to point at the next element. – Franz Feb 10 '12 at 10:06

2 Answers2

5

Since this is pseudocode, a simple example with 2 elements will reveal that there are cases where the program won't terminate:

x = 0, y = 1;

          x     y
Step 1:   0.5   1
Step 2:   0.5   0.75
Step 3:   0.635 0.75
//and so one

With some math involved, lim(x-y) = lim( 1 / 2^n )

So the numbers converge, but they're never equal.

However, if you'd actually implement this on a computer, they will turn out equal because of hardware limitations - not all numbers can be expressed in a limited number of bits.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • There exist arbitrary precision real-number implementations, which would allow for a real-life implementation to run forever. –  Feb 10 '12 at 10:09
  • @bdares I doubt that. They still store the number in memory, and as large as it gets, it's not infinite. – Luchian Grigore Feb 10 '12 at 10:11
  • @LuchianGrigore: You can store the number in disk/remote cluster and expand it on the fly. Theoretically, it can be done. – amit Feb 10 '12 at 10:14
  • Hmmm... good point. @amit any real-life storage is finite, so his argument still holds. –  Feb 10 '12 at 10:15
  • @bdares: (1) You can expand the cluster on the fly, so it is infinite. (2) You could say that the universe will collapse at some point in time, and there are finite number of atoms in the universe, so every implementation of any algorithm is `O(1)` space & time. But I don't think that's what the discussion is about. – amit Feb 10 '12 at 10:18
  • :))) phylosophy.stackexchange.com. Okay then, I think we can all agree that theoretically it will never end, but in practice it will, right? – Luchian Grigore Feb 10 '12 at 10:21
  • I guess it comes down to whether or not we're considering theoretical programs running on theoretical machines (such as the Turing machine, with infinite memory), or a real-life machine with real constraints. –  Feb 10 '12 at 10:23
2

It depends.

If your elements hold discrete values, then most likely they will fall into the same value after a few runs.

If your elements hold limited precision values (such as floats or doubles), then it will take longer, but finite time.

If your elements hold arbitrary precision values, then your algorithm may never finish. (If you count up every piece of an integral and add it to a figure you have on a piece of paper, you need infinite time, an infinitely large piece of paper, and infinite patience with this analogy.)

There is little difference between your code and the following:

var i = 1;
while (i != 0) 
    i = i / 2;

Will it ever terminate? That really depends on the implementation.