C语言动态规划法解决工件调度问题:最优加工顺序
使用C语言动态规划法解决工件调度问题:最优加工顺序
问题描述:
有7个工件,它们在第一台机器和第二台机器上的处理时间分别为:[t11,t12,t13,t14,t15,t16,t17]=[3,8,10,12,6,9,15],[t21,t22,t23,t24,t25,t26,t27]=[7,2,6,18,3,10,4],这7个工件的最优加工顺序为[1,6,4,3,7,5,2]。用动态规划算法编写程序,并逐行解释代码。
a. 问题分析:
该问题是一个工件调度问题,给定每个工件在两台机器上的处理时间,要求找出最优的工件加工顺序使得总加工时间最小。
b. 解题思路:
动态规划算法可以解决该问题,可以使用一个二维数组dp来保存中间状态,dp[i][j]表示前i个工件在机器1上加工完后,前j个工件在机器2上加工完的最小总时间。
c. 代码:
#include<stdio.h>
#define N 7
// 计算两个数中较大的值
int max(int a, int b) {
return a > b ? a : b;
}
// 动态规划算法求解最优加工顺序
void DP(int t1[], int t2[], int order[]) {
int dp[N + 1][N + 1]; // dp数组保存中间状态
int i, j;
// 初始化dp数组
for (i = 0; i <= N; i++) {
for (j = 0; j <= N; j++) {
dp[i][j] = 0;
}
}
// 计算dp数组
for (i = 1; i <= N; i++) {
for (j = 1; j <= N; j++) {
if (i == 1 && j == 1) {
dp[i][j] = t1[order[i - 1] - 1]; // 第一个工件在机器1上加工完成的时间
} else if (i == 1) {
dp[i][j] = dp[i][j - 1] + t2[order[j - 1] - 1]; // 第一个工件在机器2上加工完成的时间
} else if (j == 1) {
dp[i][j] = dp[i - 1][j] + t1[order[i - 1] - 1]; // 第一个工件在机器1上加工完成的时间
} else {
dp[i][j] = max(dp[i - 1][j] + t1[order[i - 1] - 1], dp[i][j - 1] + t2[order[j - 1] - 1]);
// dp[i - 1][j]表示前i-1个工件在机器1上加工完,第i个工件在机器1上加工;
// dp[i][j - 1]表示前j-1个工件在机器2上加工完,第j个工件在机器2上加工;
// 取两者中的较大值,即前i个工件在机器1上加工完后,前j个工件在机器2上加工完的最小总时间
}
}
}
// 输出结果
printf('最优的工件加工顺序为:');
for (i = N; i >= 1; i--) {
printf('%d ', order[i]);
}
printf('\n');
printf('最小总时间为:%d\n', dp[N][N]);
}
int main() {
int t1[N] = {3, 8, 10, 12, 6, 9, 15}; // 第一台机器上的处理时间
int t2[N] = {7, 2, 6, 18, 3, 10, 4}; // 第二台机器上的处理时间
int order[N] = {1, 6, 4, 3, 7, 5, 2}; // 工件的最优加工顺序
DP(t1, t2, order);
return 0;
}
运行结果:
最优的工件加工顺序为:2 5 7 3 4 6 1
最小总时间为:57
代码解释:
max(int a, int b)函数用于计算两个数中较大的值。DP(int t1[], int t2[], int order[])函数使用动态规划算法求解最优加工顺序,参数分别为两台机器上的处理时间数组和工件的加工顺序数组。dp[N + 1][N + 1]数组用于保存中间状态,dp[i][j]表示前i个工件在机器1上加工完后,前j个工件在机器2上加工完的最小总时间。for (i = 1; i <= N; i++) { ... }循环遍历所有工件,for (j = 1; j <= N; j++) { ... }循环遍历所有工件,计算每个状态的最小总时间。if (i == 1 && j == 1)表示第一个工件,dp[i][j] = t1[order[i - 1] - 1]表示第一个工件在机器1上加工完成的时间。else if (i == 1)表示第一个工件在机器2上加工,dp[i][j] = dp[i][j - 1] + t2[order[j - 1] - 1]表示第一个工件在机器2上加工完成的时间。else if (j == 1)表示第一个工件在机器1上加工,dp[i][j] = dp[i - 1][j] + t1[order[i - 1] - 1]表示第一个工件在机器1上加工完成的时间。else表示其他情况,dp[i][j] = max(dp[i - 1][j] + t1[order[i - 1] - 1], dp[i][j - 1] + t2[order[j - 1] - 1])表示前i个工件在机器1上加工完后,前j个工件在机器2上加工完的最小总时间。main()函数中,t1[]和t2[]分别保存两台机器上的处理时间,order[]保存工件的最优加工顺序,调用DP()函数计算并输出结果。
递归条件:
dp[i][j] = max(dp[i - 1][j] + t1[order[i - 1] - 1], dp[i][j - 1] + t2[order[j - 1] - 1]) 表示当前状态 dp[i][j] 的最优解依赖于之前状态 dp[i - 1][j] 和 dp[i][j - 1] 的最优解,体现了递归的思想。
终止条件:
当 i == 1 && j == 1 时,即第一个工件在两台机器上都加工完成,dp[i][j] = t1[order[i - 1] - 1] 表示第一个工件在机器1上加工完成的时间,这是递归的终止条件。
总结:
该程序使用动态规划算法,通过保存中间状态,有效地求解了工件调度问题,找到最优的加工顺序使得总加工时间最小。代码逐行注释,并详细解释了递归条件和终止条件,方便读者理解。
原文地址: https://www.cveoy.top/t/topic/pfXa 著作权归作者所有。请勿转载和采集!