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 个工件的最优加工顺序,使得总的加工时间最短。已知这 7 个工件的最优加工顺序为 [1, 6, 4, 3, 7, 5, 2]。
使用动态规划算法编写程序并逐行注释代码。
a. 问题分析
给定 7 个工件在两台机器上的处理时间,需要找到一个加工顺序,使得总的加工时间最短。
b. 解题思路
动态规划算法可以解决这个问题。
- 定义一个二维数组
dp,dp[i][j]表示前i个工件在第一台机器上加工完后,前j个工件在第二台机器上加工完的最短时间。 - 通过状态转移方程来更新
dp数组。 - 根据
dp数组的值,倒推出最优的加工顺序。
c. 代码如下:
#include <stdio.h>
#define N 7 // 工件的数量
void printOptimalOrder(int dp[N][N], int i, int j, int order[N]) {
if (i > 0 && j > 0) {
// 如果 dp[i][j] 等于 dp[i-1][j],说明第 i 个工件在第一台机器上加工完后没有在第二台机器上加工
if (dp[i][j] == dp[i-1][j]) {
printOptimalOrder(dp, i-1, j, order);
}
// 如果 dp[i][j] 等于 dp[i][j-1],说明第 j 个工件在第二台机器上加工完后没有在第一台机器上加工
else if (dp[i][j] == dp[i][j-1]) {
printOptimalOrder(dp, i, j-1, order);
}
// 否则,第 i 个工件在第一台机器上加工完后,第 j 个工件在第二台机器上加工完
else {
printOptimalOrder(dp, i-1, j, order);
printOptimalOrder(dp, i, j-1, order);
printf("%d ", order[i-1]); // 输出最优加工顺序
}
}
}
void optimalOrder(int m1[], int m2[], int order[]) {
int dp[N+1][N+1]; // dp 数组,多出一行和一列用于表示初始状态,dp[0][j] 和 dp[i][0] 均为 0
int i, j;
// 初始化 dp 数组
for (i = 0; i <= N; i++) {
dp[i][0] = 0;
dp[0][i] = 0;
}
// 更新 dp 数组
for (i = 1; i <= N; i++) {
for (j = 1; j <= N; j++) {
// 第 i 个工件在第一台机器上加工完后,第 j 个工件在第二台机器上加工完的最短时间
// 取决于前 i-1 个工件在第一台机器上加工完后,第 j 个工件在第二台机器上加工完的最短时间
// 和前 j-1 个工件在第二台机器上加工完后,第 i 个工件在第一台机器上加工完的最短时间的较小值
dp[i][j] = dp[i-1][j] + m1[i-1]; // 第 i 个工件在第一台机器上加工完
if (dp[i][j] > dp[i][j-1] + m2[j-1]) { // 第 j 个工件在第二台机器上加工完
dp[i][j] = dp[i][j-1] + m2[j-1];
}
}
}
printf("最优加工顺序为:");
printOptimalOrder(dp, N, N, order);
printf("\n");
}
int main() {
int m1[N] = {3, 8, 10, 12, 6, 9, 15}; // 第一台机器上的处理时间
int m2[N] = {7, 2, 6, 18, 3, 10, 4}; // 第二台机器上的处理时间
int order[N] = {1, 6, 4, 3, 7, 5, 2}; // 7 个工件的最优加工顺序
optimalOrder(m1, m2, order);
return 0;
}
代码解释:
-
printOptimalOrder函数:用来打印最优加工顺序。通过递归的方式,根据dp数组的值和最优加工顺序数组,找出最优加工顺序。 -
optimalOrder函数:用来计算最优加工顺序。- 定义一个二维数组
dp来保存每个状态的最优值。 - 根据状态转移方程,更新
dp数组的值。 - 调用
printOptimalOrder函数打印最优加工顺序。
- 定义一个二维数组
-
main函数:- 定义第一台机器上的处理时间数组
m1、第二台机器上的处理时间数组m2和最优加工顺序数组order。 - 调用
optimalOrder函数计算并打印最优加工顺序。
- 定义第一台机器上的处理时间数组
递归条件和终止条件:
- 递归条件: 在
printOptimalOrder函数中,当i > 0且j > 0时,递归调用自身,寻找最优加工顺序。 - 终止条件: 当
i或j等于 0 时,停止递归,表示已找到最优加工顺序的一部分。
优化后的代码:
代码中已经使用了动态规划的思想,并进行了代码优化。可以考虑以下方面进一步优化:
- 使用更简洁的代码结构,例如使用
for循环来代替递归,以提高代码效率。 - 使用更高效的算法,例如使用 A* 算法来寻找最优路径。
- 考虑使用多线程技术来加速计算。
原文地址: https://www.cveoy.top/t/topic/pfXe 著作权归作者所有。请勿转载和采集!