算法其實很簡單—貪心算法

目錄

1. 貪心算法介紹

2. 應用場景—集合覆蓋問題

2.1 思路分析

3. 代碼


1. 貪心算法介紹

算法可以貪心,人不能貪心哦~

  1. 貪婪算法(貪心算法)是指在對問題進行求解時,在每一步選擇中都採取最好或者最優(即最有利)的選擇,從而希望能夠導致結果是最好或者最優的算法
  2. 貪婪算法所得到的結果不一定 是最優的結果(有時候會是最優解),但是都是相對近似(接近)最優解的結果

 

2. 應用場景—集合覆蓋問題

 

2.1 思路分析

➢ 如何找出覆蓋所有地區的廣播臺的集合呢,使用窮舉法實現,列出每個可能的廣播臺的集合,這被稱爲冪集。假設總的有n個廣播臺,則廣播臺的組合總共有2n -1個,假設每秒可以計算10個子集,如圖:

➢ 使用貪婪算法,效率高:目前並沒有算法可以快速計算得到準備的值,使用貪婪算法,則可以得到非常接近的解,並且效率高。選擇策略上,因爲需要覆蓋全部地區的最小集合:

  1. 遍歷所有的廣播電臺,找到一個覆蓋了最多未覆蓋的地區的電臺(此電臺可能包含一些己覆蓋的地區,但沒有關係)
  2. 將這個電臺加入到一個集合中(比如ArrayList),想辦法把該電臺覆蓋的地區在下次比較時去掉。
  3. 重複第1步直到覆蓋了全部的地區

3. 代碼

package com.example.datastructureandalgorithm.greedy;

import java.util.*;

/**
 * @author 浪子傑
 * @version 1.0
 * @date 2020/6/15
 */
public class GreedyDemo {
    public static void main(String[] args) {
        // 創建電臺,放入map
        Map<String, Set<String>> broadcasts = new HashMap<String, Set<String>>();
        Set set1 = new HashSet<String>();
        set1.add("北京");
        set1.add("上海");
        set1.add("天津");

        Set set2 = new HashSet<String>();
        set2.add("廣州");
        set2.add("北京");
        set2.add("深圳");

        Set set3 = new HashSet<String>();
        set3.add("成都");
        set3.add("上海");
        set3.add("杭州");

        Set set4 = new HashSet<String>();
        set4.add("上海");
        set4.add("天津");

        Set set5 = new HashSet<String>();
        set5.add("杭州");
        set5.add("大連");

        broadcasts.put("K1", set1);
        broadcasts.put("K2", set2);
        broadcasts.put("K3", set3);
        broadcasts.put("K4", set4);
        broadcasts.put("K5", set5);

        // 存放所有的地區
        Set allAreas = new HashSet<String>();
        allAreas.add("北京");
        allAreas.add("上海");
        allAreas.add("杭州");
        allAreas.add("天津");
        allAreas.add("成都");
        allAreas.add("大連");
        allAreas.add("廣州");
        allAreas.add("深圳");

        // 存放選擇的電臺
        List selects = new ArrayList<String>();

        // 循環,直到allAreas大小爲0
        while (allAreas.size() != 0) {
            // 中間變量,存放選擇的最大的電臺key
            String maxKey = null;
            // 循環所有的電臺
            for (String key : broadcasts.keySet()) {
                // 中間變量,用來存放當前key和allAreas的交集
                Set<String> tempSet = new HashSet<>();
                // 獲取key對應的所有地區
                Set<String> areas = broadcasts.get(key);
                // 將當前key的地區放入中間變量
                tempSet.addAll(areas);
                // 求出當前key和allAreas的交集
                tempSet.retainAll(allAreas);
                // 如果交集不爲空,並且
                // 最大電臺的maxKey爲空或者交集大於maxKey對應的地區的時候
                // 需要重置maxKey
                if (tempSet.size() > 0 &&
                        (maxKey == null || tempSet.size() > broadcasts.get(maxKey).size())) {
                    maxKey = key;
                }
            }
            if (maxKey != null) {
                selects.add(maxKey);
                allAreas.removeAll(broadcasts.get(maxKey));
            }
        }

        System.out.println(selects);
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章