动态规划

1装配线调度:一个汽车公司有两套装配线,每条装备线各有6个装配站,每个装配站完成装配需要一定的时间,两条装配线对应的站完成相同的功能,但所用的时间不一定相等。现在希望找出完成装配用的最少的装配站点。

分析:经过第1条线的第N个装配站的最短的路径可能是从第一条线的第N-1个装配站送过去的,也可能由第二条线的第N-1个装配站送过去的,不管是从哪条线的第N-1个站送过来的,这个路径一定是经过该N-1站的最短路径,如果不是,那么就会有更短的路径从N-1站到达N装配站

View Code
#include<IOSTREAM.H>
typedef struct Point
{
    int x;int y;
}Point;
void main()
{
    int t[2][5]={{2,3,1,3,4},{2,1,2,2,1}};
    int s[2][6]={{7,9,3,4,8,4},{8,5,6,4,5,7}};
    int e[2]={2,4},x[2]={3,2};
    Point A[7],B[7];
    int sum1=e[0]+s[0][0];A[0].x=0;A[0].y=0;
    int sum2=e[1]+s[0][1];B[0].x=1;B[0].y=0;
    for (int i=1;i<6;i++)
    {
        int temp1=sum1,temp2=sum2;
        temp1=(sum1+s[0][i])<(sum2+t[1][i-1]+s[0][i])?(A[i].x=0,A[i].y=i,sum1+s[0][i]):(A[i].x=1,A[i].y=i,sum2+t[1][i-1]+s[0][i]);
        temp2=(sum2+s[1][i])<(sum1+t[0][i-1]+s[1][i])?(A[i].x=1,A[i].y=i,sum2+s[1][i]):(A[i].x=0,A[i].y=i,sum1+t[0][i-1]+s[1][i]);
        sum1=temp1;
        sum2=temp2;
    }
    if(sum1+x[0]<sum2+x[1])
    {
        cout<<sum1+x[0]<<endl;
        A[6].x=0;A[6].y=6;
        for (int i=1;i<7;i++)
        {
            cout<<A[i].x<<","<<A[i].y<<"  ";
        }
        cout<<endl;
    }
    else
    {
        cout<<sum2+x[1]<<endl;
        B[6].x=1;B[6].y=6;
        for (int i=1;i<7;i++)
        {
            cout<<B[i].x<<","<<B[i].y<<"  ";
        }
        cout<<endl;
    }
    
}

2、矩阵链乘法

为说明由不同的加全部括号顺序所带来的矩阵成绩的代价不同,考虑三个矩阵相乘(A1,A2,A3),假设三个矩阵的维数分别为10*100,100*5,5*50。如果按照((A1,A2)A3)的次序来做乘法,求10*5的矩阵A1A2要做10*100*5=5000次的标量乘法运算,再乘上A3还要做10*5*50=2500次标量乘法,总共7500次的标量乘法。如果按照(A1(A2A3))的次序来计算,则为求100*50的矩阵乘积A2A3要做100*5*80=25000次的标量乘法,再乘上A1还要10*100*50=50000次标量乘法,总共需要75000次标量乘法运算,这就清楚的看到了乘法顺序对矩阵运算产生的巨大影响。

那么如何才能使得标量运算量降到最低呢,同样用动态规划进行分析:

采用自底向上的方法

View Code
#include<IOSTREAM.H>
#include <IOMANIP.H>
//矩阵链乘积的递归解法
/*
// int fun(int *p,int (*m)[7],int i,int j)
// {
//     int sum=11111111;
//     if(i==j) return m[i][i];
//     int index;
//     for (int k=i;k<j;k++)
//     {
//         int temp=fun(p,m,i,k)+fun(p,m,k+1,j)+p[i-1]*p[k]*p[j];
//         if(temp<sum)
//         {
//             index=k;
//             sum=temp;
//         }
//     }
//     m[i][j]=index;
//     //cout<<index<<endl;
//     return sum;
// }
// void main()
// {
//     int p[7]={30,35,15,5,10,20,25};
//     int m[7][7]={0};
//     for (int i=0;i<7;i++)
//     {
//         m[i][i]=0;
//     }
//     cout<<fun(p,m,1,6)<<endl;
//     for (i=1;i<7;i++)
//     {
//         for (int j=1;j<7;j++)
//         {
//             cout<<m[i][j]<<"  ";
//         }
//         cout<<endl;
//     }
// 
// }
*/
void rusult(int (*n)[7],int i,int j)
{
    if (i==j) cout<<"A"<<i;
    else
    {
        cout<<"(";
        rusult(n,i,n[i][j]);
        rusult(n,n[i][j]+1,j);
        cout<<")";
    }
    
}
//矩阵链乘的动态规划
void main()
{
    int p[7]={5,10,3,12,5,50,6};//矩阵A1:5*10 A2:10*3 A3:3*12等等相乘
    int m[7][7]={0};
    int n[7][7]={0};
    for (int len=1;len<7;len++)
    {
        for (int i=1;i<=7-len;i++)
        {
            if(len==1) m[i][i]=0;
            else
            {
                int sum=111111;
                int index;
                for (int k=i;k<len+i-1;k++)
                {
                    int temp=m[i][k]+m[k+1][len+i-1]+p[i-1]*p[k]*p[len+i-1];
                    if (temp<sum)
                    {
                        index=k;
                        sum=temp;
                    }
                }
                m[i][i+len-1]=sum;
                n[i][i+len-1]=index;
            }
        }
    }
    /*for (int i=1;i<7;i++)
    {
        for (int j=1;j<7;j++)
        {
            cout<<setw(6)<<m[i][j];
        }
        cout<<endl<<endl;
    }*/
    for ( int i=1;i<7;i++)
    {
        for (int j=1;j<7;j++)
        {
            cout<<setw(6)<<n[i][j];
        }
        cout<<endl<<endl;
    }

    rusult(n,1,6);

}

posted on 2012-10-31 10:30  为梦飞翔  阅读(220)  评论(0编辑  收藏  举报

导航