您的位置:首页 > 其它

动态规划

2015-08-11 15:14 176 查看
动态规划

动态规划(dynamic programming)与分治法一样,是通过组合子问题的解而解决整个问题的。动态规划通常用于最优化问题。

动态规划步骤:

1) 描述最优解的结构

2) 递归定义最优解的值

3) 按自底向上的方式计算最优解的值

4) 由计算的结果构造最优解

示例:装配线调度

Colonel公司有两条装配线生产汽车,如图1所示。每条装配线有n个装配站,编号为j=1,2,……,n。每条线上对应站的功能相同,但加工时间不同,将装配线(i=1,2)的第j个装配站表示为

,对应的加工时间表示为

。底盘进入装配线的时间为

,离开装配线的时间为

。部分完成的汽车在任何站上可从一条装配线移到另一条装配线上,将通过

的底盘从装配线i转走所花时间为

。求加工底盘的最快时间。



图1 加工底盘流程

步骤1:通过工厂最快路线的结构

由最优子结构得知,通过装配站

的最快路线是以下二者之一:

(1) 通过装配站

的最快路线,再直接通过



(2) 通过装配站

的最快路线,从装配线2移到1,再通过



同理可知通过装配站 的最快路线。

步骤2:一个递归的解

利用子解的最优解来递归的定义一个最优解的值。令

表示底盘从起点到装配站

的最快可能时间,

表示加工底盘最短时间。则



初始条件为

。接下来计算

,其中 j=2,3,…,n(i=1,2)。



整理得:



步骤3:计算最快时间

定义

为装配线编号(1或2),其中的装配站j-1被通过装配站

的最快路线所使用。函数FastWay以值

以及在每条装配线中装配站的数目n作为输入。

int FastWay(int[]a1,int[]a2,int[]t1,int[]t2,int e1,int e2,int x1,int x2, int n)
{
int[] f1 = new int
;
int[] f2 = new int
;
int[] l1 = new int
;
int[] l2 = new int
;
int fbest;
int lfinal;
f1[0] = e1 + a1[0]; f2[0] = e2 + a2[0];
for (int j = 1; j < n; j++)
{
if (f1[j - 1] + a1[j] <= f2[j - 1] + t2[j - 1] + a1[j])
{
f1[j] = f1[j - 1] + a1[j];
l1[j] = 1;
}
else
{
f1[j] = f2[j - 1] + t2[j - 1] + a1[j];
l1[j] = 2;
}
if (f2[j - 1] + a2[j] <= f1[j - 1] + t1[j - 1] + a2[j])
{
f2[j] = f2[j - 1] + a2[j];
l2[j] = 2;
}
else
{
f2[j] = f1[j - 1] + t1[j - 1] + a2[j];
l2[j] = 1;
}
}
if (f1[n - 1] + x1 <= f2[n - 1] + x2)
{
fbest = f1[n - 1] + x1;
lfinal = 1;
}
else
{
fbest = f2[n - 1] + x2;
lfinal = 2;
}
return fbest;
}


步骤4:构造通过工厂的最短路线

计算出

,

,

的值以后,需要构造在通过工厂的最快路线中使用的装配站的序列,函数PaintStation实现。

void PaintStation(int[] l1,int[]l2,int lfinal,int n)
{
int i = lfinal;
Console.WriteLine("line" + i + ",station" + n);
for (int j = n - 1; j > 0; j--)
{
if (i == 1)
{
i = l1[j];
Console.WriteLine("line" + i + ",station" + j);
}
else
{
i = l2[j];
Console.WriteLine("line" + i + ",station" + j);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: