[动态规划] 《算法导论》中的装配线调度问题实现

来源:互联网 发布:js select 选中第一个 编辑:程序博客网 时间:2024/04/29 10:27

问题描述:
  某汽车工厂有2个装配线,每个装配线有n 个装配站(按顺序编号1~n ),两个装配线对应的装配站执行相同的功能,但所用的时间可能不同。经过第i条流水线(i=1,2)的第j 个装配站所花的时间为Aij。从第i条流水线的第j 个装配站移到第j+1个装配站的时间可以忽略,而移到另外一个流水线的下一个装配站则需要一定的时间Tij。
  汽车进入流水线不需要花时间,出流水线时需要花时间Tin。
  汽车的装配需要按顺序经过所有装配站。
  现在已知装配时间Aij 和转移时间Tij,要求输出装配一辆汽车所需要的最短时间。 

动态规划算法思想:
  动态规划与贪心策略类似,将一个问题的解决方案视为一系列决策的结果。不同的是,贪心算法每采用一次贪心选择便做出一个不可撤回的决策,而在动态规划中,还要考察每个最优决策序列中是否包含一个最优决策自序列。使用动态规划时,所求问题应具有以下两种性质。
  1.最优子结构性质
  所求问题的最优子结构性质是采用动态规划算法的条件之一,这种性质又被称为最优化原理。动态规划方法采用最优化原理来建立用于计算最优解的递归式。所谓最优化原理即不管前面的策略如何,此后的决策必须是基于当前状态(由上一次决策产生)的最优决策。由于对于有些问题的某些递归式来说并不一定能保证最优原则,因此在求解问题时有必要对它进行验证。若不能保持最优原则,则不可应用动态规划方法。在得到最优解的递归式之后,需要执行回溯以构造最优解。当最优决策序列中包含最优决策子序列时,可建立动态规划递归方程,它可以帮助我们高效地解决问题。
  2.子结构重迭性质
  人们总希望编写一个简单的递归程序来求解动态规划递归方程。然而,如果不努力地去避免重复计算,递归程序的复杂性将非常可观。如果在递归程序设计中解决了重复计算问题,复杂性将大幅度下降。这种方法的思想是:由程序设置“备忘录”,每计算出一个新的子结构的解时,都保存起来。当遇到一次递归时,判断是否已经计算,如果已经计算,只需取出先前保存的结果既可。动态规划递归方程也可用迭代方式来求解,这时很自然地避免了重复计算。尽管迭代程序与避免重复计算的递归程序有相同的复杂性,但迭代程序不需要附加的递归栈空间,因此将比避免重复计算的递归程序更快。

#include <stdio.h>

#define N 6

#define MIN(a, b) (a) < (b) ? (a) : (b);

int main()
{
 const int a[N] = {7 , 9, 3, 4, 8, 4};
 const int b[N] = {8 , 5, 6, 4, 5, 7};

 const int a2b[N-1] = {2, 3, 1, 3, 4};
 const int b2a[N-1] = {2, 1, 2, 2, 1};

  char ra[N], rb[N];
 int min_a = 2;
 int min_b = 4;

 int station;
 int ai, aj;
 int bi, bj;
 min_a += a[0];
 min_b += b[0];
 printf("sa=%d sb=%d/n", min_a, min_b);
 int i;
 for(i = 1; i < N; i++)
 {
  ai = min_a + a[i];
  aj = min_b + b2a[i-1] + a[i];
  bi = min_b + b[i];
  bj = min_a + a2b[i-1] + b[i];
  ra[i-1] = (ai < aj) ? 'a' : 'b';
  rb[i-1] = (bi < bj) ? 'b' : 'a';
   //printf("min(%d, %d) s=%c, min(%d, %d) s=%c ", ai, aj, ra[i-1], bi, bj, rb[i-1]);

  min_a = MIN(ai, aj);
  min_b = MIN(bi, bj);
   printf("sa=%d b=%d while i=%d/n", min_a, min_b, i);
 }

 min_a += 3;
 min_b += 2;

 printf("sa=%d sb=%d/n", min_a, min_b);
 station = (min_a < min_b);
 printf("last station is %c/n", (min_a < min_b) ? 'a' : 'b');
 for(i = N - 2; i > -1; i--)
 {

  if(station)
  {
   station =  ra[i] == 'a' ;
   printf("station %c at line %d /n", ra[i], i);
  }
  else
  {
   station =  rb[i] == 'a'  ;
   printf("station %c at line %d /n", rb[i], i);
  }
 }
}

 

原创粉丝点击