Quantcast
Channel: CSDN博客推荐文章
Viewing all articles
Browse latest Browse all 35570

动态规划

$
0
0

装配线调度问题


问题描述 

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

动态规划的算法思想

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

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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



作者:zinss26914 发表于2013-3-22 23:59:50 原文链接
阅读:70 评论:0 查看评论

Viewing all articles
Browse latest Browse all 35570

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>