流水线调度dp问题

来源:互联网 发布:软件投标书模板 编辑:程序博客网 时间:2024/04/30 04:32

流水线调度 Assembly-Lines-Scheduling
问题:生产产品X需要经过m道手续,现在有两条流水线,每条流水线上m个站点,对应的站点功能相同, p[i][j]表示在第i条流水线上第j个站点上的加工时间;t[i][j]表示由第i条流水线跳转到第j条流水线上的时间。那么问题来了,想要用最短的时间加工完X,应该怎么加工呢?
分析:简单来讲,就是从1,1开始或者从2,1开始(哪条流水线开始),1,m结束还是2.m结束的问题,也就是最后只要比较cost[1][m]和cost[2][m]哪个比较小,比较无论如何要经过这m道工序
以1,m举例,到达1,m的时间cost[1][m]最小的话,有两种可能:一是经过流水线1,m-1然后不跳转直接到了1,m省了t[1][2]的时间; 另一种情况是本来再2,m-1的,结果发现从2上转过来再在1上加工最后一道程序比较快,也就是cost[2][m-1]+t[2][1]+p[1][m]分别表示在转过去之前已经消耗的时间和跳转流水线的时间和在1上完成最后一道工序的时间
所以只要找出min(cost[1][m], cost[2][m-1]+t[2][1]+ p[1][m])就可以了
那么问题来了cost[1][m]和cost[2][m-1]怎么知道呢
要知道cost[1][m]就得知道cost[1][m-1],就要知道cost[1][m-2]。。。就要知道
cost[1][1].幸运的是我们刚好就知道cost[1][1]和cost[2][1]就是p[1][1]和p[2][1]

所以这种有点递归性质的具有最优子结构的问题就可以使用动态规划来实现了
伪代码可以是这样的

cost[1][1]= p[1][1];cost[2][1] = p[2][1];for(int j = 2;j<=m;j++){        cost[1][j] = min(cost[1][j-1]+p[1][j], cost[2][j-1]+t[2][1]+p[1][j]);        cost[2][j] = min(cost[2][j-1]+p[2][j], cost[1][j-1]+t[1][2]+p[2][j]);}

进一步呢可以推广到n条流水线的情况,每条流水线上m个站点的时候
其实这个时候就可以安静的用图里面的Floyd算法了

for(int i = 1;i<=n;i++)for(int j = 1;j<=m;j++)cost[i][j] = (1<<30);for(int i = 1;i<=n;i++)cost[i][1] = p[i][1];for(int k = 2;k<=m;k++)//第k个站点for(int i = 1;i<=n;i++)for(int j = 1;j<=n;j++)cost[i][k] = min(cost[i][k], cost[j][k-1]+t[j][1]+p[i][k]);

不过在最后的循环里改成

for(int k = 2;k<=m;k++)//第k个站点for(int i = 1;i<=n;i++)for(int j = 1;j<=n;j++){int temp = min(cost[i][k-1]+p[i][k], cost[j][k-1]+t[j][i]+ p[i][k]);if(cost[i][k]>temp)cost[i][k] = temp;}

我真的找不到哪里不对,但是它确实不对……求指点……

0 0