zoukankan      html  css  js  c++  java
  • 求一般图的最小顶点覆盖集问题的混合贪婪算法(近似算法)

    之前准备做hiho一下的时候,网上查关于无向图的最大独立集;

    看到了一篇论文,说是能“求一般图的最小顶点覆盖集问题”的混合贪婪算法;

    我一看觉得挺牛逼的啊,跑去研究了大半天的这篇论文,发现实际是求近似解的,在特殊情况下偏差极大;

    实现完之后拿去做题,发现连样例都过不了,差点还以为程序哪里写挫了,

    仔细一看,正好样例产生的无向图就是一个对本算法十分不友好的情况,

    看来想在搞算法题的时候用是不大现实了,不过好歹算是研究了一篇论文,还手动实现了一遍;

    当然,这个算法在图的规模较大的情况下,应该拥有较好的近似比,可以考虑在某些特定场景下使用;

    论文链接clickhere

    具体实现:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<vector>
      4 #include<queue>
      5 #include<algorithm>
      6 #define MAX 20
      7 using namespace std;
      8 int n,m;
      9 struct Edge{
     10     int u,v;
     11 };
     12 struct Point{
     13     int id;
     14     int degree,adj_degree;
     15 }point[MAX];
     16 vector<Edge> E;
     17 vector<int> G[MAX];
     18 int degree[MAX],adj_degree[MAX];//每个点的度数和邻接度数
     19 bool del[MAX],vis[MAX];
     20 int V_cnt,Vv_cnt,E_cnt;
     21 void init_edge()
     22 {
     23     E.clear();
     24     for(int i=1;i<=n;i++) G[i].clear();
     25 }
     26 void add_edge(int u,int v)
     27 {
     28     E.push_back((Edge){u,v});
     29     E.push_back((Edge){v,u});
     30     int _size=E.size();
     31     G[u].push_back(_size-2);
     32     G[v].push_back(_size-1);
     33 }
     34 bool cmp(Point a,Point b){return a.adj_degree>b.adj_degree;}
     35 int pretreat()
     36 {
     37     for(int i=1;i<=n;i++)
     38     {
     39         point[i].degree=0;
     40         if(del[i]) continue;
     41         for(int j=0,_size=G[i].size();j<_size;j++)
     42         {
     43             Edge& e=E[G[i][j]];
     44             if(!del[e.v]) point[i].degree++;
     45         }
     46         if(point[i].degree==0) del[i]=1;
     47     }
     48     for(int i=1;i<=n;i++)
     49     {
     50         if(del[i])
     51         {
     52             point[i].adj_degree=0;
     53             continue;
     54         }
     55         point[i].adj_degree=point[i].degree;
     56         for(int j=0,_size=G[i].size();j<_size;j++) point[i].adj_degree+=point[E[G[i][j]].v].degree;
     57         printf("adj_degree[%d] = %d
    ",i,point[i].adj_degree);
     58     }
     59     sort(point+1,point+n+1,cmp);
     60 }
     61 void MinVC_MGA(bool ans[])
     62 {
     63     memset(del,0,sizeof(del));
     64     for(int i=1;i<=n;i++) point[i].id=i;
     65     E_cnt=0;
     66     while( E_cnt < m )
     67     {
     68         memset(vis,0,sizeof(vis));
     69         pretreat();
     70         V_cnt=0;
     71         Vv_cnt=0;
     72         for(int i=1;i<=n;i++) if(!del[i]) Vv_cnt++;
     73         for(int i=1;i<=n;i++)
     74         {
     75             printf("del[%d]=%d vis[%d]
    ",point[i].id,del[point[i].id],point[i].id,vis[point[i].id]);
     76             if(del[point[i].id]) continue;
     77             if(vis[point[i].id]) continue;
     78             printf("now ans add: %d
    ",point[i].id);
     79             ans[point[i].id]=1;//加入到最小顶点覆盖集中
     80             del[point[i].id]=1, Vv_cnt--;
     81             for(int j=0,_size=G[point[i].id].size();j<_size;j++)
     82             {
     83                 Edge& e=E[G[point[i].id][j]];
     84                 if(del[e.v]) continue;
     85                 E_cnt++;
     86                 if(!vis[e.v])
     87                 {
     88                     vis[e.v]=1;
     89                     V_cnt++;
     90                 }
     91             }
     92             if(V_cnt>=Vv_cnt) break;
     93         }
     94     }
     95 }
     96 
     97 int main()
     98 {
     99     while(scanf("%d %d
    ",&n,&m)!=EOF)
    100     {
    101         init_edge();
    102         for(int i=1,u,v;i<=m;i++)
    103         {
    104             scanf("%d%d",&u,&v);
    105             add_edge(u,v);
    106         }
    107         bool ans[n+5];
    108         memset(ans,0,sizeof(ans));
    109         MinVC_MGA(ans);
    110         for(int i=1;i<=n;i++) printf("%d:%s
    ",i,ans[i]?"YES":"NO");
    111     }
    112 }
    113 /*
    114 13 17
    115 1 10
    116 1 2
    117 1 7
    118 10 11
    119 7 11
    120 7 3
    121 7 8
    122 11 8
    123 3 4
    124 4 9
    125 8 9
    126 8 12
    127 9 12
    128 5 9
    129 12 13
    130 5 6
    131 6 13
    132 */
  • 相关阅读:
    8086汇编学习小记王爽汇编语言实验12
    8086汇编学习小记王爽汇编语言课程设计1
    activeMQ 持久化配置 kevin
    snmpwalk kevin
    tcp benchmark kevin
    apache camel 条件路由 kevin
    netty 并发访问测试配置 kevin
    snmp常见操作 kevin
    转发:RocketMQ与kafka的对比 kevin
    centos jdk 下载 kevin
  • 原文地址:https://www.cnblogs.com/dilthey/p/7633404.html
Copyright © 2011-2022 走看看