算法导论_15.1装配线调度

一、装配线调度问题描述

总共有n个装配站;
底盘进入到装配线1和装配线2的时间记录在二元数组e[2]上;
底盘在装配线1和装配线2上每个站的时间记录在数组a1[n] 和a2[n]上;
底盘在每个站上换装配线的时间记录在t1[n-1], t2[n-2]上;(在最后一个站时候, 不需要换装配线了,所以数组只有n-1个数据)
底盘离开装配线的时间存放在二元数组x[2]上面;
求得的最优解记录在数组f1[n] 和f2[n]上;
每次做出的选择记录在数组l1[n-1], l2[n-1]上;(在最后一个站的时候, 不需要做选择了, 所以只有n-1个元素)
在这里插入图片描述

二、求解方法

暴力法求解:
如果有n个装配站, 每个装配站都要考虑是选择装配线1还是装配线2, 这样时间复杂度就是2^n次方;
动态规划算法,子问题空间是一维的,每一个子问题要两次选择,所以时间复杂度 = n *2;

动态规划求解:
1) 步骤1(最优化结构分析)
将对装配线1 和 装配线2的求解区分开来;
对装配线1而言,边界是第一个装配站的解, f1[0] = e[0] + a1[0];
对第i个装配站的解A(i), 可以由其子问题的解构成, 即只有一个子问题A(i-1),即第i-1个解;(第i个问题的解是由第i-1个问题的解组成的。因此其子问题空间就是一维的;
对于每一个子问题, 都有两种选择:选择1 是选择装配站S(1, i-1); 选择2 是选择装配站S(2, i-1);
因此,其时间复杂度 = 子问题空间 × 选择次数 = n × 2 = 2n,

使用剪贴技术证明子问题的最优解构造了原问题的最优解:假设通过装配站S(1, i)的最快路线通过了装配站S(1, i-1), 那么这个最快路线也是通过装配站S(1, i-1)的最快路线;如果假设存在其他一条最快路线通过装配站S(1, i-1), 那么会导致通过装配站S(1, i)的最快路线不是最快的,形参矛盾;
经过以上分析,可以得到一个最优子结构一个问题的最优解包含了子问题的最优解,这是引用动态规划的标志之一。 因此可以使用动态规划算法。

以上相同的分析适用于装配线2;
2) 步骤2 (一个递归的解)
依据最优子结构, 一个问题的最优解包含有子问题的最优解, 因此可以利用子问题的最优解来递归得到原问题的最优解;
最终的目标是求得底盘通过装配线的最短时间, 即f*;
f* = min(f1[n] + x[0], f2[n] +x[1]);
因此需要求得f1[n] 和f2[n];
对于边界: f1[0] = e[0] + a1[0]; f2[0] = e[1] + a2[0];
对于第i个装配站: f1[i] = min(f1[i-1] + a1[i], f2[i-1] + t2[i-1] + a1[i]) , 使用min函数做出选择
f2[i] = min(f2[i-1] + a2[i], f1[i-1] + t1[i-1] + a2[i])

在这里插入图片描述
3) 步骤3(计算最快时间)
如果根据上面的递归式子使用自顶向下递归算法编码,其时间复杂度是z^n;
考虑计算f(i, j)的次数, 计算f(1, n)一次, 要计算f(1, n-1)2次,计算f(1, n-2) 4次,计算f(1, 1) 2^(n-1)次;
自顶向下的递归算法实现如下:

void fastest_way_recur_help(int* e, int* x, int* a1, int* a2, int* t1, int* t2, int *value1, int *value2, int n) {
   
	//边界条件
	if (n == 1) {
   
		*value1 = e[0] + a1[0];
		*value2 = e[1] + a2[0];
	}
	else {
   	//递归处理
		int result1, result2;
		fastest_way_recur_help(e, x, a1, a2, t1, t2, &result1, &result2, n-1);
		*value1 = min(result1 + a1[n - 1], result2 + t2[n - 2] + a1[n - 1]);
		*value2 = min(result2 + a2[n - 1], result1 + t1[n - 2] + a2[n - 1]
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值