码迷,mamicode.com
首页 > 编程语言 > 详细

贪心算法

时间:2020-05-01 18:38:26      阅读:62      评论:0      收藏:0      [点我收藏+]

标签:最好   思路   java   sele   tab   system   计算   ret   创建   

贪心算法

1. 算法介绍

贪心算法是指在可对问题进行求解时,在每一步中采用最好或者最优的选择,从而导致结果最好的算法

贪心算法得到的结果不一定是最优的结果,但是都是相对近似最优解的结果

2. 实际问题

广播台 覆盖地区
k1 “北京”,“上海”,“天津”
k2 “广州”,“北京”,“深圳”
k3 “成都”,“上海”,“杭州”
k4
k5 ”杭州“,”大连“

假设存在以上电视台,以及覆盖区域,如何选择最少的电视台让所有地区都能接收到信号

3. 算法思路

3.1 穷举法

列出所有集合,若有 n 个广播台,则共有 2 ^ n - 1 个组合

倘若有 5 个城市,则 共有 32 种组合,若每秒可以计算10种,则需要 3.2秒,若是100个广播台,则需要 4 * 10 ^ 23 年

3.2 贪婪算法

  • 遍历所有广播电台,找到一个覆盖了最多未覆盖的地区的电台
  • 将这个电台加入集合,下次进行比较时,去掉覆盖的地区
  • 重复上述步骤

4. 代码实现

package cn.imut;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

public class GreedyAlgorithm {

    public static void main(String[] args) {
        //创建广播电台,放入到Map
        HashMap<String,HashSet<String>> broadcasts = new HashMap<String, HashSet<String>>();
        //将各个电台放入到broadcasts
        HashSet<String> hashSet1 = new HashSet<String>();
        hashSet1.add("北京");
        hashSet1.add("上海");
        hashSet1.add("天津");

        HashSet<String> hashSet2 = new HashSet<String>();
        hashSet2.add("广州");
        hashSet2.add("北京");
        hashSet2.add("深圳");

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


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

        HashSet<String> hashSet5 = new HashSet<String>();
        hashSet5.add("杭州");
        hashSet5.add("大连");

        //加入到map
        broadcasts.put("K1", hashSet1);
        broadcasts.put("K2", hashSet2);
        broadcasts.put("K3", hashSet3);
        broadcasts.put("K4", hashSet4);
        broadcasts.put("K5", hashSet5);

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

        //创建ArrayList, 存放选择的电台集合
        ArrayList<String> selects = new ArrayList<String>();

        //定义一个临时的集合, 在遍历的过程中,存放遍历过程中的电台覆盖的地区和当前还没有覆盖的地区的交集
        HashSet<String> tempSet = new HashSet<String>();

        //定义给maxKey , 保存在一次遍历过程中,能够覆盖最大未覆盖的地区对应的电台的key
        //如果maxKey 不为null , 则会加入到 selects
        String maxKey = null;
        while(allAreas.size() != 0) { // 如果allAreas 不为0, 则表示还没有覆盖到所有的地区
            //每进行一次while,需要
            maxKey = null;

            //遍历 broadcasts, 取出对应key
            for(String key : broadcasts.keySet()) {
                //每进行一次for
                tempSet.clear();
                //当前这个key能够覆盖的地区
                HashSet<String> areas = broadcasts.get(key);
                tempSet.addAll(areas);
                //求出tempSet 和   allAreas 集合的交集, 交集会赋给 tempSet
                tempSet.retainAll(allAreas);
                //如果当前这个集合包含的未覆盖地区的数量,比maxKey指向的集合地区还多
                //就需要重置maxKey
                // tempSet.size() >broadcasts.get(maxKey).size()) 体现出贪心算法的特点,每次都选择最优的
                if(tempSet.size() > 0 &&
                        (maxKey == null || tempSet.size() >broadcasts.get(maxKey).size())){
                    maxKey = key;
                }
            }
            //maxKey != null, 就应该将maxKey 加入selects
            if(maxKey != null) {
                selects.add(maxKey);
                //将maxKey指向的广播电台覆盖的地区,从 allAreas 去掉
                allAreas.removeAll(broadcasts.get(maxKey));
            }

        }

        System.out.println("得到的选择结果是" + selects);//[K1,K2,K3,K5]

    }
}

注意:贪心算法不一定是最优解!!!

贪心算法

标签:最好   思路   java   sele   tab   system   计算   ret   创建   

原文地址:https://www.cnblogs.com/yfyyy/p/12814047.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!