贪心法解决最小顶点覆盖

最小顶点覆盖:假如选了一个点就相当于覆盖了以它为端点的所有边,最小顶点覆盖就是选择最少的点来覆盖所有的边。
贪心法思想:贪心法是只顾局部利益,由顶向下,一步一步做出贪心选择。抓住重点看它贪什么。在用贪心法解决最小顶点覆盖问题中,它贪的是覆盖的边最多的顶点。用邻接矩阵存储无向图,矩阵中每行的和即为顶点的出度。出度最多的顶点即为最优量度标准。
最小顶点覆盖其一般特性:
(1)找覆盖边最多的顶点
(2)已选中的顶点和未选中的顶点
(3)判断解函数,检查邻接矩阵中元素是否都为0,若不是则继续寻找顶点
(4)如果已找到的顶点集合没有覆盖所有的边,则该集合是可行的
(5)选择函数:从未选的顶点集中找到出度最多的顶点
(6)目标函数:计算顶点个数
在这里插入图片描述

这是本次贪心算法选择的一个无向图,用二维数组将其存储

在这里插入图片描述

在此代码中,方法wei0()用来判断邻接矩阵中是否每个值都为0,如果不是则继续执行。
如果是则说明最小顶点都已找到,退出循环。
方法 findMax()用来找到出度最多的顶点
方法reFresh()用来刷新邻接矩阵,每次找出一个局部最优解后,将其顶点所对应的行和列元素置为0,进行刷新。
输出结果:
在这里插入图片描述

符合最优解,由局部最优选择得到整体最优选择。`package suanfahomework;

/**
*无向图的邻接矩阵每行元素和为这个顶点的出度

  • @author lenovo
    */
    public class TanXin {

    public static void main(String args[]){
    int a[][]={{0,0,1,1,1,0,0},
    {0,0,0,1,0,1,0},
    {1,0,0,1,0,1,0},
    {1,1,1,0,0,0,0},
    {1,0,0,0,0,1,0},
    {0,1,1,0,1,0,1},
    {0,0,0,0,0,0,0},
    };
    int yuansu=0;
    int b[]=new int[a.length];//用来存储邻接矩阵中每个顶点的出度
    int count=0;
    while(wei0(a)) {//邻接矩阵中如果还有元素,就去找候选对象
    yuansu=findMax(a,b);//存储用findMax找出顶点出度最大的点
    System.out.println(“依次取出来的是”+yuansu);
    reFresh(a,yuansu);//对取出来的顶点所在的出入度化为0,得到新的矩阵
    count++;
    }
    System.out.println(“最小顶点覆盖个数为”+count);
    }
    public static boolean wei0(int[][] a){//判断矩阵中元素是否都为0
    for(int i=0;i<a.length;i++){
    for(int j=0;j<a[0].length;j++){
    if(a[i][j]!=0){ return true;
    }
    }
    }return false;
    }
    public static int findMax(int a[][],int b[]){
    int max=0;
    int dingdian=0;
    for(int i=0;i<a.length;i++){
    int sum=0;//计算每行的和
    for(int j=0;j<a[0].length;j++){
    sum+=a[i][j];
    }b[i]=sum;//数组b来存储每行的最大值,最后以判断取出哪一个顶点。
    // System.out.println(b[i]+“aaaa”);
    max=max>sum?max:sum;
    }// System.out.println(max);
    for(int k=0;k<b.length;k++){//用来找到出度最多的顶点,即覆盖边最多的顶点
    if(max==b[k]){ dingdian=k; break;}
    }
    //System.out.println(dingdian);
    return dingdian;
    }
    public static int[][] reFresh(int a[][],int yuansu){
    //将取出的顶点的对应行和列的元素置为0
    for(int i=0;i<a.length;i++){
    a[i][yuansu]=0;
    }
    for(int i=0;i<a[0].length;i++){
    a[yuansu][i]=0;
    }
    return a;
    }
    }`

  • 5
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值