Ackermann functionIn the theory of computation, the Ackermann function or Ackermann-Peter function is a simple example of a recursive function that is not primitive recursive. It takes two natural numbers as arguments and yields a natural number, and its value grows extremely quickly. Even for small inputs (4,3, say) the values of the Ackermann function become so large that they cannot be feasibly computed, and in fact their decimal expansions cannot even be stored in the entire physical universe.
HistoryIn 1928, Wilhelm Ackermann, a mathematician studying the foundations of computation, originally considered a function A(m, n, p) of three variables, the p-fold iterated exponentiation of m with n, or m → n → p as expressed using Conway's arrows. When p=2, this is simply mn, m multiplied by itself n times. When p=3, it is a tower of exponents Ackermann proved that A is a recursive function, a function a computer with infinite memory can calculate, but it is not a primitive recursive function, a class of functions including almost all familiar functions such as addition and factorial. This definition was later simplified by Rozsa Peter and Raphael Robinson to the two-variable definition given below. Definition and propertiesThe Ackermann function is defined recursively for non-negative integers m and n as follows: The Ackermann function can be calculated by a simple function based directly on the definition: The following is , a proposed pseudocode for use in many articles: function ack(m, n)
if m = 0
return n+1
else if m > 0 and n = 0
return ack(m-1, 1)
else
return ack(m-1, ack(m, n-1))
The same function can be written partially iteratively as: function ack(m, n)
while m ≠ 0
if n = 0
n := 1
else
n := ack(m, n-1)
m := m - 1
return n+1
It may be surprising that these functions always return a value. This is because at each step either n decreases, or n increases and m decreases. Each time that n reaches zero, m must decrease, so m must eventually reach zero as well. Note, however, that when m decreases there is no upper bound on how much n can increase — and it will often increase greatly. The Ackermann function can also be expressed nonrecursively using Conway's arrow:
or the hyper operators:
For small values of m like 1, 2, or 3, the Ackermann function grows relatively slowly with respect to n (at most exponentially). For m ≥ 4, however, it grows much more quickly; even A(4, 2) is about 2×1019728, and the decimal expansion of A(4, 3) cannot be recorded in the physical universe. If we define the function f (n) = A(n, n), which increases both m and n at the same time, we have a function of one variable that dwarfs every primitive recursive function, including very fast-growing functions such as the exponential function, the factorial function, multi- and superfactorial functions, and even functions defined using Knuth's up-arrow notation. This extreme growth can be exploited to show that f, which is obviously computable on a machine with infinite memory such as a Turing machine and so is a recursive function, grows faster than any primitive recursive function and is therefore not primitive recursive. In combination with the Ackermann function's applications in analysis of algorithms, discussed later, this debunks the theory that all useful or simple functions are primitive recursive functions. One surprising aspect of the Ackermann function is that the only arithmetic operations it ever uses are addition and subtraction of 1. Its properties come solely from the power of unlimited recursion. This also implies that its running time is at least proportional to its output, and so is also extremely huge. In actuality, for most cases the running time is far larger than the output; see below. Table of valuesComputing the Ackermann function can be restated in terms of an infinite table. We place the natural numbers along the top row. To compute a number in the table, you must compute the number immediately to its left, then look at that column in the previous row. If there is no number to its left, simply look at column 1 in the previous row. Here is a small upper-left portion of the table:
If you were able to expand every particle in the universe to a universe the size of ours by snapping your fingers, and likewise with all the particles in the created universes, and did this repeatedly, you would die of old age before the number of particles reached A(4, 3). Note that A(5, 1) is larger than even this number. Despite the inconceivably large values occurring in this early section of the table, some even larger numbers have been defined, such as Graham's number, which cannot be written with any small (or, indeed, recordable) number of Knuth arrows. This number is constructed with a technique similar to applying Ackermann function to itself recursively. Extending the table further to overcome it is like trying the same with the list of natural numbers. ExplanationTo see how the Ackermann function grows so quickly, it helps to expand out some simple expressions using the rules in the original definition. For example, we can fully evaluate A(1, 2) in the following way:
A(1, 2) = A(0, A(1,1))
= A(0, A(0, A(1,0)))
= A(0, A(0, A(0,1)))
= A(0, A(0, 2))
= A(0, 3)
= 4
Now let us attempt the more complex A(4, 3), the first value which cannot be recorded as a decimal expansion in the physical universe:
A(4, 3) = A(3, A(4, 2))
= A(3, A(3, A(4, 1)))
= A(3, A(3, A(3, A(4, 0))))
= A(3, A(3, A(3, A(3, 1))))
= A(3, A(3, A(3, A(2, A(3, 0)))))
= A(3, A(3, A(3, A(2, A(2, 1)))))
= A(3, A(3, A(3, A(2, A(1, A(2, 0))))))
= A(3, A(3, A(3, A(2, A(1, A(1, 1))))))
= A(3, A(3, A(3, A(2, A(1, A(0, A(1, 0)))))))
= A(3, A(3, A(3, A(2, A(1, A(0, A(0, 1)))))))
= A(3, A(3, A(3, A(2, A(1, A(0, 2))))))
= A(3, A(3, A(3, A(2, A(1, 3)))))
= A(3, A(3, A(3, A(2, A(0, A(1, 2))))))
= A(3, A(3, A(3, A(2, A(0, A(0, A(1, 1)))))))
= A(3, A(3, A(3, A(2, A(0, A(0, A(0, A(1, 0))))))))
= A(3, A(3, A(3, A(2, A(0, A(0, A(0, A(0, 1))))))))
= A(3, A(3, A(3, A(2, A(0, A(0, A(0, 2))))))
= A(3, A(3, A(3, A(2, A(0, A(0, 3)))))
= A(3, A(3, A(3, A(2, A(0, 4)))))
= A(3, A(3, A(3, A(2, 5))))
= ...
= A(3, A(3, A(3, 13)))
= ...
= A(3, A(3, 65533))
= ...
We stop here because A(3, 65533) returns 265536-3, a number which is much larger than the number of atoms in the universe, and fully expanding out the expression A(3, 65533) would form a line roughly 1020000 times longer than the diameter of the universe. After this, this number is itself raised as a power of 2 to obtain the final result. InverseSince the function f (n) = A(n, n) considered above grows very rapidly, its inverse function, f−1, grows very slowly. In fact, this function has a value less than 5 for any conceivable input size, since A(4, 4) has a number of digits that cannot itself be written in the physical universe. For all practical purposes, f−1(n) can be regarded as being a constant. This inverse appears in the time complexity of some algorithms, such as the union-find algorithm and Chazelle's algorithm for minimum spanning trees. Sometimes Ackermann's original function or other variations are used in these settings, but they all grow at similarly high rates. In particular, some modified functions simplify the expression by eliminating the −3 and similar terms. Use as benchmarkThe Ackermann function, due to its definition in terms of extremely deep recursion, can be used as a benchmark of a compiler's ability to optimize recursion. For example, a compiler which, in analying the computation of A(3, 30), is able to save intermediate values like the A(3, n) and A(2, n) in that calculation rather than recomputing them, can speed up computation of A(3, 30) by a factor of hundreds of thousands. Also, if A(2, n) is computed directly rather than as a recursive expansion of the form A(1, A(1, A(1,...A(1, 0)...))), this will save significant amounts of time. Computing A(1, n) takes linear time in n. Computing A(2, n) requires quadratic time, since it expands to O(n) nested calls to A(1, i) for various i. Computing A(3, n) requires time proportionate to 4n+1. Note that the computation of A(3, 1) in the example above takes 16 (42) steps. It may be noted that A(4, 2), which appears as a decimal expansion in several web pages, cannot possibly be computed by recursive application of the Ackermann function in any even remotely plausible amount of time. Instead, formulas such as A(3, n) = 8×2n−3 are used to quickly complete some of the recursive calls. References
External links
de:Ackermannfunktion es:Función de Ackermann fr:Fonction d'Ackermann ja:アッカーマン関数
Categories: Computability |
|
This article is licensed under the GNU Free Documentation License. It uses material from Wikipedia article. Browse Wikipedia for more information. |