0095 贪心算法,普利姆算法

news2025/7/18 9:22:15

 

 

 

 

 

 

 

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

/*
 * 贪心算法
 * 1.指在对问题进行求解时,在 每一步 选择中都采取最好或最优的选择,希望能够导致结果是最好或最优的算法
 * 2.所得到的结果不一定是最优结果,但相对接近最优解
 * 
 * 应用——集合覆盖
 * 存在下列广播台及可覆盖地区,如何选择最少的广播台?
 * 广播台            覆盖地区
 * K1            北京,上海,天津
 * K2            广州,北京,深圳
 * K3            成都,上海,杭州
 * K4            上海,天津    
 * K5            杭州,大连
 * 
 * 思路
 * 1.使用穷举法列出每个可能的广播台集合
 *   假设有n个广播台,则组合共有2^n-1,效率低
 *   
 * 2.使用贪心算法,得到近似解,效率高
 *         1.遍历所有广播电台,找到一个覆盖了最多未覆盖地区的电台
 *         2.将这个电台加入到一个集合中(如ArrayList),把该电台覆盖的地区在下次比较中去掉
 *         3.重复1,直到覆盖全部地区
 */
public class Greedy_ {
    public static void main(String[] args) {
        //创建广播电台K-V,放入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);
        
        //存放所有的地区
        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) {
            //每一次while,需要置空
            maxKey = null;
            
            //遍历broadcasts,取出对应的K
            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
                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);
        
    }
}

import java.util.Arrays;
/*
 * 普利姆算法
 * 
 * 应用——修路问题
 * 尽可能选择少的路线,并且每条路线最小,保证总里程数最小
 * 
 * 本质:最小生成树(MST)
 * 1.给定一个带权的无向连通图,使树上所有边权的总和最小,就叫最小生成树
 * 2.N个顶点,N-1条边,包含所有顶点
 * 3.求最小生成树的算法主要为普利姆算法和克鲁斯卡尔算法
 * 
 * 普利姆算法求最小生成树,就是在包含n个顶点的连通图中,找出只要n-1条边包含所有n个顶点的连通子图,即极小连通子图
 * 算法如下:
 * 1.设G=(V,E)是连通网,T=(U,D)是最小生成树,V,U是顶点集合,E,D是边集合
 * 2.若从顶点u开始构造最小生成树,则从集合V中取出顶点u放入集合U中,标记顶点v的visited[u]=1
 * 3.若集合U中顶点ui与集合V-U中的顶点vj之间存在边,则寻找这些边中权值最小的边,但不能构成回路
 *      将顶点vj加入集合U中,将边(ui,vj)加入集合D中,标记visited[vj]=1
 * 4.重复步骤2,直到U,V相等,即所有顶点都被标记为访问过,此时D中有n-1条边
 */
public class Prim_ {
    public static void main(String[] args) {
        char[] data = new char[] {'A','B','C','D','E','F','G'};
        int verxs = data.length;
        //邻接矩阵关系用二维数组表示,10000表示两个点不连通
        int[][] weight = new int[][] {
            {10000,5,7,10000,10000,10000,2},
            {5,10000,10000,9,10000,10000,3},
            {7,10000,10000,10000,8,10000,10000},
            {10000,9,10000,10000,10000,4,10000},
            {10000,10000,8,10000,10000,5,4},
            {10000,10000,10000,4,5,10000,6},
            {2,3,10000,10000,4,6,10000}};
            
        //创建Graph对象
        MGraph graph = new MGraph(verxs);
        //创建一个MinTree对象
        MinTree minTree = new MinTree();
        minTree.creatGraph(graph, verxs, data, weight);
        //输出
        minTree.showGraph(graph);
        
        //普利姆算法
        minTree.prim(graph, 0);
    }
}

//创建最小生成树
class MinTree{
    //创建图的邻接矩阵
    //graph:图对象,verxs:图对应的顶点个数,data:图的各个顶点的值,weight:图的邻接矩阵
    public void creatGraph(MGraph graph,int verxs,char data[],int[][] weight) {
        for(int i = 0;i < verxs;i++) {//顶点
            graph.data[i] = data[i];
            for(int j = 0;j < verxs;j++) {//邻接矩阵
                graph.weight[i][j] = weight[i][j];
            }
        }
    }
    
    //显示图的邻接矩阵
    public void showGraph(MGraph graph) {
        for(int[] link : graph.weight) {
            System.out.println(Arrays.toString(link));
        }
    }
    
    //编写普利姆算法,得到最小生成树
    //graph:图,v:表示从图的第几个顶点开始生成 'A'->0,'B'->1...
    public void prim(MGraph graph,int v) {
        //visited[]标记结点是否被访问过
        int visited[] = new int[graph.verxs];
        //默认元素都是0,表示没有访问过
        for(int i = 0;i < graph.verxs;i++) {
            visited[i] = 0;
        }
        
        //把当前这个结点标记为已访问
        visited[v] = 1;
        //h1和h2记录两个顶点的下标
        int h1 = -1;
        int h2 = -1;
        int minWeight = 10000;//先初始成一个大数
        
        for(int k = 1;k < graph.verxs;k++) {//有graph.verxs个顶点,有graph.verxs-1条边
            
            //确定每一次生成的子图 哪个结点 和 这次遍历的结点 距离最近
            for(int i = 0;i < graph.verxs;i++) {//i结点表示被访问过的结点
                for(int j = 0;j < graph.verxs;j++) {//j结点表示没有被访问过的结点
                    if (visited[i] == 1 && visited[j] == 0 && graph.weight[i][j] < minWeight) {
                        //替换minWeight(权值最小的边)
                        minWeight = graph.weight[i][j];
                        h1 = i;
                        h2 = j;
                    }
                }
            }
            //退出for循环,找到了一条边最小
            System.out.println("边<" + graph.data[h1] + "," + graph.data[h2] + "> 权值:" + minWeight);
            //将当前结点标记为访问过
            visited[h2] = 1;
            //重置minWeight
            minWeight = 10000;
        }
    }
}

//图
class MGraph{
    int verxs;//表示图的结点个数
    char[] data;//存放结点数据
    int[][] weight;//邻接矩阵
    
    public MGraph(int verxs) {
        this.verxs = verxs;
        data = new char[verxs];
        weight = new int[verxs][verxs];
    }
}

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/8284.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【SSH远程登录长时间连接后容易出现自动断开的解决方案】

SSH远程登录长时间连接后容易出现自动断开的解决方案0 问题描述1 方法一1.1 打开ssh_config文件1.2 在文件中添加以下内容1.3 重启ssh2 方法二2.1 打开sshd_config文件2.2 在文件中添加以下内容2.3 重启ssh0 问题描述 使用SSH连接远程服务器的时候 报出 client_loop send disc…

时序分析 48 -- 时序数据转为空间数据 (七) 马尔可夫转换场 python 实践(下)

时序分析 48 – 时序数据转为空间数据 (七) 马尔可夫转换场 python 实践&#xff08;下&#xff09; … 接上 从MTF到图模型 从MTF中我们可以生成图 &#x1d43a;(&#x1d449;,&#x1d438;)&#x1d43a;(&#x1d449;,&#x1d438;)G(V,E) &#xff0c;节点V和时间…

Redis从理论到实战:使用Redis实现商铺查询缓存(逐步分析缓存更新策略)

文章目录一、什么是缓存二、缓存的作用三、添加商户缓存四、分析缓存更新策略1、删除缓存还是更新缓存&#xff1f;2、如何保证缓存与数据库的操作同时成功或失败&#xff1f;3、先操作缓存还是先操作数据库&#xff1f;加油加油&#xff0c;不要过度焦虑(#^.^#) 一、什么是缓存…

ThreadLocal为什么会出现内存泄漏,你真的知道吗?

目录 1 前言 2 ThreadLocal进行线程隔离的小示例 3 原因 1 前言 大家想要搞清楚这个问题&#xff0c;就必须知道内存泄漏和内存溢出的区别 内存泄漏&#xff1a;不就被使用的对象或者变量无法被回收 内存溢出&#xff1a;没有剩余的空间来创建新的对象 2 ThreadLocal进行…

Java中的字符串

&#x1f649; 作者简介&#xff1a; 全栈领域新星创作者 &#xff1b;天天被业务折腾得死去活来的同时依然保有对各项技术热忱的追求&#xff0c;把分享变成一种习惯&#xff0c;再小的帆也能远航。 &#x1f3e1; 个人主页&#xff1a;xiezhr的个人主页 java中的字符串一、简…

C++:重定义:符号重定义:变量重定义

概述&#xff1a;在上一篇我们知道 通过 #ifndef....#defin....#endif &#xff0c; 这个解决头文件重复包含的问题 C&#xff1a;重定义&#xff1a;class类型重定义_hongwen_yul的博客-CSDN博客 避免头文件的重复包含可以有效的避免变量的重复定义&#xff0c;其实不光变量…

[附源码]java毕业设计基于web旅游网站的设计与实现

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

使用Docker开发GO应用程序

根据Stack Overflow的2022开发者调查&#xff0c;Go&#xff08;或Golang&#xff09;是最受欢迎和最受欢迎的编程语言之一。由于与许多其他语言相比&#xff0c;Go的二进制大小更小&#xff0c;开发人员经常使用Go进行容器化应用程序开发。 Mohammad Quanit在他的社区全能课程…

小程序vant-tabbar使用示例,及报错处理

小程序vant-tabbar使用示例&#xff0c;及报错处理1. 配置信息2. 添加 tabBar 代码文件3. 编写 tabBar 代码custom-tab-bar/index.tscustom-tab-bar/index.jsoncustom-tab-bar/index.wxml使小程序使用vant-tabbar组件时&#xff0c;遇到以下报错&#xff1a;Couldn’t found th…

Java基于springboot+vue的儿童玩具销售购物网站 多商家

爱玩儿是所有孩子的天性。尤其是在婴幼儿阶段。选择一个好的玩具&#xff0c;不仅能够让孩子玩儿的开心&#xff0c;而且有助于孩子智力的开发。很多家长在选择玩具的时候&#xff0c;不知道选择什么样的玩具。且当前玩具市场的玩具鱼目混杂&#xff0c;种类繁多&#xff0c;而…

SAR信号处理基础1——线性调频信号

关键字&#xff1a;线性调频信号&#xff0c;LFM信号&#xff0c;chirp信号&#xff0c;驻定相位原理&#xff08;POSP&#xff09;&#xff0c;泰勒展开&#xff0c;Taylor展开&#xff0c;脉冲压缩&#xff0c;匹配滤波&#xff0c;sinc&#xff0c;分辨率&#xff0c;峰值旁…

QProgressDialog.close()失败,进度条关闭感觉失败了,无法彻底关闭

开发环境&#xff1a;我是在deepin&#xff08;深度&#xff09;系统下开发的&#xff0c;在我本机上&#xff0c;一点问题也没有&#xff0c;但是我移植到了ubantu的机子上&#xff0c;就偶尔出现出个问题&#xff0c;出现了一个模态框&#xff0c;需要重启软件才能关闭。 问题…

Vue的computed和watch的区别是什么?

一、computed介绍 computed 用来监控自己定义的变量&#xff0c;该变量在 data 内没有声明&#xff0c;直接在 computed 里面定义&#xff0c;页面上可直接使用。 //基础使用 {{msg}} <input v-model"name" /> //计算属性 computed:{msg:function(){return …

【MySQL】MySQL日志系统以及InnoDB背后的技术(MySQL专栏启动)

&#x1f4eb;作者简介&#xff1a;小明java问道之路&#xff0c;专注于研究 Java/ Liunx内核/ C及汇编/计算机底层原理/源码&#xff0c;就职于大型金融公司后端高级工程师&#xff0c;擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。 &#x1…

Java基于springboot+vue的个人博客网站 前后端分离

随着现在网络的快速发展&#xff0c;网上管理系统也逐渐快速发展起来&#xff0c;网上管理模式很快融入到了许多网站的之中&#xff0c;随之就产生了“博客网站”&#xff0c;这样就让博客网站更加方便简单。 对于本博客网站的设计来说&#xff0c;系统开发主要是采用java语言技…

2022国产8K摄像机介绍

摄像机是一种把光学图像信号转变为电信号&#xff0c;以便于存储或者传输的设备。当我们拍摄一个物体时&#xff0c;此物体上反射的光被摄像机镜头收集&#xff0c;使其聚焦在摄像器件的受光面&#xff08;例如摄像管的靶面&#xff09;上&#xff0c;再通过摄像器件把光转变为…

N-HiTS: Neural Hierarchical Interpolation for Time Series Forecasting

N-HiTS: Neural Hierarchical Interpolation for Time Series Forecasting 神经预测的最新进展加速了大规模预测系统性能的提高。然而,长期预测仍然是一项非常困难的任务。影响这项任务的两个常见挑战是预测的波动性和它们的计算复杂性。本文提出N-HiTS,一种通过结合新的分层…

不同字符编码对比

目录 1. ASCII码 2. Unicode 3. GBK编码 1. ASCII码 ASCII码使用一个字节编码&#xff0c;但只适用于英文&#xff1b; 2. Unicode Unicode定义了字符集&#xff0c;有 17 个 code plane&#xff0c;总共规划了 1,114,112 个 code point。而这些字符可以使用UTF-8、UTF-1…

Windows无法访问指定设备、路径或文件怎么办?

如何解决Windows 无法访问指定的设备、路径或文件错误&#xff1f; 1.修改安全中心的设置 如果在安装程序的过程中&#xff0c;遇到该错误&#xff0c;可以进入到【Windows安全中心】进行设置修改。 第一步&#xff1a;点击左下角的开始按钮&#xff0c;然后依次点击【设置】…

直接安装WSL2及安装Ubuntu到F盘

1. 勾选这三项&#xff0c;重启 2. 以管理员方式运行powersell wsl --updatewsl --shutdownwsl --set-default-version 2wsl --status3. 解压缩ubuntu 解压缩Ubuntu_1804.2019.522.0_x64.appx到F盘 4. 安装ubuntu 双击ubuntu1804.exe安装 5. 运行 双击ubuntu1804.exe …