顶点覆盖(vertex cover)

2016/12/03 Algorithm

顶点覆盖(Vertex cover)

  在图论的数学学科中,图的顶点覆盖(有时是节点覆盖)是一组顶点的集合,使得图的每个边缘至少与集合中的一个顶点相连接。 找到最小顶点覆盖的问题是计算机科学中的经典优化问题,也是NP-hard最优问题近似算法的一个典型例子。

vertex cover

图来自于wiki

顶点覆盖问题(vertex cover problem)

顶点覆盖问题是在给定的无向图中找出顶点覆盖的最小值,尽管我们不能够在多项式时间里找出一个图G中最优的顶点覆盖, 但是我们可以有效的找出一个顶点覆盖的近似最优解。

例如:给定图G和正整数K

问题: G是否有顶点覆盖的大小至多为K?

问题解决

对于这类问题没有很精确的算法来解决,只有一些近似的算法解决这类问题。 2-approximation就是其中一种近似算法来解决这类问题,能找到至多不会超过最优顶点覆盖的2倍的顶点覆盖的集合,算法时间复杂度 O(E+V)。

2-approximation近似算法

1 C = {}
2 E' = G.E
3 while E != {};
4   let (u,v) be an arbitrary edge of E'
5   C = C U {u,v}
6   remove from E' every edge incident on either u or v
7 return C
  • 其中C为Vertex cover,G为图,E’为图的一个拷贝,(u,v)为边。

java实现

import java.util.Iterator;
import java.util.LinkedList;

class Graph
{
    private int V;
    private LinkedList<Integer> adj[];
    //构造函数
    Graph(int v)
    {
        V = v;
        adj = new LinkedList[v];     
        
        for (int i=0; i<v; ++i)
            adj[i] = new LinkedList();
    }
    //用邻接表来表示图
    void addEdge(int v, int w)
    {
        adj[v].add(w);
        adj[w].add(v);
    }
    void printVertexCover()
    {
        //初始化所有点都没有被遍历
        boolean visited[] = new boolean[V];
        for (int i=0; i<V; i++)
            visited[i] = false;
        Iterator<Integer> i;
        //遍历所有的点
        for (int u=0; u<V; u++)
        {
            if (visited[u] == false)
            {
                //遍历与当前节点相链接的点
                i = adj[u].iterator();
                while (i.hasNext())
                {
                    int v = i.next();
                    //对已经访问的点进行标记
                    if (visited[v] == false){
                        visited[v] = true;
                        visited[u] = true;
                        break;
                    }
                }
            }
        }
        //顶点覆盖的结果C
        for (int j=0; j<V; j++)
            if (visited[j])
                System.out.print(j+" ");
        System.out.println();
        for (boolean v: visited)
            System.out.print(v+" ");
        System.out.println();
        //邻接表
        for (LinkedList<Integer> str: adj)
            System.out.println(str);
    }
    
    public static void main(String args[])
    {
        Graph g = new Graph(7);
        g.addEdge(0, 1);
        g.addEdge(1, 2);
        g.addEdge(2, 3);
        g.addEdge(2, 4);
        g.addEdge(4, 5);
        g.addEdge(3, 5);
        g.addEdge(3, 4);
        g.addEdge(3, 6); 
        
        g.printVertexCover();
    }
}

run

0 1 2 3 4 5 
true true true true true true false 
[1]
[0, 2]
[1, 3, 4]
[2, 5, 4, 6]
[2, 5, 3]
[4, 3]
[3]

参考:




  • 除非注明,本博文即为原创,转载请注明本博文链接地址
  • 本博文只用于分享和交流知识,不得转载商用或个人牟利
  • 如果您觉得文章对您有帮助,可以通过点击下面按钮分享

Search

    Post Directory