最大团问题属于图论里的经典问题,典型的案例是找出朋友圈关系图中最大的圈子,即两两相识的最大圈子。

        这里给出使用回溯法求解的两个方案:

        方案一:1.遍历所有点构造二叉树;

                    2.深度遍历树,遍历过程中判断加入当前结点的点数据时,是否构成完全子图,如果不能则走右结点,即剪枝左结点。达到叶子结点时即为一个完全子图的解,进行记录;

                    3.选择最大的记录作为最大团。(实现为如下代码)

        方案二:1.开始遍历点构造二叉树时就进行记录当前达到叶子的最大完全子图,记录最大值为tmpMax,此值会在后续构造二叉树时更新;

                    2.继续遍历点构造树的时候,计算当前结点所包含的完全子图加剩余结点数是否大于之前记录的tmpMax,如果不大于,则直接剪枝,因为哪怕剩下所有结点都包含在完全子图,也不会大于tmpMax。

package test;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by saishangmingzhu on 2018/12/9.
 * 最大团问题
 */
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}};
    private List leafNodeList=new ArrayList<>();

    public static void main(String[] arg){
        new MaximumCliqueProblem().backtracking();
    }

    /**
     * 回溯法
     */
    public void backtracking(){
        List 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】深度遍历+判断记录
        traversal(root);
        //【3】选最大
        System.out.println("所有子图");
        int size=0;
        Node maxNode=null;
        for (Node node:leafNodeList){
            if (size1)
                leafNodeList.add(parent);
            return;
        }
        List leftPointList=parent.leftNode.hasPointList;
        if (judge(leftPointList)!=0){
            traversal(parent.leftNode);
        }
        //因为右结点是空,所以不需要判断
        //List rightPointList=parent.rightNode.hasPointList;
        traversal(parent.rightNode);
    }

    /**
     * 判断现有节点是否是完全子图 -1 表示不是
     * @param pointList
     * @return
     */
    private int judge(List pointList){
        for (int i=0;i 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 hasPointList=new ArrayList<>();

    }
}