为了账号安全,请及时绑定邮箱和手机立即绑定

最大团问题-分支界限法

标签:
Java


最大团问题-分支界限法

遍历所有点构造二叉树;

广度遍历树,遍历过程中判断当前结点的点数据时,是否构成完全子图,如果不能则只将右结点加入队列,每次选取队列中完全子图最大的结点作为活结点,无子结点时到达叶子结点,记录为一个完全子图,优先队列法中第一个完全子图即为最优解。

package test;

import java.util.*;

/**

 * Created by saishangmingzhu on 2018/12/10.

 * 最大团问题

 */

public class MaximumCliqueProblem {

    //图

    private int[][] pointIndex=new int[][]{

                                    {1,1,0,1,1},

                                    {1,1,1,0,1},

                                    {0,1,1,0,1},

                                    {1,0,0,1,1},

                                    {1,1,1,1,1}};

    public static void main(String[] arg){

        new MaximumCliqueProblem().branchAndBoundMethod();

    }

    /**

     * 分支界限法-优先队列式

     * 优先队列式求解时,到达第一个没有子结点的活结点时,即为最优解

     */

    public void branchAndBoundMethod() {

        List<Point> pointList=new ArrayList<>();

        pointList.add(new Point("1",0));

        pointList.add(new Point("2",1));

        pointList.add(new Point("3",2));

        pointList.add(new Point("4",3));

        pointList.add(new Point("5",4));

        //【1】构建树

        Node root=new Node();

        createTree(pointList, root,0);

        //【2】广度遍历

        List<Node> currentLiveNodeList=new ArrayList<>();

        currentLiveNodeList.add(root);

        while (true) {

            //排序

            Node parent = currentLiveNodeList.get(0);

            if (parent.leftNode==null){

                //表示到了叶子结点,进行记录

                //点不算子图,所以要去除点集为1的叶子

                break;

            }

            List<Point> leftPointList = parent.leftNode.hasPointList;

            if (judge(leftPointList) != 0) {

                currentLiveNodeList.add(parent.leftNode);

            }

            //因为右结点是空,所以不需要判断

            //List<Point> rightPointList=parent.rightNode.hasPointList;

            currentLiveNodeList.add(parent.rightNode);

            currentLiveNodeList.remove(parent);

            Collections.sort(currentLiveNodeList, new Comparator<Node>() {

                @Override

                public int compare(Node o1, Node o2) {

                    return o2.hasPointList.size()-o1.hasPointList.size();

                }

            });

        }

        System.out.println("最大团");

        for (Point point:currentLiveNodeList.get(0).hasPointList){

            System.out.print(point.name+",");

        }

    }

    /**

     * 判断现有节点是否是完全子图 -1 表示不是

     * @param pointList

     * @return

     */

    private int judge(List<Point> pointList){

        for (int i=0;i<pointList.size();i++){

            Point pointi=pointList.get(i);

            int indexi=pointi.index;

            for (int j=i+1;j<pointList.size();j++){

                Point pointj=pointList.get(j);

                int indexj=pointj.index;

                //使用[indexi][indexj]是为了说明问题,可以直接使用[i][j]

                if (pointIndex[indexi][indexj]!=1){

                    return 0;

                }

            }

        }

        return 1;

    }

    private void createTree(List<Point> pointList, Node parent,int i) {

        if (i>=pointList.size()){

            return;

        }

        Node leftNode=new Node();

        leftNode.hasPointList.addAll(parent.hasPointList);

        leftNode.hasPointList.add(pointList.get(i));

        i++;

        createTree(pointList,leftNode,i);

        parent.leftNode=leftNode;

        Node rightNode=new Node();

        rightNode.hasPointList.addAll(parent.hasPointList);

        createTree(pointList,rightNode,i);

        parent.rightNode=rightNode;

    }

    class Point{

        private String name;

        private int index;

        public Point(String name,int index) {

            this.name = name;

            this.index = index;

        }

    }

    class Node{

        private Node leftNode;

        private Node rightNode;

        private List<Point> hasPointList=new ArrayList<>();

    }

}

©著作权归作者所有:来自51CTO博客作者塞上名猪的原创作品,如需转载,请注明出处,否则将追究法律责任


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消