动态规划问题一:装配线调度问题
装配线调度问题是动态规划的经典问题:一个汽车底盘在进入每一条装配线后,在装配站中会在底盘安装部件,然后完成装配的汽车在装配线末端离开。每条装配线有n个装配站,编号为
对于一些加急订单,底盘仍然需要经过n个装配站,但是为了加快装配速度,允许将部分完成的汽车在任何装配站上从一条装配线转移到另外一条。我们把已经通过装配站
举个具体的例子来说明并求解问题:
问题划分
动态规划方法第一步是描述最优解的结构的特征
此问题(找出通过装配站
对于子问题一
(1)通过装配站
(2)通过装配站
同理,通过装配站
(1)通过装配站
(2)通过装配站
递归求解分析
动态规划方法第二步是利用子问题的最优解来递归定义的一个最优值。
令
要对
考虑计算
得到递推公式:
算法实现
计算最快时间和构造最快路线的C语言实现如下:
#include <stdio.h>
void main(){
/*time consumption of assembly in every station of two saaembly lines( six stations in each line)*/
int S[2][6]={{7,9,3,4,8,4},{8,5,6,4,5,7}};
/*initialization time of each assemly line*/
int e[2]={2,4};
/*time cost of transfer parts from line 1 to line 2 and in the opposite direction*/
int T[2][5]={{2,3,1,3,4},{2,1,2,2,1}};
//time comsumption of delivery components out from the two lines
int x[2]={3,2};
//the least time comsumption from starting point to each station
int f[2][6]={{0,0}};
int L[2][5]={{0,0}};//record the moving path;
int Path[6][2]={{0,0}};//the final path (station,line)
int i=0,j=0,f_final=0,k11,k12,k21,k22,L_end;
f[0][0]=e[0]+S[0][0];
f[1][0]=e[1]+S[1][0];
//stations on line 1
for(i=1;i<6;i++){
k11=f[0][i-1] + S[0][i]; //from one station to next on the same line 1
k21=f[1][i-1] + S[1][i]; //from one station to next on the same line 2
k12=f[1][i-1] + T[1][i-1] + S[0][i];// from one station of line 2 to the one of line 1
k22=f[0][i-1] + T[0][i-1] + S[1][i];// from one station of line 1 to the one of line 2
if(k11<k12){ //find the most time-saving road
f[0][i]=k11;
L[0][i-1]=1;
}else{
f[0][i]=k12;
L[0][i-1]=2;
}
if(k21<k22){ //find the most time-saving road
f[1][i]=k21;
L[1][i-1]=2;
}else{
f[1][i]=k22;
L[1][i-1]=1;
}
}
k11=f[0][5]+x[0];
k22=f[1][5]+x[1];
if(k11<=k22){
f_final=k11;L_end=1;
}else{
f_final=k22;L_end=2;
}
//print the most efficient time consumption on every station
printf("Time-consumption situation on every station of the two lines:\n");
for(i=0;i<2;i++){
printf("LINE %d: ",i);
for(j=0;j<6;j++)
printf("%3d",f[i][j]);
printf("\n");
}
printf("It costs the most saving time: %d\n ",f_final);
printf("The most time-saving path for every station:\n");
for(i=0;i<2;i++){
printf("LINE %d: ",i);
for(j=0;j<5;j++)
printf("%3d",L[i][j]);
printf("\n");
}
//Obtain the optimal path
Path[5][0]=6;
Path[5][1]=L_end;
for(i=4;i>=0;i--){
Path[i][0]=i+1;
Path[i][1]=L[Path[i+1][1]-1][i];
}
printf("The most efficient road is:\n");
for(i=0;i<6;i++){
printf("station %d, line %d\n",i+1,Path[i][1]);
}
}
运行结果如下:
装配线调度室动态规划算法的一个经典问题。
动态规划算法的设计主要有4步:
- 描述最优解的结果。
- 递归定义最优解的值。
- 按自底向上的方式计算最优解的值。
- 由计算出的结果构造一个最优解。