本篇文章不是原创!而是笔记
import java.util.Scanner;
public class P1065作业调度方案_改进版 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m, n;
m = sc.nextInt();
n = sc.nextInt();
// 记录当前工件要完成第几道工序 并进行初始化
int[] workpiece = new int[n + 1];
for (int i = 1; i <= n; i++) {
workpiece[i] = 1;
}
// 记录第i件工件在完成之前的工序后最早开始时间 初始化为0
int[] earlyTime = new int[n + 1];
// 记录安排顺序
int[] arrangeOrder = new int[m * n];
for (int i = 0; i < m * n; i++) {
arrangeOrder[i] = sc.nextInt();
}
// 记录第i件工件第j道工序的机器号和加工时常
Info[][] info = new Info[n + 1][m + 1];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
int machineNum = sc.nextInt();
info[i][j] = new Info();
info[i][j].machineNum = machineNum;
}
}
// 记录完成时间
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
int time = sc.nextInt();
info[i][j].time = time;
}
}
// 记录第i个机器的时间线 并初始化 false表示该时间点不忙 true表示在忙
// 注意每个机器时间线是理论上0-无穷大 但是计算机无法表示无穷数据,且模拟数据量不会过大 因此我们时间线设置到0-10000即可
boolean[][] lineTime = new boolean[m + 1][10001];
for (int i = 1; i <= m; i++) {
for (int j = 0; j <= 10000; j++) {
lineTime[i][j] = false;
}
}
// 开始进行遍历 cur代表当前去除的工件号
for (Integer cur : arrangeOrder) {
int order = workpiece[cur]; // order表示该工件要完成的工序
workpiece[cur]++;
int eralytime = earlyTime[cur]; // 带工序的最早开始时间
Info curInfo = info[cur][order]; // 该工序的信息
for (int i = eralytime; i <= 10000; i++) {
if (isArrange(i, curInfo, lineTime)) {
updateTime(i, curInfo, lineTime);
earlyTime[cur] = i + curInfo.time;
break;
}
}
}
// 从最后时间中查找最大值
int res = -1;
for (int i = 1; i <= n; i++) {
res = Math.max(res, earlyTime[i]);
}
System.out.print(res);
sc.close();
return;
}
// 是否可以安排时间
static boolean isArrange(int startTime, Info inf, boolean[][] lineTime) {
int len = inf.time;
int num = inf.machineNum;
// 对末尾时间的处理我们认为其完成在末尾时间左侧一点
for (int i = startTime; i < startTime + len; i++) {
if (lineTime[num][i])
return false;
}
return true;
}
// 更新时间线
static void updateTime(int startTime, Info inf, boolean[][] lineTime) {
int len = inf.time;
int num = inf.machineNum;
// 对末尾时间的处理我们认为其可以作为下一个开始点因此设为忙
for (int i = startTime; i < startTime + len; i++) {
lineTime[num][i] = true;
}
}
// 记录工序所需机器以及完成时间
static class Info {
public int machineNum;
public int time;
}
}
这是一个Java程序,用于解决作业调度问题。程序读取输入的工件工序和机器信息,通过构建和更新时间线来确定每个工件的最早完成时间,最终找出所有工件完成的最大时间,即为所有作业的最短完成时间。
119

被折叠的 条评论
为什么被折叠?



