一、问题描述
某个汽车工厂共有两条装配线,每条有 n 个装配站。装配线 i 的第 j个装配站表示为 Si,j ,在该站的装配时间为 ai,j 。一个汽车底盘进入工厂,然后进入装配线 i(i 为 1 或 2),花费时间为 ei 。在通过一条线的第 j 个装配站后,这个底盘来到任一条装配线的第(j+1)个装配站。如果它留在相同的装配线,则没有移动开销。但是,如果它移动到另一条线上,则花费时间为 ti,j 。在离开一条装配线的第 n 个装配站后,完成的汽车底盘花费时间为 xi 离开工厂。待求解的问题是,确定应该在装配线 1 内选择哪些站,在装配线 2 内选择哪些站,才能使汽车通过工厂的总时间最短。
问题提供的变量
ei:进入装配线i的时间
aij:在装配站ij所花费的时间
tij:从装配站ij装配完成之后离开该装配线额外花费的时间
xi:装配完成离开i的时间
二、思路分析
观察一条通过装配站 S1,j 的最快路线,发现它必定是经过装配线 1 或2 上的装配站(j-1)。因此,通过装配站 S1,j 的最快路线只能是以下二者之一:
? 通过装配站 S1,j?1 的最快路线,然后直接通过装配站 S1,j 。
? 通过装配站 S2,j?1 的最快路线,从装配线 2 转移到装配线 1,然后通过装配站 S1,j 。
故寻找通过任一条装配线上的装配站 j 的最快路线,我们可以规划为先寻找通过两条装配线上的装配站 j-1 的最快路线。
j-1的最优情况可以由j-2的情况来确定,一直向前能推到S0,0和S1,0,而S0,0可以由e0和a0,0相加来确定,S1,1可以由e1和a1,0相加来确定。
三、代码实现
代码用path存放路径,表示最短路径代表的装配线。装配线为2条,每条装配线有6个装配站。其他数据结构含义见注释。
int main() { //两条装配线 //进入装配线i的时间 int e[2] = {1,2}; //在装配站ij所花费的时间 int a[2][6] = { {4,2,3,5,3},{7,2,4,2,4} }; //从装配站ij装配完成之后离开该装配线额外花费的时间 int t[2][6] = { {2,3,2,2,1},{1,1,2,4,2} }; //装配完成离开i的时间 int x[2] = {2,1}; //用path存放最短路径 int path[6] = { 0 }; //每条装配线包含的装配站个数 int n = 6; //result[i][j]表示离开装配站ij所花费的最少时间 int result[2][6] = {0}; result[0][0] = e[0] + a[0][0]; result[1][0] = e[1] + a[1][0]; if (result[0][0] < result[1][0]) path[0] = 0; else path[0] = 1; for (int j = 1; j < n; j++) { if (result[0][j - 1] < result[1][j - 1] + t[1][j - 1]) result[0][j] = result[0][j - 1] + a[0][j]; else result[0][j] = result[1][j - 1] + a[0][j] + t[1][j - 1]; if (result[0][j - 1] + t[0][j - 1] < result[1][j - 1]) result[1][j] = result[0][j - 1] + a[1][j] + t[0][j-1]; else result[1][j] = result[1][j-1] + a[1][j]; //保存路径 if (result[0][j] < result[1][j]) path[j] = 0; else path[j] = 1; } result[0][5] = result[0][5] + x[0]; result[1][5] = result[1][5] + x[1]; for (int i = 0; i < 5; i++) cout << path[i] << endl; if (result[0][5] < result[1][5]) cout << result[0][5] <<endl; else cout << result[1][5] << endl; system("pause"); return 0; }