1. 程式人生 > 實用技巧 >貪心演算法(集合覆蓋問題)

貪心演算法(集合覆蓋問題)

貪心演算法(集合覆蓋問題)

貪心演算法介紹

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

應用場景-集合覆蓋問題

問題詳情

  假設存在下面需要付費的廣播臺,以及廣播臺訊號可以覆蓋的地區。 如何選擇最少的廣播臺,讓所有的地區都可以接收到訊號

思路分析

  1. 目前並沒有演算法可以快速計算得到準備的值, 使用貪婪演算法,則可以得到非常接近的解,並且效率高。選擇策略上,因為需要覆蓋全部地區的最小集合:
  2. 遍歷所有的廣播電臺, 找到一個覆蓋了最多未覆蓋的地區的電臺(此電臺可能包含一些已覆蓋的地區,但沒有關係)
  3. 將這個電臺加入到一個集合中(比如 ArrayList), 想辦法把該電臺覆蓋的地區在下次比較時去掉。
  4. 重複第 1 步直到覆蓋了全部的地區

圖解:

實現程式碼:

package com.edu.algorithm.貪心演算法;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 * <p>
 * 假設存在下面需要付費的廣播臺,以及廣播臺訊號可以覆蓋的地區。 如何選擇最少的廣播臺,讓所有的地區都可以接收到訊號
 * </p>
 *
 * @作者 five-five
 * @建立時間 2020/9/1
 
*/ public class 集合覆蓋 { public static void main(String[] args) { //儲存結果 List<Integer> nums = new ArrayList<>(); String[] k1 = {"北京", "上海", "天津"}; String[] k2 = {"廣州", "北京", "深圳"}; String[] k3 = {"成都", "上海", "杭州"}; String[] k4 = {"上海", "天津"}; String[] k5
= {"杭州", "大連"}; String[][] all = {k1, k2, k3, k4, k5}; //把所有集合的元素都拿一遍(去重) HashSet<String> hashSet = new HashSet<>(); for (String[] s : all) { for (String string : s) { hashSet.add(string); } } System.out.println(hashSet); //開始比較(來獲得maxkey) int[] key=null; do { key = new int[all.length]; for (int i = 0; i < all.length; i++) { for (int j = 0; j < all[i].length; j++) { //開始來弄key if (hashSet.contains(all[i][j])) { key[i]+=1; } } } //拿到key值,弄一個maxkey的下標出來 int max=0; for (int k=0;k<key.length;k++){ if (key[max]<key[k]) { max=k; } } nums.add(max); //開始刪除內容 for (String s : all[max]) { if (hashSet.contains(s)) { hashSet.remove(s); } } } while (isReady(key));//key全部為0的時候 nums.remove(nums.size()-1); //列印結果 for (Integer num : nums) { System.out.print("k"+(num+(Integer) 1)+"\t"); } } private static boolean isReady(int[] key) { for (int i:key){ if(i!=0){ return true; } } return false; } }