📜  顶点覆盖问题 | Set 1(介绍和近似算法)

📅  最后修改于: 2022-05-13 01:57:53.895000             🧑  作者: Mango

顶点覆盖问题 | Set 1(介绍和近似算法)

无向图的顶点覆盖是其顶点的子集,因此对于图的每条边 (u, v),“u”或“v”都在顶点覆盖中。虽然名称是 Vertex Cover,但该集合覆盖了给定图的所有边。给定一个无向图,顶点覆盖问题是找到最小尺寸的顶点覆盖
以下是一些示例。

顶点覆盖

顶点覆盖问题是一个已知的 NP 完全问题,即,除非 P = NP,否则没有多项式时间解决方案。不过,有近似多项式时间算法可以解决这个问题。以下是改编自 CLRS 书籍的简单近似算法。

天真的方法:

一个一个地考虑所有顶点的子集,并找出它是否覆盖了图的所有边。例如。在仅包含 3 个顶点的图中,由顶点组合组成的集合为:{0,1,2,{0,1},{0,2},{1,2},{0,1,2}} .使用该集合的每个元素检查这些顶点是否覆盖了图的所有边。因此更新最佳答案。因此打印具有最少顶点数的子集,该子集也覆盖了图的所有边。

顶点覆盖的近似算法:

1) Initialize the result as {}
2) Consider a set of all edges in given graph.  Let the set be E.
3) Do following while E is not empty
...a) Pick an arbitrary edge (u, v) from set E and add 'u' and 'v' to result
...b) Remove all edges from E which are either incident on u or v.
4) Return result 

下图展示了上述近似算法的执行情况:

顶点覆盖

上述算法的性能如何?
可以证明,上述近似算法永远不会找到一个顶点覆盖,其大小是最小可能顶点覆盖大小的两倍以上(证明参考this)
执行:
以下是上述近似算法的 C++ 和Java实现。

C++
// Program to print Vertex Cover of a given undirected graph
#include
#include 
using namespace std;
 
// This class represents a undirected graph using adjacency list
class Graph
{
    int V;    // No. of vertices
    list *adj;  // Pointer to an array containing adjacency lists
public:
    Graph(int V);  // Constructor
    void addEdge(int v, int w); // function to add an edge to graph
    void printVertexCover();  // prints vertex cover
};
 
Graph::Graph(int V)
{
    this->V = V;
    adj = new list[V];
}
 
void Graph::addEdge(int v, int w)
{
    adj[v].push_back(w); // Add w to v’s list.
    adj[w].push_back(v); // Since the graph is undirected
}
 
// The function to print vertex cover
void Graph::printVertexCover()
{
    // Initialize all vertices as not visited.
    bool visited[V];
    for (int i=0; i::iterator i;
 
    // Consider all edges one by one
    for (int u=0; u


Java
// Java Program to print Vertex
// Cover of a given undirected graph
import java.io.*;
import java.util.*;
import java.util.LinkedList;
 
// This class represents an undirected
// graph using adjacency list
class Graph
{
    private int V;   // No. of vertices
 
    // Array  of lists for Adjacency List Representation
    private LinkedList adj[];
 
    // Constructor
    Graph(int v)
    {
        V = v;
        adj = new LinkedList[v];
        for (int i=0; i i;
 
        // Consider all edges one by one
        for (int u=0; u


Python3
# Python3 program to print Vertex Cover
# of a given undirected graph
from collections import defaultdict
 
# This class represents a directed graph
# using adjacency list representation
class Graph:
 
    def __init__(self, vertices):
         
        # No. of vertices
        self.V = vertices
         
        # Default dictionary to store graph
        self.graph = defaultdict(list)
 
    # Function to add an edge to graph
    def addEdge(self, u, v):
        self.graph[u].append(v)
 
    # The function to print vertex cover
    def printVertexCover(self):
         
        # Initialize all vertices as not visited.
        visited = [False] * (self.V)
         
        # Consider all edges one by one
        for u in range(self.V):
             
            # An edge is only picked when
            # both visited[u] and visited[v]
            # are false
            if not visited[u]:
                 
                # Go through all adjacents of u and
                # pick the first not yet visited
                # vertex (We are basically picking
                # an edge (u, v) from remaining edges.
                for v in self.graph[u]:
                    if not visited[v]:
                         
                        # Add the vertices (u, v) to the
                        # result set. We make the vertex
                        # u and v visited so that all
                        # edges from/to them would
                        # be ignored
                        visited[v] = True
                        visited[u] = True
                        break
 
        # Print the vertex cover
        for j in range(self.V):
            if visited[j]:
                print(j, end = ' ')
                 
        print()
 
# Driver code
 
# Create a graph given in
# the above diagram
g = Graph(7)
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 3)
g.addEdge(3, 4)
g.addEdge(4, 5)
g.addEdge(5, 6)
 
g.printVertexCover()
 
# This code is contributed by Prateek Gupta


C#
// C# Program to print Vertex
// Cover of a given undirected
// graph
using System;
using System.Collections.Generic;
 
// This class represents an
// undirected graph using
// adjacency list
class Graph{
   
// No. of vertices
public int V;
 
// Array of lists for
// Adjacency List Representation
public List []adj;
 
// Constructor
public Graph(int v)
{
  V = v;
  adj = new List[v];
 
  for (int i = 0; i < v; ++i)
    adj[i] = new List();
}
 
//Function to add an edge
// into the graph
void addEdge(int v, int w)
{
   // Add w to v's list.
  adj[v].Add(w);
   
  //Graph is undirected
  adj[w].Add(v);
}
 
// The function to print
// vertex cover
void printVertexCover()
{
  // Initialize all vertices
  // as not visited.
  bool []visited = new bool[V];
 
  // Consider all edges one
  // by one
  for (int u = 0; u < V; u++)
  {
    // An edge is only picked
    // when both visited[u]
    // and visited[v] are false
    if (visited[u] == false)
    {
      // Go through all adjacents
      // of u and pick the first
      // not yet visited vertex
      // (We are basically picking
      // an edge (u, v) from remaining
      // edges.
      foreach(int i in adj[u])
      {
        int v = i;
        if (visited[v] == false)
        {
          // Add the vertices (u, v)
          // to the result set. We
          // make the vertex u and
          // v visited so that all
          // edges from/to them would
          // be ignored
          visited[v] = true;
          visited[u] = true;
          break;
        }
      }
    }
  }
 
  // Print the vertex cover
  for (int j = 0; j < V; j++)
    if (visited[j])
      Console.Write(j + " ");
}
 
// Driver method
public static void Main(String []args)
{
  // Create a graph given in
  // the above diagram
  Graph g = new Graph(7);
  g.addEdge(0, 1);
  g.addEdge(0, 2);
  g.addEdge(1, 3);
  g.addEdge(3, 4);
  g.addEdge(4, 5);
  g.addEdge(5, 6);
 
  g.printVertexCover();
}
}
 
// This code is contributed by gauravrajput1


Javascript


输出:

0 1 3 4 5 6