现在的位置: 首页 > 综合 > 正文

Ackmann函数– 动态规划

2013年11月26日 ⁄ 综合 ⁄ 共 2418字 ⁄ 字号 评论关闭

求解ackermann函数  
                    {n+1;                                                 m=0,n>0  
  A(m,n)=     {A(m-1,1);                                       n=0,m>0  
                    {A(m-1,A(m,n-1))                           n>0,m>0  
  求救动态规划算法! 

最简单的方法,用动态规划的备忘录法  
  即使用一个二维数祖A[1..m,1..n]记录所有的ackermann函数值  
  初始的时候全部填充-1,表示尚未计算过  
  然后直接用递归函数计算ackermann函数  
  在递归计算之前,现判断数组A中该函数值是否以被计算过,如果计算过了则直接从数组A中取出结果,不要再做重复计算;如果没有计算过,则递归计算。  
   
  大致的算法过程如下:  
   
  Ackermann(m,   n)  
  1.   if   A[m,n]   >=   0    
  2.         then   return   A[m,   n];  
  3.   else   if   m   =   0   and   n   >   0  
  4.         then   A[m,n]   <-   n   +   1;  
  5.   else   if   n   =   0   and   m   >   0  
  6.         then   A[m,n]   <-   Ackermann(m-1,   1);  
  7.   else   if   n   >   0   and   m   >   0  
  8.         then   A[m,n]   <-   Ackermann(m-1,   Ackermann(m,   n-1));  
  9.   return   A[m,   n];   

Ackermann函数A(m,n)可递归定义如下:
当m=0时,A(m,n)=n+1
当m>0,n=0时,A(m,n)=A(m-1,1)
当m>0,n>0时,A(m,n)=A(m-1,A(m,n-1))

试设计一个计算A(m,n)的动态规划算法,该算法只占用O(m)空间。
 
用两个一维数组,ind[i]和val[i],使得当ind[i]等于t时,val[i]=A(i,ind[i])。
i             ind[i]              val[i]
0            0                  1
1            -1                0
2            -1                0
……
初始时,令ind[0]=0,val[0]=1,ind[i]=-1(i>0),val[i]=0(i>0)。
1当m=0时,A(m,n)=n+1。
任给一个t,当ind[0]=t时,能够求出val[0]的值,val[0]等于ind[0]。
2当n=0,m>0时,A(m,n)=n+1。
能够求出当ind[i]=0时,val[i]的值,此时val[i]等于当ind[i-1]等于1时val[i-1]的值。
3当m>0,n>0时,A(m,n)=A(m-1,A(m,n-1))。
当ind[i]=t,val[i]=s时,要求当ind[i]’=t+1时val[i]’的值。
Val[i]’=A(i,ind[i]’)=A(i-1,A(i,ind[i]’-1)=A(i-1,A(i,ind[i]))=A(i-1,val[i])
所以,当ind[i-1]=val[i]时,能够求出当ind[i]’=k+1时,val[i]’=val[i-1]。
 
#include <stdio.h>
int ack(int& m,int& n)
{
       int i,j;
       int *val=new int[m+1];
       int *ind=new int[m+1];
       for(i=1;i<=m;i++)
       {
              ind[i]=-1;
              val[i]=-1;
       }
       ind[0]=0;
       val[0]=1;
       while(ind[m]<n)
       {
              val[0]++;
              ind[0]++;
              printf("%d ",val[0]);
              for(j=1;j<=m;j++)
              {
                     if(1==ind[j-1])
                     {
                            val[j]=val[j-1];
                            ind[j]=0;
                     }
                     if(val[j]!=ind[j-1])
                            break;
                     ind[j]++;
                     val[j]=val[j-1];
              }
       }
       printf("/n");
       printf("    i   ind[i] val[i]/n");
       for(i=0;i<=m;i++)
              printf("%5d %6d %6d/n",i,ind[i],val[i]);
       return val[m];
}
void main()
{
       int m,n,ak;
       printf("Ackmann(m,n)/nPlease enter m:");
       scanf("%d",&m);
       printf("Please enter n:");
       scanf("%d",&n);
       ak=ack(m,n);
       printf("the Ackmann(%d,%d) is %d/n",m,n,ak);
}

 
 

抱歉!评论已关闭.