zoukankan      html  css  js  c++  java
  • 贪心算法(集合覆盖问题)

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

    贪心算法介绍

    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)+"	");
            }
    
        }
    
        private static boolean isReady(int[] key) {
            for (int i:key){
                if(i!=0){
                    return true;
                }
            }
            return false;
        }
    }
  • 相关阅读:
    页面滚屏截图工具推荐
    java总结第二次(剩余内容)//类和对象1
    happy birthday to tbdd tomorrow
    数组增删改查及冒泡
    三个循环方面程序
    三个入门小程序
    java总结第二次//数组及面向对象
    Java总结第一次//有些图片未显示,文章包含基础java语言及各种语句
    后台验证url是不是有效的链接
    img 鼠标滑上后图片放大,滑下后图片复原
  • 原文地址:https://www.cnblogs.com/five-five/p/13602305.html
Copyright © 2011-2022 走看看