给定两个非零整数M和N ,问题是要根据某些特定方程式来计算Ackermann函数的结果。
Ackermann function is defined as:
例子:
Input: M = 2, N = 2
Output: 7
Input: M = 2, N = 7
Output: 6141004759
本文描述的Ackermann函数方法需要花费大量时间来计算较小的(M,N)值,或者在大多数情况下不会产生任何结果。
动态编程方法:
以下是可用于提出有效解决方案的下列Ackermann方程。
A(m, n) = A(m-1, A(m, n-1)) —– (Eq 1)
A(0, n) = n+1 —– (Eq 2)
A(m, 0) = A(m-1, 1) —– (Eq 3)
假设m = 2和n = 2
创建了大小为( (m + 1) x (n + 1) )的2d DP表,用于存储每个子问题的结果。
以下是演示如何填写表格的步骤。
- 空表-初始步骤
-
使用A(0,n)= n + 1填充
接下来的方法是借助equation-2填充所有基本值。 -
在下一步中,将填满整个第一行,
-
A ( 1, 0 ) = A ( 0, 1 ) —– (refer Eq (3))
Since A ( 0, 1 ) = 2
Therefore, A ( 1, 0 ) = 2 —–(Eq 4) -
A ( 1, 1 ) = A ( 0, A ( 1, 0 ) ) —– refer Eq (1)
= A ( 0, 2 ) —– refer Eq (4)
= 3 —– refer Eq (2)
So, A ( 1, 1 ) = 3 —–(Eq 5) -
A ( 1, 2 ) = A ( 0, A ( 1, 1 ) ) —– refer equation (1)
= A ( 0, 3 ) —– refer equation (5)
= 4 —– refer equation (2)
So, A ( 1, 2 ) = 4 —–(Eq 6)
-
- 使用方程式和存储的值填写表格
让我们以与上述相同的方式填充最后一行的第一列,即(2,0) ,因为对于其他两列,还有一些未解决的值。
A ( 2, 0 ) = A ( 1, 1 ) —– refer equation (3)
A ( 1, 1 ) = 3
So, A ( 2, 0 ) = 3 —– (Eq. 7) -
求解A(2,1)和A(2,2)。
为简单起见,解决上述功能的过程分为两个步骤:
- 在第一个中,确定了问题。
A ( 2, 1 ) = A ( 1, A ( 2, 0 ) ) —– refer equation (1)
A ( 2, 0 ) = 3
A ( 2, 1 ) = A ( 1, 3 )So to compute this value, again use equation (1)
A ( 1, 3 ) = A ( 0, A ( 1, 2 ) )
A ( 1, 2 ) = 4
A ( 1, 3 ) = A ( 0, 4 ) —– refer equation(2)
= 5Therefore A ( 2, 1 ) = A ( 1, 3 ) = 5 — (Eq 7)
- 在下一个中,将详细介绍方法,并在程序中使用通用公式时使其具有逻辑性
让我们先付一个理论来解决A(2,2)
A ( 2, 2 ) = A ( 1, A ( 2, 1 ) ) —– refer equation (1)
A ( 2, 1) = 5
A ( 2, 2 ) = A ( 1, 5 )要以通用方式计算A(1,5) ,请观察它如何减少自身!
A ( 1, 5 ) = A ( 0, A ( 1, 4 ) )
A ( 1, 4 ) = A( 0, A ( 1, 3 ) )
A ( 1, 3 ) = A ( 0, A ( 1, 2 ) )
A ( 1, 2 ) = 4Returning back from the function we get,
A ( 1, 3 ) = A ( 0, 4 ) = 5 —– refer equation (2)
A ( 1, 4 ) = A ( 0, A (1, 3 ) ) = A ( 0, 5 ) = 6 —–Since A ( 1, 3 ) = 5
A ( 1, 5 ) = A ( 0, A ( 1, 4 ) ) = A ( 0, 6 ) = 7
So, A ( 2, 2 ) = 7 ——- (Eq 9)
重要事项:
(n = column number, c: ( any number > n), r: row number]
1 . A ( 1, c ) = A ( 1, n ) + ( c – n ) From the Above Observation
2 . A ( r, c ) = A ( r, n ) + ( c – n )*r Based on hand tracing
- 在第一个中,确定了问题。
- 最终表以及每个子问题的结果
下面是上述方法的实现:
Python3
# Python code for the above approach
# Bottum Up Approach
def Ackermann(m, n):
# creating 2D LIST
cache = [[0 for i in range(n + 1)] for j in range(m + 1)]
for rows in range(m + 1):
for cols in range(n + 1):
# base case A ( 0, n ) = n + 1
if rows == 0:
cache[rows][cols] = cols + 1
# base case A ( m, 0 ) =
# A ( m-1, 1) [Computed already]
elif cols == 0:
cache[rows][cols] = cache[rows-1][1]
else:
# if rows and cols > 0
# then applying A ( m, n ) =
# A ( m-1, A ( m, n-1 ) )
r = rows - 1
c = cache[rows][cols-1]
# applying equation (2)
# here A ( 0, n ) = n + 1
if r == 0:
ans = c + 1
elif c <= n:
# using stored value in cache
ans = cache[rows-1][cache[rows][cols-1]]
else:
# Using the Derived Formula
# to compute mystery values in O(1) time
ans = (c-n)*(r) + cache[r][n]
cache[rows][cols] = ans
return cache[m][n]
# very small values
m = 2
n = 2
# a bit higher value
m1 = 5
n1 = 7
print("Ackermann value for m = ", m,
" and n = ", n, "is -> ",
Ackermann(m, n))
print("Ackermann value for m = ", m1,
" and n = ", n1, "is -> ",
Ackermann(m1, n1))
Ackermann value for m = 2 and n = 2 is -> 7
Ackermann value for m = 5 and n = 7 is -> 6141004759
时间复杂度: O(M * N)
辅助空间复杂度: O(M * N)