贪心算法

介绍

1.贪婪算法(贪心算法)是指在对问题进行求解时,在每一步选择中都采取最好或者最优(即最有利)的选择,从而希望能够导致结果是最好或者最优的算法

2.贪婪算法所得到的结果不一定是最优的结果(有时候会是最优解),但是都是相对近似(接近)最优解的结果

 

贪心算法解决集合覆盖问题

1.描述:假设已知广播台以及广播台信号可以覆盖的地区, 选择最少的广播台,让所有的地区都可以接收到信号

2.思路

(1)遍历所有的广播电台,找到一个覆盖了最多未覆盖的地区的电台(哪怕电台可能包含一些已覆盖的地区) 

(2)将这个电台加入到一个集合中(如ArrayList),把该电台覆盖的地区在下次比较时去掉

(3)重复步骤1直到覆盖了全部的地区

 

代码实现

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

public class Greedy {

    public static void main(String[] args) {//集合覆盖问题
        HashMap<String, HashSet<String>> broadcasts = new HashMap<>();//创建key:电台,value:覆盖地区

        HashSet<String> hashSet1 = new HashSet<>();
        hashSet1.add("北京");
        hashSet1.add("上海");
        hashSet1.add("天津");
        hashSet1.add("杭州");

        HashSet<String> hashSet2 = new HashSet<>();
        hashSet2.add("广州");
        hashSet2.add("北京");
        hashSet2.add("上海");
        hashSet2.add("天津");

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

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

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

        broadcasts.put("K1", hashSet1);
        broadcasts.put("K2", hashSet2);
        broadcasts.put("K3", hashSet3);
        broadcasts.put("K4", hashSet4);
        broadcasts.put("K5", hashSet5);

        GreedyAlgorithm(broadcasts);
    }

    //贪心算法解决集合覆盖
    public static void GreedyAlgorithm(HashMap<String, HashSet<String>> broadcasts) {
        //存放所有未覆盖的地区
        HashSet<String> allAreas = new HashSet<>();
        Collection<HashSet<String>> values = broadcasts.values();
        for (HashSet<String> broadcast : values) {
            allAreas.addAll(broadcast);
        }
        //存放选择的电台集合
        ArrayList<String> select = new ArrayList<>();
        //储存当前遍历电台未覆盖地区
        HashSet<String> curAreas = new HashSet<>();
        //储存上次遍历的最优方案的未覆盖地区
        HashSet<String> bestAreas = new HashSet<>();
        //储存上次遍历的最优方案的电台
        String best;
        while (allAreas.size() != 0) {//如果allAreas不为0,则表示还没有覆盖到所有的地区
            best = null;
            bestAreas.clear();
            for (String cur : broadcasts.keySet()) {//遍历broadcasts,取出对应电台
                curAreas.clear();
                //当前电台能够覆盖的地区,包含已覆盖和未覆盖地区,加入curAreas
                curAreas.addAll(broadcasts.get(cur));
                //利用allAreas将已覆盖地区去重,即提取电台未覆盖区域
                curAreas.retainAll(allAreas);
                //best == null,第一次遍历;curAreas.size() > bestAreas.size(),当前遍历电台方案优于上次便利的最优方案
                if (best == null || curAreas.size() > bestAreas.size()) {
                    bestAreas.clear();
                    best = cur;
                    bestAreas.addAll(broadcasts.get(best));
                    bestAreas.retainAll(allAreas);
                }
            }
            if (best != null) {
                select.add(best);
                //将best指向的广播电台覆盖的地区,从allAreas去掉
                allAreas.removeAll(broadcasts.get(best));
            }
        }
        System.out.println("选择结果" + select);
    }
}

 

posted @   半条咸鱼  阅读(50)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示