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); }