Loading

贪心算法(集合覆盖问题)

贪心算法(集合覆盖问题)

贪心算法介绍

  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;
    }
}

 

posted @ 2020-09-02 16:10  揸火箭  阅读(504)  评论(0编辑  收藏  举报

Loading