动态规划——装配线调度
2008-01-31 18:57
274 查看
动态规划
动态规划算法的设计可分为如下4个步骤:
(1)描述最优解的结构;
(2)递归定义最优解的值;
(3)按自底向上的方式计算最优解的值;
(4)由计算出的结果构造一个最优解。
第1~3步构成问题的动态规划解得基础,第4步在只要求计算最优解的值时可以略去。如果的确做了第4步,则有时要在第3步的计算中记录一些附加信息,要构造一个最优解变得容易。
装配线问题
一个找出通过工厂装配线的最快方式的制造问题。共有两条装配线,每一条装配线上有n个装配站,编号为j = 0, 1, … , n - 1。装配线i(i = 0或1),在装配站S[i][j]上所需的装配时间记为a[i][j]。一个汽车底盘进入工厂,然后进入装配线i的进入时间为e[i],在通过一条线的第j个装配站后,这个底盘来到任一条线的第(j + 1)个装配站。如果留在相同的装配线上,则没有移动的开销;如果在装配站S[i][j]后,它移动到了另一条线上,则花费时间t[i][j]。在离开一条线的第n个装配站后,完成的汽车离开装配线i的离开时间为x[i] 。
f[i][j]:底盘从起点到装配站S[i][j]的最快可能时间。
最终目标是确定底盘通过工厂的所有路线的最快时间,记为fast ,有:
fast = min{f[0][n-1] + x[0], f[1][n-1] + x[1]}
f[0][0] = e[0] + a[0][0]
f[1][0] = e[1] + a[1][0]
f[0][j] = min{f[0][j-1] + a[0][j], f[1][j-1] + t[1][j-1] + a[0][j]} (j = 1, 2, … , n-1)
f[1][j] = min{f[1][j-1] + a[1][j], f[0][j-1] + t[0][j-1] + a[1][j]} (j = 1, 2, … , n-1)
按上式迭代,可计算出f[i][j],以及fast的值。
f[i][j]的值就是子问题最优解的值,定义l[i][j](j = 1, 2, … , n-1)记录装配线的编号,表示通过装配站S[i][j]的最快路线所用的j-1装配站所在的装配线的编号。last记录n-1装配站被通过整个工厂的最快路线所使用。
WaterLineMain.c
#include <stdio.h>
void PrintStations(int l[][6], int last, int n);
void FastestWay(int a[][6], int t[][5], int *e, int *x, int n);
void PrintStations(int l[][6], int last, int n)
...{
int i, j;
i = last;
printf("line:%d station:%d ", i, n);
for(j = n-1; j > 0; j--)
...{
i = l[i][j];
printf("line:%d station:%d ", i, j);
}
}
void FastestWay(int a[][6], int t[][5], int *e, int *x, int n)
...{
int j;
int f[2][6], l[2][6];
int fast, last;
f[0][0] = e[0] + a[0][0];
f[1][0] = e[1] + a[1][0];
for(j = 1; j < n; j++)
...{
if(f[0][j-1] < f[1][j-1] + t[1][j-1])
...{
f[0][j] = f[0][j-1] +a[0][j];
l[0][j] = 0;
}
else
...{
f[0][j] = f[1][j-1] + t[1][j-1] + a[0][j];
l[0][j] = 1;
}
if(f[1][j-1] < f[0][j-1] + t[0][j-1])
...{
f[1][j] = f[1][j-1] +a[1][j];
l[1][j] = 1;
}
else
...{
f[1][j] = f[0][j-1] + t[0][j-1] + a[1][j];
l[1][j] = 0;
}
}
if(f[0][n-1] + x[0] <= f[1][n-1] + x[1])
...{
fast = f[0][n-1] + x[0];
last = 0;
}
else
...{
fast = f[1][n-1] + x[1];
last = 1;
}
PrintStations(l, last, n);
}
int main(int argc, char **argv)
...{
int a[2][6] = ...{...{7, 9, 3, 4, 8, 4}, ...{8, 5, 6, 4, 5, 7}};
int t[2][5] = ...{...{2, 3, 1, 3, 4},...{2, 1, 2, 2, 1}};
int e[2] = ...{2, 4};
int x[2] = ...{3, 2};
int n = 6;
FastestWay(a, t, e, x, n);
return 0;
}
动态规划算法的设计可分为如下4个步骤:
(1)描述最优解的结构;
(2)递归定义最优解的值;
(3)按自底向上的方式计算最优解的值;
(4)由计算出的结果构造一个最优解。
第1~3步构成问题的动态规划解得基础,第4步在只要求计算最优解的值时可以略去。如果的确做了第4步,则有时要在第3步的计算中记录一些附加信息,要构造一个最优解变得容易。
装配线问题
一个找出通过工厂装配线的最快方式的制造问题。共有两条装配线,每一条装配线上有n个装配站,编号为j = 0, 1, … , n - 1。装配线i(i = 0或1),在装配站S[i][j]上所需的装配时间记为a[i][j]。一个汽车底盘进入工厂,然后进入装配线i的进入时间为e[i],在通过一条线的第j个装配站后,这个底盘来到任一条线的第(j + 1)个装配站。如果留在相同的装配线上,则没有移动的开销;如果在装配站S[i][j]后,它移动到了另一条线上,则花费时间t[i][j]。在离开一条线的第n个装配站后,完成的汽车离开装配线i的离开时间为x[i] 。
f[i][j]:底盘从起点到装配站S[i][j]的最快可能时间。
最终目标是确定底盘通过工厂的所有路线的最快时间,记为fast ,有:
fast = min{f[0][n-1] + x[0], f[1][n-1] + x[1]}
f[0][0] = e[0] + a[0][0]
f[1][0] = e[1] + a[1][0]
f[0][j] = min{f[0][j-1] + a[0][j], f[1][j-1] + t[1][j-1] + a[0][j]} (j = 1, 2, … , n-1)
f[1][j] = min{f[1][j-1] + a[1][j], f[0][j-1] + t[0][j-1] + a[1][j]} (j = 1, 2, … , n-1)
按上式迭代,可计算出f[i][j],以及fast的值。
f[i][j]的值就是子问题最优解的值,定义l[i][j](j = 1, 2, … , n-1)记录装配线的编号,表示通过装配站S[i][j]的最快路线所用的j-1装配站所在的装配线的编号。last记录n-1装配站被通过整个工厂的最快路线所使用。
WaterLineMain.c
#include <stdio.h>
void PrintStations(int l[][6], int last, int n);
void FastestWay(int a[][6], int t[][5], int *e, int *x, int n);
void PrintStations(int l[][6], int last, int n)
...{
int i, j;
i = last;
printf("line:%d station:%d ", i, n);
for(j = n-1; j > 0; j--)
...{
i = l[i][j];
printf("line:%d station:%d ", i, j);
}
}
void FastestWay(int a[][6], int t[][5], int *e, int *x, int n)
...{
int j;
int f[2][6], l[2][6];
int fast, last;
f[0][0] = e[0] + a[0][0];
f[1][0] = e[1] + a[1][0];
for(j = 1; j < n; j++)
...{
if(f[0][j-1] < f[1][j-1] + t[1][j-1])
...{
f[0][j] = f[0][j-1] +a[0][j];
l[0][j] = 0;
}
else
...{
f[0][j] = f[1][j-1] + t[1][j-1] + a[0][j];
l[0][j] = 1;
}
if(f[1][j-1] < f[0][j-1] + t[0][j-1])
...{
f[1][j] = f[1][j-1] +a[1][j];
l[1][j] = 1;
}
else
...{
f[1][j] = f[0][j-1] + t[0][j-1] + a[1][j];
l[1][j] = 0;
}
}
if(f[0][n-1] + x[0] <= f[1][n-1] + x[1])
...{
fast = f[0][n-1] + x[0];
last = 0;
}
else
...{
fast = f[1][n-1] + x[1];
last = 1;
}
PrintStations(l, last, n);
}
int main(int argc, char **argv)
...{
int a[2][6] = ...{...{7, 9, 3, 4, 8, 4}, ...{8, 5, 6, 4, 5, 7}};
int t[2][5] = ...{...{2, 3, 1, 3, 4},...{2, 1, 2, 2, 1}};
int e[2] = ...{2, 4};
int x[2] = ...{3, 2};
int n = 6;
FastestWay(a, t, e, x, n);
return 0;
}
相关文章推荐
- 动态规划——装配线调度问题
- 动态规划-装配线调度
- 动态规划之装配线调度理解
- 动态规划—装配线调度
- 动态规划 - 装配线调度问题
- 动态规划-装配线调度
- 流水线调度最优问题(装配线调度问题)动态规划 O(n)时间(线性时间)C++实现
- 第十五章动态规划之“装配线调度”
- 深入理解动态规划思想——装配线调度、矩阵链乘法、最长公共子序列、最优二叉查找树
- 动态规划 - 装配线调度问题
- 动态规划-装配线调度
- 动态规划之装配线调度
- 动态规划--装配线调度问题
- 动态规划: 装配线调度问题 (算法导…
- 动态规划--装配线调度问题
- 动态规划之装配线调度问题
- 算法导论 15.1动态规划 装配线调度
- 动态规划-装配线调度
- 流水线调度最优问题(装配线调度问题)动态规划 O(n)时间(线性时间)C++实现
- 动态规划——装配线调度