两个限制条件的动态规划java_动态规划 - java程序员填空 - 博客园

某汽车工厂有2个装配线,每个装配线有n个装配站(按顺序编号1~n),两个装配线对应的装配站执行相同的功能,但所用的时间可能不同.经过第i条流水线(i=1,2)的第j个装配站所花的时间为Aij。从第i条流水线的第j个装配站移到第j+1个装配站的时间可以忽略,而移到另外一个流水线的下一个装配站则需要一定的时间Tij。

汽车进入流水线不需要花时间,出流水线时需要花时间Tin。

汽车的装配需要按顺序经过所有装配站。

现在已知装配时间Aij和转移时间Tij,要求输出装配一辆汽车所需要的最短时间。

动态规划的算法思想

动态规划与贪心策略类似,将一个问题的解决方案视为一系列决策的结果。不同的是,贪心算法每采用一次贪心选择便做出一个不可撤回的决策,而在动态规划中,还要考察每个最优决策序列中是否包含一个最优决策自序列。使用动态规划时,所求的问题应具有以下两种性质:

最优子结构性质

所求问题的最优子结构性质是采用动态规划算法的条件之一,这种性质又被称为最优化原理。动态规划方法采用最优化原理来建立用于计算最优解的递归式。所谓最优化原理即不管前面的策略如何,此后的决策必须是基于当前状态(由上一次决策产生)的最优决策。由于对于有些问题的某些递归式来说并不一定能保证最优原则,因此在求解问题时有必要对它进行验证。若不能保持最优原则,则不可应用动态规划方法。在得到最优解的递归式之后,需要执行回溯以构造最优解。当最优决策序列中包含最优决策子序列时,可建立动态规划递归方程,它可以帮助我们高效的解决问题

子结构重迭性质

人们总希望编写一个简单的递归程序来求解动态规划方程。然而,如果不努力的去避免重复计算,递归程序的复杂性将非常可观。如果在递归程序设计中解决了重复计算问题,复杂性将大幅度下降。这种方法的思想是:由程序设置“备忘录”,每计算出一个新的子结构的解时,都保存起来。当遇到一次递归时,判断是否已经计算,如果已经计算,只需取出先前保存的结果即可。动态规划递归方程也可以用迭代方式来求解,这时很自然的避免了重复计算。尽管迭代程序与避免重复计算的递归程序有相同的重复性,但迭代程序不需要附加的递归栈空间,因此将避免重复计算的递归程序更快

装配线调度代码(c语言版)

#include

#include

#include

#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;

}

最长公共子序列(LCS)

题目描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值