最小顶点覆盖:假如选了一个点就相当于覆盖了以它为端点的所有边,最小顶点覆盖就是选择最少的点来覆盖所有的边。
贪心法思想:贪心法是只顾局部利益,由顶向下,一步一步做出贪心选择。抓住重点看它贪什么。在用贪心法解决最小顶点覆盖问题中,它贪的是覆盖的边最多的顶点。用邻接矩阵存储无向图,矩阵中每行的和即为顶点的出度。出度最多的顶点即为最优量度标准。
最小顶点覆盖其一般特性:
(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;
}
}`