貪心算法 - 會場安排


(1)問題描述:假設要在足夠多的會場里安排一批活動,並希望使用盡可能少的會場。前提每個活動都有開始和結束時間,一個會場中多個活動不能交叉進行,只能按次序進行,設計一個有效的貪心算法進行安排。

(2)算法設計:對於給定的 activities 個帶安排的活動,計算使用最少會場的時間表;

(3)數據輸入:第一行輸入待安排的活動數量 activities。接下來 activities 行中,每一行有 2 個整數,分別表示 activities 個待安排的活動的開始和結束時間;

(4)思想:記錄每個活動的開始和結束時間,按照升序排列,遍歷活動開始【START】和結束【FINISHED】標識,遇到 START,加 1,遇到 FINISHED,減 1,然后遍歷活動標識數組,找出最大值即為最少會場數量;

(5)代碼展示:

public class MeetingArrange {

    /**
     * 會場開始結束標識
     */
    private static final String START = "start";
    private static final String FINISHED = "finished";

    /**
     * 會場安排的活動數量
     */
    private static Integer activities = 0;

    /**
     * 記錄當前最少的會場個數
     */
    private static Integer minMettings = 0;

    /**
     * 記錄當前會場的數量
     */
    private static Integer[] nowMettingCount;

    /**
     * 活動安排開始結束時間數組
     */
    private static Integer[] startAndFinishedTime;

    /**
     * 活動安排開始結束標識
     */
    private static String[] flag;

    /**
     * 初始化數據
     */
    private static void initData() {
        Scanner input = new Scanner(System.in);
        System.out.println("請輸入安排的活動數量:");
        activities = input.nextInt();
        System.out.println("請輸入每個活動開始和結束時間:");
        startAndFinishedTime = new Integer[activities * 2];
        flag = new String[activities * 2];
        nowMettingCount = new Integer[flag.length];
        for (int i = 0; i < activities * 2; i = i + 2) {
            startAndFinishedTime[i] = input.nextInt();      // 活動開始時間
            startAndFinishedTime[i + 1] = input.nextInt();  // 活動結束時間
            flag[i] = START;                                // 活動開始標識
            flag[i + 1] = FINISHED;                         // 活動結束標識
            nowMettingCount[i] = 0;                         // 初始化當前會場數量為 0
        }
    }

    /**
     * 活動起始、結束時間數組升序排列
     */
    private static void sortAsc() {
        Integer temp;
        Integer change = 1;
        String str;
        for (int i = 0; i < startAndFinishedTime.length - 1 && change == 1; i++) {
            change = 0;
            for (int j = 0; j < startAndFinishedTime.length - i - 1; j++) {
                if (startAndFinishedTime[j] > startAndFinishedTime[j + 1]) {
                    // 活動開始和結束時間交換
                    temp = startAndFinishedTime[j];
                    startAndFinishedTime[j] = startAndFinishedTime[j + 1];
                    startAndFinishedTime[j + 1] = temp;

                    // 活動開始和結束標識交換
                    str = flag[j];
                    flag[j] = flag[j + 1];
                    flag[j + 1] = str;

                    change = 1;
                }
            }
        }
    }

    /**
     * 統計最少的會場數量
     * 思想:遇到 START,當前會場數量加 1,遇到 FINISHED,當前會場數量減 1;然后遍歷當前會場數量數組,取最大值即為最少會場數
     */
    private static Integer countMinMettings() {
        for (int i = 0; i < flag.length; i++) {
            if (flag[i].equals(START)) {
                minMettings++;
            } else {
                minMettings--;
            }
            nowMettingCount[i] = minMettings;
        }

        // 找出最少的會場數量
        return Stream.of(nowMettingCount).max(Comparator.comparingInt(o -> o)).get();
    }

    public static void main(String[] args) {
        // 初始化數據
        initData();

        // 升序
        sortAsc();
//        Stream.of(startAndFinishedTime).forEach(element -> System.out.print(element + " "));

        // 統計最少的會場數量
        Integer min = countMinMettings();
        System.out.println("最少的會場數量為:" + min);

    }

}

(6)輸入輸出:

請輸入安排的活動數量:
5
請輸入每個活動開始和結束時間:
1 23
12 28
25 35
27 80
36 50
最少的會場數量為:3

(7)總結:會場安排完全闡釋了貪心算法的核心思想,統計出多個局部最優解,在此局部最優解的集合中,選擇一個整體的最優解;

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM