动态规划之装配线调度
2014-06-08 13:54
393 查看
在看这张之前,最好看看我写的动态规划详解,里面都是讲理论基础,我下面的分析都是在此基础上进展的。
题目:
装配一辆汽车,有两条装配线分别有n个装配点,每条装配线在进出所花时间为e[i],x[i] (i=0,1),每个装配点所需时间a[i][j](i=0,1;j=0,1,...,n-1),从一条装配线i的第j个装配点到另一条装配线的第j+1个装配点所需时间t[i][j]。
![](http://img.blog.csdn.net/20140608133007796?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYTQ1ODcyMDU1NTU1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
DP算法的设计可以分为四个步骤:
①.描述最优解的结构。
②.递归定义最优解的值。
③.按自底而上的方式计算最优解的值。
④.由计算出的结果创造一个最优解。
下面用上面的四步来解题:
①.描述最优解的结构。
最后的出口(1,n)从第(1,n-1)位置或(2,n-1)来,出口(2,n)类似。那好,这样一次划分后,是否具有最优子结构问题?具有最优子结构:一个问题的最优解包含了子问题的一个最优解。正如这个题中,找出通过装配站S(i,j)的最优解,包含了找出通过S(1,j-1)或S(2,j-1)的一个最优解。转化成了,为了解决这个问题(寻找通过任一条装配线上的j的最快路线),我们解决其子问题(寻找通过两条装配线上的j-1的最快路线),原问题就能的解。
②.递归定义最优解的值。
第一步分析了最优解是如何拆分的,第二步就是用来组成最优解。
装配线问题:根据题意,可以写出f(i)与f(i-1)之间的关系。
先剥离边界性条件差异,我们得到如下递归式:
![](http://img.blog.csdn.net/20140608134347593)
![](http://img.blog.csdn.net/20140608134354625)
然后处理边界性问题:
出口时,应该求解f1
+x1,f2
+x2。然后选出其中的最小值求解。
入口时,也有条件:
![](http://img.blog.csdn.net/20140608134404640)
因此得到两个方程组和一个结果方程
![](http://img.blog.csdn.net/20140608134411671)
![](http://img.blog.csdn.net/20140608134524234)
方程有了,第二步也就算结束了。
③.按自底而上的方式计算最优解的值。
如果单纯根据表达式求解的话,需要用到递归,问题是解决了,但时间复杂度是O(2^n)。这明显是不理想的。但对于动态规划问题,通常采用自底向上的方式,需要建立数组来保持。那么这里就有个问题,数组保存哪些值呢?利用数组就是为了防止递归带来的时间消耗,因此数组保存的是要递归时的返回值。也就是递归表达式中的f1[n-1]以及f2[n-2]。
有了这样的数组,将i从1->n增长,一步一步求解。
④.由计算出的结果创造一个最优解。
通常只用求解最优解的话,是不需要这一步的。但要给出方案,就要保存路径信息。只需要额外设置数组即可。
如果按照书中的话,设计两个数组li[j]。i=1/2,j表示第j个装配站,l1[j]保存1/2,含义是到达这个点的话,最短路径是从1线的j-1过来的还是从2线的j-1过来的。整体的含义表示,到达i线上的j站点来自于哪个线上的j-1。但是求出口时,要有个统一的入口设一个变量L*,那么根据f1
+x1和f2
+x2的大小决定L*为1还是为2。
注意:一开始考虑这里附设一个数组就可以了,将L[j]存储从哪个结点过来的,这样是不合理的,l1[]和l2[]数组是不能合并的。
代码如下:
题目:
装配一辆汽车,有两条装配线分别有n个装配点,每条装配线在进出所花时间为e[i],x[i] (i=0,1),每个装配点所需时间a[i][j](i=0,1;j=0,1,...,n-1),从一条装配线i的第j个装配点到另一条装配线的第j+1个装配点所需时间t[i][j]。
DP算法的设计可以分为四个步骤:
①.描述最优解的结构。
②.递归定义最优解的值。
③.按自底而上的方式计算最优解的值。
④.由计算出的结果创造一个最优解。
下面用上面的四步来解题:
①.描述最优解的结构。
最后的出口(1,n)从第(1,n-1)位置或(2,n-1)来,出口(2,n)类似。那好,这样一次划分后,是否具有最优子结构问题?具有最优子结构:一个问题的最优解包含了子问题的一个最优解。正如这个题中,找出通过装配站S(i,j)的最优解,包含了找出通过S(1,j-1)或S(2,j-1)的一个最优解。转化成了,为了解决这个问题(寻找通过任一条装配线上的j的最快路线),我们解决其子问题(寻找通过两条装配线上的j-1的最快路线),原问题就能的解。
②.递归定义最优解的值。
第一步分析了最优解是如何拆分的,第二步就是用来组成最优解。
装配线问题:根据题意,可以写出f(i)与f(i-1)之间的关系。
先剥离边界性条件差异,我们得到如下递归式:
然后处理边界性问题:
出口时,应该求解f1
+x1,f2
+x2。然后选出其中的最小值求解。
入口时,也有条件:
因此得到两个方程组和一个结果方程
方程有了,第二步也就算结束了。
③.按自底而上的方式计算最优解的值。
如果单纯根据表达式求解的话,需要用到递归,问题是解决了,但时间复杂度是O(2^n)。这明显是不理想的。但对于动态规划问题,通常采用自底向上的方式,需要建立数组来保持。那么这里就有个问题,数组保存哪些值呢?利用数组就是为了防止递归带来的时间消耗,因此数组保存的是要递归时的返回值。也就是递归表达式中的f1[n-1]以及f2[n-2]。
有了这样的数组,将i从1->n增长,一步一步求解。
④.由计算出的结果创造一个最优解。
通常只用求解最优解的话,是不需要这一步的。但要给出方案,就要保存路径信息。只需要额外设置数组即可。
如果按照书中的话,设计两个数组li[j]。i=1/2,j表示第j个装配站,l1[j]保存1/2,含义是到达这个点的话,最短路径是从1线的j-1过来的还是从2线的j-1过来的。整体的含义表示,到达i线上的j站点来自于哪个线上的j-1。但是求出口时,要有个统一的入口设一个变量L*,那么根据f1
+x1和f2
+x2的大小决定L*为1还是为2。
注意:一开始考虑这里附设一个数组就可以了,将L[j]存储从哪个结点过来的,这样是不合理的,l1[]和l2[]数组是不能合并的。
代码如下:
int n; // 一个装配线上有n个装配站 int e1, e2; // 进入装配线1,2需要的时间 int x1, x2; // 离开装配线1,2需要的时间 int t[3][100]; // t[1][j]表示底盘从S[1][j]移动到S[2][j+1]所需时间,同理t[2][j] int a[3][100]; // a[1][j]表示在装配站S[1][j]所需时间 int f1[100], f2[100]; // f1[j], f2[j]分别表示在第一/第二条装配线上第j个装配站的最优解 int ln1[100], ln2[100];// ln1[j]记录第一条装配线上,最优解时第j个装配站的前一个装配站是第一条线还是第二条线上 int f, ln; // 最优解是,f代表最小花费时间,ln表示最后出来时是从装配线1还是装配线2 void DP() { f1[1] = e1 + a[1][1]; f2[1] = e2 + a[2][1]; for(int j=2; j<=n; ++j){ // 处理第一条装配线的最优子结构 if(f1[j-1] + a[1][j] <= f2[j-1] + t[2][j-1] + a[1][j]){ f1[j] = f1[j-1] + a[1][j]; ln1[j] = 1; }else{ f1[j] = f2[j-1] + t[2][j-1] + a[1][j]; ln1[j] = 2; } // 处理第二条装配线的最优子结构 if(f2[j-1] + a[2][j] <= f1[j-1] + t[1][j-1] + a[2][j]){ f2[j] = f2[j-1] + a[2][j]; ln2[j] = 2; }else{ f2[j] = f1[j-1] + t[1][j-1] + a[2][j]; ln2[j] = 1; } } if(f1 + x1 <= f2 + x2){ f = f1 + x1; ln = 1; }else{ f = f2 + x2; ln = 2; } } void PrintStation() { int i= ln; printf("line %d,station %d",i,n); for(int j=n; j>=2; --j){ if(i == 1) i = ln1[j]; else i = ln2[j]; printf("line %d ,station %d",i,j-1); } }
相关文章推荐
- 动态规划之装配线调度
- 动态规划-装配线调度
- 算法导论 15.1动态规划 装配线调度
- 动态规划: 装配线调度问题 (算法导…
- 动态规划-装配线调度
- 动态规划——装配线调度问题
- 动态规划 - 装配线调度问题
- 动态规划--装配线调度问题
- 动态规划 - 装配线调度问题
- 动态规划--装配线调度问题
- 动态规划之装配线调度
- 动态规划——装配线调度
- 动态规划—装配线调度
- 动态规划——装配线调度
- 流水线调度最优问题(装配线调度问题)动态规划 O(n)时间(线性时间)C++实现
- 装配线调度问题 算法导论动态规划P194
- 动态规划之 装配线调度问题
- 动态规划----装配线调度
- 动态规划-装配线调度
- 动态规划-装配线调度