• 最大团问题分支限界


    问题描述:

      给定无向图G=(VE),其中V是非空集合,称为顶点集

      EV中元素构成的无序二元组的集合,称为边集,无向图中的边均是顶点的无序对,无序对常用圆括号“( )”表示。

      如果UV,且对任意两个顶点uvU有(uv)∈E,则称UG完全子图

      G的完全子图UG的团当且仅当U不包含在G的更大的完全子图中。G最大团是指G中所含顶点数最多的团。

      如果U∈V且对任意uvU有(uv)∈E,则称UG空子图G的空子图UG的独立集当且仅当U不包含在G的更大的空子图中。G的最大独立集是G中所含顶点数最多的独立集。

      对于任一无向图G=(VE),其补图G'=(V', E')定义为:V'=V,且(uv)∈E'当且仅当(uv)∈E

      如果UG的完全子图,则它也是G'的空子图,反之亦然。因此,G的团与G'的独立集之间存在一一对应的关系。特殊地,UG的最大团当且仅当UG'的最大独立集


    问题定义:

      解空间树中结点类型:bbnode

      活结点优先队列中元素类型为 CliqueNode(cn 表示与该节点相应的团的定点数,un表示结点为根的子树中的最大顶点树的上界。level表示结点在子集空间树中所处的层次;ch 左右儿子的结点标记)

      ch=1  左儿子  ch=0  右儿子

      ptr 指向解空间树中相应结点的指针

      cn+n-level+1表示定点数上界的un值。

    代码描述:

    相关结构体定义:

    class bbnode{
        friend class Clique;
    private:
        bbnode * parent;
        bool LChild;
    };
    class CliqueNode{
        friend class Clique;
    public:
        operator int () const {return un;}
    private:
        int cn,
            un,
            level;
        bbnode *ptr;
    };
    class Clique{
        friend void main(void);
    public:
        int BBMaxClique(int []);
    private:
        void AddLiveNode(MaxHeap<CliqueNode> &H,int cn,int un,int level,bbnode E[],bool ch);
        int * * a ,n;
    };

    AddLiveNode:将当前构造的活结点 加入到子集空间树中并插入活结点优先队列中。

    void Clique::AddLiveNode(MaxHeap<CliqueNode> &H,int cn,int un,int level,bbnode E[],bool ch)
    {
        bbnode * b = new bbnode;
        b->parent = E;
        b->LChild = ch;
        CliqueNode N;
        N.cn = cn;
        N.level = level;
        N.un = un;
        N.Insert(N);
    }

    算法核心代码:BBMaxClique

    子集树的根节点是 初始扩展结点 cn为0      

    i 表示当前扩展结点的解空间树中所处的层次。

    首先考察左儿子:

      顶点加入当前团,检查该顶点与当前团中其他顶点是否有边相连。

      都有边,可行,纳入 活结点 优先队列中,AddLiveNode(),接着考察当前扩展结点的 右儿子结点,仅当un>bestn时,右子树中可能含有最优解  ;

      否则,不可行。

    int Clique::BBMaxClique(int bestx[])
    {
        MaxHeap<CliqueNode> H(1000);
        bbnode * E = 0;
        int i=1,
            cn = 0,
            bestn = 0;
        while(i != n+1)
        {
            bool OK = true;
            bbnode * B = E;
            for(int j = i-1;j>0;B=B->parent,j--)
            {
                if(B->LChild && a[i][j]==0)
                {
                    OK = false;
                    break;
                }
            }
            if(OK)
            {
                if(cn + 1 > bestn)
                    bestn = cn + 1;
                AddLiveNode(H,cn+1,cn+n-i+1,i+1,E,true);
            }
            if(cn+n-i >= bestn)
                AddLiveNode(H,cn+1,cn+n-i+1,i+1,E,true);
            CliqueNode N;
            H.DeleteMax(N);
            E = N.ptr;
            cn = N.cn;
            i = N.level;
        }
        for(int j=n;j>0;j--)
        {
            bestx[j] = E->LChild;
            E = E->parent;
        }
        return bestn;
    }
  • 相关阅读:
    Sql Server 收缩日志文件原理及always on 下的实践
    SQL Agent服务无法启动如何破
    Sql Server Always On 读写分离配置方法
    SQL SERVER 9003错误解决方法 只适用于SQL2000
    SQL Server 数据库分离与附加
    SQL SERVER 的模糊查询 LIKE
    sqlserver 时间格式函数详细
    浅谈SQL Server中的三种物理连接操作
    谈一谈SQL Server中的执行计划缓存(下)
    asp.net获取当前系统的时间
  • 原文地址:https://www.cnblogs.com/xing901022/p/2760528.html
Copyright © 2020-2023  润新知