装配线调度问题
问题描述
某汽车工厂有2个装配线,每个装配线有n个装配站(按顺序编号1~n),两个装配线对应的装配站执行相同的功能,但所用的时间可能不同.经过第i条流水线(i=1,2)的第j个装配站所花的时间为Aij。从第i条流水线的第j个装配站移到第j+1个装配站的时间可以忽略,而移到另外一个流水线的下一个装配站则需要一定的时间Tij。 汽车进入流水线不需要花时间,出流水线时需要花时间Tin。 汽车的装配需要按顺序经过所有装配站。 现在已知装配时间Aij和转移时间Tij,要求输出装配一辆汽车所需要的最短时间。
动态规划的算法思想
动态规划与贪心策略类似,将一个问题的解决方案视为一系列决策的结果。不同的是,贪心算法每采用一次贪心选择便做出一个不可撤回的决策,而在动态规划中,还要考察每个最优决策序列中是否包含一个最优决策自序列。使用动态规划时,所求的问题应具有以下两种性质:
- 最优子结构性质
所求问题的最优子结构性质是采用动态规划算法的条件之一,这种性质又被称为最优化原理。动态规划方法采用最优化原理来建立用于计算最优解的递归式。所谓最优化原理即不管前面的策略如何,此后的决策必须是基于当前状态(由上一次决策产生)的最优决策。由于对于有些问题的某些递归式来说并不一定能保证最优原则,因此在求解问题时有必要对它进行验证。若不能保持最优原则,则不可应用动态规划方法。在得到最优解的递归式之后,需要执行回溯以构造最优解。当最优决策序列中包含最优决策子序列时,可建立动态规划递归方程,它可以帮助我们高效的解决问题
- 子结构重迭性质
人们总希望编写一个简单的递归程序来求解动态规划方程。然而,如果不努力的去避免重复计算,递归程序的复杂性将非常可观。如果在递归程序设计中解决了重复计算问题,复杂性将大幅度下降。这种方法的思想是:由程序设置“备忘录”,每计算出一个新的子结构的解时,都保存起来。当遇到一次递归时,判断是否已经计算,如果已经计算,只需取出先前保存的结果即可。动态规划递归方程也可以用迭代方式来求解,这时很自然的避免了重复计算。尽管迭代程序与避免重复计算的递归程序有相同的重复性,但迭代程序不需要附加的递归栈空间,因此将避免重复计算的递归程序更快
装配线调度代码(c语言版)
#include <stdio.h> #include <stdlib.h> #include <string.h> #define LINE 2 #define N 6 int main() { // 装配线装配时间 const int product[LINE][N] = {{7, 9, 3, 4, 8, 4}, {8, 5, 6, 4, 5, 7}}; // 装配线转移时间 const int transport[LINE][N - 1] = {{2, 3, 1, 3, 4}, {2, 1, 2, 2, 1}}; // 进装配线的时间 const int e1 = 2; const int e2 = 4; // 出装配站的时间 const int o1 = 3; const int o2 = 2; // 保存从起点到终点s(i, j)的最短时间 int final[LINE][N] = {{0}, {0}}; // 保存总时间 int time = 0; // 保存经过路线 int line[LINE][N] = {{0}, {0}}; // 保存最后从哪条线走出装配线 int line_out = -1; // 保存正序的最短装配路线 int path[N]; memset(path, -1, sizeof(path)); int i, j; // 计算最快时间 final[0][0] = e1 + product[0][0]; final[1][0] = e2 + product[1][0]; for (j = 1; j < N; j ++) { if (final[0][j - 1] + product[0][j] <= final[1][j - 1] + transport[1][j - 1] + product[0][j]) { final[0][j] = final[0][j - 1] + product[0][j]; line[0][j] = 0; }else { final[0][j] = final[1][j - 1] + transport[1][j - 1] + product[0][j]; line[0][j] = 1; } if (final[1][j - 1] + product[1][j] <= final[0][j - 1] + transport[0][j - 1] + product[1][j]) { final[1][j] = final[1][j - 1] + product[1][j]; line[1][j] = 1; }else { final[1][j] = final[0][j - 1] + transport[0][j - 1] + product[1][j]; line[1][j] = 0; } } if (final[0][N - 1] + o1 <= final[1][N - 1] + o2) { line_out = 0; time = final[0][N - 1] + o1; }else { line_out = 1; time = final[1][N - 1] + o2; } printf("总共花费的时间是:%d\n", time); // 站号递增的顺序输出各装配站 for (j = N - 1, i = line_out; j >= 1; j --) { i = line[i][j]; path[j] = i; } for (i = 1; i < N; i ++) { printf("line: %d, station: %d\n", path[i] + 1, i); } printf("line: %d, station: %d\n", line_out + 1, N); return 0; }
作者:zinss26914 发表于2013-3-22 23:59:50 原文链接
阅读:70 评论:0 查看评论