8、實驗七活動安排
實驗內容
設有n個活動的集合E={1, 2, … n}, 其中每個活動都要求使用同一資源且在同一時間內只有一個活動能使用這一資源。要求根據下述兩種貪心準則,給出活動集合中最大的相容活動子集合。
(1)使用“將結束時間早的活動儘量先排”作爲貪心準則。
(2)使用“將最少佔用時間的活動儘量先排”作爲貪心準則。
解題思路
將活動按照結束時間進行從小到大排序。然後用i代表第i個活動,s[i]代表第i個活動開始時間,f[i]代表第i個活動的結束時間。按照從小到大排序,挑選出結束時間儘量早的活動,並且滿足後一個活動的起始時間晚於前一個活動的結束時間,全部找出這些活動就是最大的相容活動子集合。事實上系統一次檢查活動i是否與當前已選擇的所有活動相容。若相容活動i加入已選擇活動的集合中,否則,不選擇活動i,而繼續下一活動與集合A中活動的相容性。若活動i與之相容,則i成爲最近加入集合A的活動,並取代活動j的位置。
源代碼
package g活動安排問題;
import java.util.Scanner;
/**
* @author Draco
* @see "將結束時間早的活動儘量先排"作爲貪心準則
* @version 1.0
* @date-time 2020-06-01 - 下午12:19:16
*/
public class Plan {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("請輸入活動的個數:");
int num = scanner.nextInt();
// 創建開始數組和結束數組
int[] start = new int[num];
int[] end = new int[num];
System.out.println("請分別輸入開始時間s[i]和結束時間f[i]:");
for (int i = 0; i < num; i++) {
System.out.println();
System.out.print("s[" + (i + 1) + "]=");
int begin = scanner.nextInt();
System.out.print("f[" + (i + 1) + "]=");
int end1 = scanner.nextInt();
start[i] = begin;
end[i] = end1;
}
// 創建一個數組存儲是否安排活動
boolean[] arrange = new boolean[num + 1];
// 遍歷數組,判斷那些需要安排,安排的規則是按照順序,沒有相交的部分就安排
arrange[0] = true;
for (int i = 1, j = 0; i < start.length; i++) {
// 如果前一個的結束時間比後一個的開始時間小。則安排下去
if (end[j] < start[i]) {// 符合要求
arrange[i] = true;
j = i;// 如果成立,則j就是下一個作爲參考的時間
} else {
arrange[i] = false;
}
}
System.out.println();
System.out.println("按結束時間非遞減順序排列如下:");
System.out.println("序號\t開始時間\t結束時間");
System.out.println("--------------------");
int[] Index = new int[end.length];
Index = Plan.Arraysort(end);
for (int i = 0; i < num; i++) {
System.out.print((i + 1) + "\t");
// 對應下標
System.out.print(start[Index[i]] + "\t");
System.out.println(end[i]);
}
System.out.println("--------------------");
System.out.println("安排的活動序號依次是:");
for (int i = 0; i < arrange.length; i++) {
if (arrange[i] == true) {
System.out.println((i + 1));
}
}
}
public static int[] Arraysort(int[] arr) {
int temp;
int index;
int k = arr.length;
int[] Index = new int[k];
for (int i = 0; i < k; i++) {
Index[i] = i;
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
index = Index[j];
Index[j] = Index[j + 1];
Index[j + 1] = index;
}
}
}
return Index;
}
}
package g活動安排問題;
import java.util.Scanner;
/**
* @author Draco
* @see "將最少佔用時間的活動儘量先排"作爲貪心準則
* @version 1.0
* @date-time 2020-06-01 - 下午12:22:46
*/
public class Plan1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("請輸入活動的個數:");
int num = scanner.nextInt();
// 創建開始數組和結束數組
int[] start = new int[num];
int[] end = new int[num];
System.out.println("請分別輸入開始時間s[i]和結束時間f[i]:");
for (int i = 0; i < num; i++) {
System.out.println();
System.out.print("s[" + (i + 1) + "]=");
int begin = scanner.nextInt();
System.out.print("f[" + (i + 1) + "]=");
int end1 = scanner.nextInt();
start[i] = begin;
end[i] = end1;
}
// 創建一個數組存儲是否安排活動
boolean[] arrange = new boolean[num + 1];
// 創建一個數組存儲活動所需的時間
int[] spend = new int[num];
// 給時間數組賦值
for (int i = 0; i < num; i++) {
spend[i] = end[i] - start[i];
}
System.out.println();
System.out.println("按活動所需時間非遞減順序排列如下:");
System.out.println("序號\t開始時間\t結束時間\t活動所需時間");
System.out.println("---------------------------");
int[] Index = new int[spend.length];
Index = Plan1.Arraysort(spend);
for (int i = 0; i < num; i++) {
System.out.print((i + 1) + "\t");
// 對應下標
System.out.print(start[Index[i]] + "\t");
System.out.print(end[Index[i]] + "\t");
System.out.println(spend[i]);
}
System.out.println("---------------------------");
// 遍歷數組,判斷那些需要安排
arrange[0] = true;
for (int i = 1, j = 0; i < start.length; i++) {
// 如果前一個的結束時間比後一個的開始時間小。則安排下去
if (end[j] < start[Index[i]]) {// 符合要求
arrange[i] = true;
j = i;// 如果成立,則j就是下一個作爲參考的時間
} else {
arrange[i] = false;
}
}
System.out.println("安排的活動序號依次是:");
for (int i = 0; i < arrange.length; i++) {
if (arrange[i] == true) {
System.out.println((i + 1));
}
}
}
public static int[] Arraysort(int[] arr) {
int temp;
int index;
int k = arr.length;
int[] Index = new int[k];
for (int i = 0; i < k; i++) {
Index[i] = i;
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
index = Index[j];
Index[j] = Index[j + 1];
Index[j + 1] = index;
}
}
}
return Index;
}
}